summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/00_test_list.txt20
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html55
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html108
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-normalized-int.html80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib.html28
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html154
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer.html126
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/invalid-vertex-attribs.html73
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/attribs/render-no-enabled-attrib-arrays.html66
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt13
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html119
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html176
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html102
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html183
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html110
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/delete-buffer.html80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html250
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html223
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html195
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-second-compile.html104
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-state-restoration.html101
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html576
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/canvas/00_test_list.txt1
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/canvas/compositing.html92
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/canvas/to-data-url-with-pack-params.html73
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/00_test_list.txt10
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/constants-and-properties-2.html835
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/context-mode.html56
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/context-resize-changes-buffer-binding-bug.html49
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html150
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/context-type-test-2.html80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/incorrect-context-object-behaviour.html230
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/methods-2.html268
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/context/no-experimental-webgl2.html35
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt19
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html508
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-half-float.html27
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html316
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-filter-anisotropic.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-norm16.html253
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html573
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2.html524
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_depth.html138
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_draw_buffers.html158
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_flat_varying.html93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_instanced_draw.html105
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_non_multiview_shaders.html93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_single_view_operations.html253
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_timer_query.html142
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_transform_feedback.html125
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html115
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html64
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/required-extensions.html58
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html1021
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html150
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html91
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html87
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html131
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html240
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html144
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html48
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html100
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html368
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html86
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html124
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html90
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html157
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html75
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html83
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html71
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html88
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html211
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html118
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html125
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html66
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html94
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html88
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html37
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html59
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html180
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html351
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html170
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html106
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html170
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html327
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html106
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html248
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html57
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html95
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html62
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html67
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html369
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html176
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html285
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html57
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html44
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html61
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html114
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html583
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html320
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.js13
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation.html36
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.js13
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2.html36
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-query.html79
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-sync.html77
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-timer-query.html84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/programs/00_test_list.txt4
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/programs/active-built-in-attribs.html86
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/programs/get-uniform-indices.html121
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/programs/gl-get-frag-data-location.html121
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/programs/sampler-uniforms.html111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/query/00_test_list.txt2
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/query/occlusion-query.html137
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/query/query.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/00_test_list.txt5
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/format-r11f-g11f-b10f.html266
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-fbo-test.html642
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html85
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-into-pixel-pack-buffer.html152
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html353
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/00_test_list.txt10
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-object-attachment.html508
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-test.html288
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-texture-layer.html144
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/invalidate-framebuffer.html230
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-draws-between-blits.html207
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-with-full-sample-counts.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html180
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html149
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/readbuffer.html174
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/00_test_list.txt51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/attrib-type-match.html561
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-outofbounds.html172
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-srgb.html161
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html112
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-outside-readbuffer.html267
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html113
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html245
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-scissor-enabled.html160
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-size-overflow.html98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html207
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-stencil-only.html170
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-test.html361
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-unaffected-by-colormask.html102
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/builtin-vert-attribs.html408
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/canvas-resizing-with-pbo-bound.html111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-func-buffer-type-match.html145
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-srgb-color-buffer.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-and-draw.html216
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-sub-source.html110
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbufferfv-with-alpha-false.html80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clipping-wide-points.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/depth-stencil-feedback-loop.html165
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-dirty-state-bug.html111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-driver-hang.html187
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-sparse-output-locations.html108
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers.html598
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-with-integer-texture-base-level.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/element-index-uint.html432
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-draw-framebuffer.html74
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-unaffected.html89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-mismatched-attachment-targets.html162
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer-angle-issue.html90
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer.html440
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-changing-base-level.html107
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-level1.html64
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-to-texture.html201
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-unsupported.html134
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html169
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-arrays.html271
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-bug.html254
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-large-divisor.html145
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/line-rendering-quality.html27
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-depth-resolve.html179
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html143
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html187
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rasterizer-discard-and-implicit-clear.html149
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/read-draw-when-missing-image.html288
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rgb-format-support.html111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/texture-switch-performance.html101
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/uniform-block-buffer-size.html228
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id-large-count.html127
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id.html219
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/samplers/00_test_list.txt3
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/samplers/multi-context-sampler-test.html84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/samplers/sampler-drawing-test.html124
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/samplers/samplers.html230
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/state/00_test_list.txt4
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-enum-tests.html29
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-get-calls.html177
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-getstring.html60
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-object-get-calls.html23
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/sync/00_test_list.txt1
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/sync/sync-webgl-specific.html156
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/00_test_list.txt14
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r32f-red-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg32f-rg-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/00_test_list.txt40
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/active-3d-texture-bug.html124
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/angle-stuck-depth-textures.html197
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html73
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-from-pbo-crash.html44
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-image.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html104
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-bug.html49
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-luma-format.html165
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-same-texture.html144
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-webgl-specific.html303
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image.html249
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/generate-mipmap-with-large-base-level.html56
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/gl-get-tex-parameter.html27
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/immutable-tex-render-feedback.html221
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-specification-order-bug.html216
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-texture-sampling.html169
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/mipmap-fbo.html50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/npot-video-sizing.html181
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html146
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html82
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-size-limit.html189
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-base-level-bug.html76
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html197
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html128
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args.html57
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-different-data-source.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-input-validation.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-mipmap-levels.html225
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-new-formats.html565
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-srgb-mipmap.html220
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html290
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-and-subimage-3d.html242
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-compressed-formats.html136
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-canvas-bug.html56
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html90
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-imagedata.html126
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html499
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params.html591
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texel-fetch-undefined.html82
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texture-npot.html160
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/00_test_list.txt68
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/00_test_list.txt9
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/default_transform_feedback.html117
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/non-existent-varying.html70
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/same-buffer-two-binding-points.html176
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/simultaneous_binding.html330
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/switching-objects.html231
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/too-small-buffers.html242
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/transform_feedback.html645
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/two-unreferenced-varyings.html136
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html133
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/00_test_list.txt9
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/dependent-buffer-change.html121
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/draw-with-uniform-blocks.html120
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/gl-uniform-arrays-sub-source.html404
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/incompatible-texture-type-for-sampler.html335
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/large-uniform-buffers.html138
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/query-uniform-blocks-after-shader-detach.html93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/simple-buffer-change.html122
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/uniform-blocks-with-arrays.html115
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/00_test_list.txt2
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html132
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object.html671
1181 files changed, 79018 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/00_test_list.txt
new file mode 100644
index 0000000000..e251dc9758
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/00_test_list.txt
@@ -0,0 +1,20 @@
+attribs/00_test_list.txt
+buffers/00_test_list.txt
+canvas/00_test_list.txt
+context/00_test_list.txt
+extensions/00_test_list.txt
+glsl3/00_test_list.txt
+misc/00_test_list.txt
+--min-version 2.0.1 offscreencanvas/00_test_list.txt
+programs/00_test_list.txt
+query/00_test_list.txt
+reading/00_test_list.txt
+renderbuffers/00_test_list.txt
+rendering/00_test_list.txt
+samplers/00_test_list.txt
+state/00_test_list.txt
+sync/00_test_list.txt
+textures/00_test_list.txt
+transform_feedback/00_test_list.txt
+uniforms/00_test_list.txt
+vertex_arrays/00_test_list.txt
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/00_test_list.txt
new file mode 100644
index 0000000000..08ef3bdac8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/00_test_list.txt
@@ -0,0 +1,8 @@
+--min-version 2.0.1 gl-bindAttribLocation-aliasing-inactive.html
+gl-vertex-attrib.html
+gl-vertex-attrib-i-render.html
+--min-version 2.0.1 gl-vertex-attrib-normalized-int.html
+gl-vertexattribipointer.html
+gl-vertexattribipointer-offsets.html
+--min-version 2.0.1 invalid-vertex-attribs.html
+--min-version 2.0.1 render-no-enabled-attrib-arrays.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html
new file mode 100644
index 0000000000..abbbc43d6a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html
@@ -0,0 +1,55 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/gl-bindattriblocation-aliasing.js"></script>
+<title>bindAttribLocation with aliasing - inactive attributes</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script id="vertexShaderStaticallyUsedButInactive" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+in $(type_1) a_1;
+in $(type_2) a_2;
+void main() {
+ gl_Position = true ? $(gl_Position_1) : $(gl_Position_2);
+}
+</script>
+<script id="vertexShaderUnused" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+in $(type_1) a_1;
+in $(type_2) a_2;
+void main() {
+ gl_Position = vec4(0.0);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies combinations of valid inactive attributes cannot be bound to the same location with bindAttribLocation. GLSL ES 3.00.6 section 12.46.");
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false}, 2);
+var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShaderESSL300, gl.FRAGMENT_SHADER);
+
+debug("Testing with shader that has statically used but inactive attributes.");
+runBindAttribLocationAliasingTest(wtu, gl, glFragmentShader, wtu.getScript('vertexShaderStaticallyUsedButInactive'));
+
+debug("");
+debug("Testing with shader that has entirely unused attributes.");
+runBindAttribLocationAliasingTest(wtu, gl, glFragmentShader, wtu.getScript('vertexShaderUnused'));
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html
new file mode 100644
index 0000000000..5fcbc786fe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html
@@ -0,0 +1,108 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in ivec2 p;
+layout(location=1) in ivec4 a;
+void main()
+{
+ gl_Position = vec4(p.x + a.x + a.y + a.z + a.w, p.y, 0.0, 10.0);
+}
+</script>
+<script id='vshader_unsigned' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in ivec2 p;
+layout(location=1) in uvec4 a;
+void main()
+{
+ gl_Position = vec4(p.x + int(a.x + a.y + a.z + a.w), p.y, 0.0, 10.0);
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+void main()
+{
+ oColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+function checkRedPortion(gl, w, low, high) {
+ var buf = new Uint8Array(w * w * 4);
+ gl.readPixels(0, 0, w, w, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var i = 0;
+ for (; i < w; ++i) {
+ if (buf[i * 4 + 0] == 255 && buf[i * 4 + 1] == 0 && buf[i * 4 + 2] == 0 && buf[i * 4 + 3] == 255) {
+ break;
+ }
+ }
+ return low <= i && i <= high;
+}
+
+function runTest() {
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext('testbed', { preserveDrawingBuffer : true }, 2);
+ if (!gl) {
+ testFailed('could not create context');
+ return;
+ }
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ var program_unsigned = wtu.setupProgram(gl, ['vshader_unsigned', 'fshader']);
+
+ gl.enableVertexAttribArray(0);
+ var pos = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pos);
+ gl.bufferData(gl.ARRAY_BUFFER, new Int32Array([-10, -10, 10, -10, -10, 10, 10, 10]), gl.STATIC_DRAW);
+
+ gl.vertexAttribIPointer(0, 2, gl.INT, 4 * 2, 0);
+
+ debug('Test vertexAttribI4[ui][v] by setting different combinations that add up to 15 and use that when rendering.');
+ var vals = [[2, -3, 6, 10], [1, 3, 1, 10], [-10, 3, 2, 20], [5, 6, 2, 2]];
+ var tests = ['vertexAttribI4i', 'vertexAttribI4ui', 'vertexAttribI4iv', 'vertexAttribI4uiv'];
+
+ for (var ii = 0; ii < 4; ++ii) {
+ if (ii % 2 == 0) {
+ gl.useProgram(program);
+ } else {
+ gl.useProgram(program_unsigned);
+ }
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ if (ii < 2) {
+ gl[tests[ii]](1, vals[ii][0], vals[ii][1], vals[ii][2], vals[ii][3]);
+ } else {
+ gl[tests[ii]](1, vals[ii]);
+ }
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+
+ if (checkRedPortion(gl, 50, 50 * 0.7, 50 * 0.8)) {
+ testPassed('Attribute of ' + tests[ii] + ' was set correctly');
+ } else {
+ testFailed('Attribute of ' + tests[ii] + ' was not set correctly');
+ }
+ }
+}
+</script>
+</head>
+<body>
+<canvas id="testbed" width="50" height="50"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Verify that using constant attributes for vertexAttribI* works.');
+runTest();
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-normalized-int.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-normalized-int.html
new file mode 100644
index 0000000000..e1e24be608
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-normalized-int.html
@@ -0,0 +1,80 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+ <title>WebGL 2 Normalized Vertex Attributes Conformance Test</title>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="../../resources/js-test-style.css"/>
+</head>
+<body>
+ <canvas width=1 height=1></canvas>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script id="vertex-shader" type="x-shader/x-vertex">#version 300 es
+ layout(location = 0) in vec3 vertex;
+
+ out float normAttrib;
+
+ void main(void) {
+ gl_Position = vec4(vertex.xy, 0, 1);
+ normAttrib = vertex.z;
+ }
+ </script>
+ <script id="fragment-shader" type="x-shader/x-fragment">#version 300 es
+ in lowp float normAttrib;
+
+ layout(location=0) out lowp vec4 fragColor;
+
+ void main(void) {
+ fragColor = vec4(vec3(normAttrib == -1.0 ? 1.0 : 0.0), 1);
+ }
+ </script>
+ <script src="../../js/js-test-pre.js"></script>
+ <script src="../../js/webgl-test-utils.js"></script>
+ <script>
+ (function () {
+ 'use strict';
+
+ var wtu = WebGLTestUtils;
+
+ var gl = wtu.create3DContext(document.querySelector('canvas'), null, 2);
+
+ var program = wtu.setupProgram(gl, ['vertex-shader', 'fragment-shader']);
+
+ gl.useProgram(program);
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Int8Array([
+ // Here we set the third component (the one that's actually tested)
+ // to (MIN_INT + 1). If non-zero-preserving rules are used, it'll be
+ // converted to a float that's slightly greater than -1. If zero-preserving
+ // rules are used, as the GLES 3 spec requires, result of conversion
+ // should be exactly -1.
+ -0x80, 0x7f, -0x7f,
+ 0x7f, 0x7f, -0x7f,
+ -0x80, -0x7f, -0x7f,
+ -0x80, -0x7f, -0x7f,
+ 0x7f, 0x7f, -0x7f,
+ 0x7f, -0x80, -0x7f
+ ]), gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.BYTE, true, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 6);
+
+ wtu.checkCanvas(gl, [255, 255, 255, 255], "should be opaque white");
+ }());
+ </script>
+ <script>
+ description('Verify that conversion of normalized signed int attributes to floats uses zero-preserving rule.');
+ window.successfullyParsed = true;
+ </script>
+ <script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib.html
new file mode 100644
index 0000000000..1d12f088d1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib.html
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL vertexAttrib Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/gl-vertex-attrib.js"></script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html
new file mode 100644
index 0000000000..37f6554647
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html
@@ -0,0 +1,154 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>vertexAttribIPointer offsets tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+There is supposed to be an example drawing here, but it's not important.
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+layout(location=0) in ivec4 aPosition;
+layout(location=1) in vec4 aColor;
+out vec4 vColor;
+void main()
+{
+ gl_Position = vec4(aPosition);
+ vColor = aColor;
+}
+</script>
+
+<script id="vshader_unsigned" type="x-shader/x-vertex">#version 300 es
+layout(location=0) in uvec4 aPosition;
+layout(location=1) in vec4 aColor;
+out vec4 vColor;
+void main()
+{
+ gl_Position = vec4(aPosition);
+ vColor = aColor;
+}
+
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+in vec4 vColor;
+layout(location=0) out vec4 oColor;
+void main()
+{
+ oColor = vColor;
+}
+</script>
+
+<script>
+"use strict";
+function init()
+{
+ description("test vertexAttribIPointer offsets work");
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("example", undefined, 2);
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"]);
+ var program_unsigned = wtu.setupProgram(gl, ["vshader_unsigned", "fshader"]);
+
+ var tests = [
+ { data: new Int32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.INT,
+ componentSize: 4,
+ },
+ { data: new Uint32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_INT,
+ componentSize: 4,
+ },
+ { data: new Uint16Array([ 0, 32767, 0, 32767, 0, 0, 0, 0, 0 ]),
+ type: gl.SHORT,
+ componentSize: 2,
+ },
+ { data: new Uint16Array([ 0, 65535, 0, 65535, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_SHORT,
+ componentSize: 2,
+ },
+ { data: new Uint8Array([ 0, 127, 0, 127, 0, 0, 0, 0, 0 ]),
+ type: gl.BYTE,
+ componentSize: 1,
+ },
+ { data: new Uint8Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
+ type: gl.UNSIGNED_BYTE,
+ componentSize: 1,
+ }
+ ];
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+
+ var kNumVerts = 3;
+ var kNumComponents = 3;
+
+ var count = 0;
+ for (var tt = 0; tt < tests.length; ++tt) {
+ var test = tests[tt];
+ for (var oo = 0; oo < 3; ++oo) {
+ for (var ss = 0; ss < 3; ++ss) {
+ var offset = (oo + 1) * test.componentSize;
+ var color = (count % 2) ? [1, 0, 0, 1] : [0, 1, 0, 1];
+ var stride = test.componentSize * kNumComponents + test.componentSize * ss;
+ debug("");
+ debug("check with " + wtu.glEnumToString(gl, test.type) + " at offset: " + offset + " with stride:" + stride);
+ if (test.type == gl.INT || test.type == gl.SHORT || test.type == gl.BYTE) {
+ gl.useProgram(program);
+ } else {
+ gl.useProgram(program_unsigned);
+ }
+ gl.vertexAttrib4fv(1, color);
+ var data = new Uint8Array(test.componentSize * kNumVerts * kNumComponents + stride * (kNumVerts - 1));
+ var view = new Uint8Array(test.data.buffer);
+ var size = test.componentSize * kNumComponents;
+ for (var jj = 0; jj < kNumVerts; ++jj) {
+ var off1 = jj * size;
+ var off2 = jj * stride;
+ for (var zz = 0; zz < size; ++zz) {
+ data[off2 + zz] = view[off1 + zz];
+ }
+ }
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, data);
+ gl.vertexAttribIPointer(0, 3, test.type, stride, offset);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ var buf = new Uint8Array(50 * 50 * 4);
+ gl.readPixels(0, 0, 50, 50, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+
+ var black = [0, 0, 0, 0];
+ var other = [color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255];
+ var otherMsg = "should be " + ((count % 2) ? "red" : "green")
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, black, "should be black", 0);
+ wtu.checkCanvasRect(gl, 0, 49, 1, 1, black, "should be black", 0);
+ wtu.checkCanvasRect(gl, 26, 40, 1, 1, other, otherMsg, 0);
+ wtu.checkCanvasRect(gl, 26, 27, 1, 1, other, otherMsg, 0);
+ wtu.checkCanvasRect(gl, 40, 27, 1, 1, other, otherMsg, 0);
+ ++count;
+ }
+ }
+ }
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer.html
new file mode 100644
index 0000000000..ecefc6d4e0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer.html
@@ -0,0 +1,126 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL vertexAttribIPointer Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("This test checks vertexAttribIPointer behaviors in WebGL 2.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking gl.vertexAttribIPointer.");
+
+ gl.vertexAttribIPointer(0, 3, gl.INT, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "vertexAttribIPointer should succeed if no buffer is bound and offset is zero");
+
+ gl.vertexAttribIPointer(0, 3, gl.INT, 0, 12);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "vertexAttribIPointer should fail if no buffer is bound and offset is non-zero");
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Int32Array(0), gl.STATIC_DRAW);
+
+ gl.vertexAttribIPointer(0, 1, gl.FLOAT, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
+ "vertexAttribIPointer should not support FLOAT");
+
+ var checkVertexAttribIPointer = function(
+ gl, err, reason, size, type, stride, offset) {
+ gl.vertexAttribIPointer(0, size, type, stride, offset);
+ wtu.glErrorShouldBe(gl, err,
+ "gl.vertexAttribIPointer(0, " + size +
+ ", gl." + wtu.glEnumToString(gl, type) +
+ ", " + stride +
+ ", " + offset +
+ ") should " + (err == gl.NO_ERROR ? "succeed " : "fail ") + reason);
+ }
+
+ var types = [
+ { type:gl.BYTE, bytesPerComponent: 1 },
+ { type:gl.UNSIGNED_BYTE, bytesPerComponent: 1 },
+ { type:gl.SHORT, bytesPerComponent: 2 },
+ { type:gl.UNSIGNED_SHORT, bytesPerComponent: 2 },
+ { type:gl.INT, bytesPerComponent: 4 },
+ { type:gl.UNSIGNED_INT, bytesPerComponent: 4 },
+ ];
+
+ for (var ii = 0; ii < types.length; ++ii) {
+ var info = types[ii];
+ debug("");
+ for (var size = 1; size <= 4; ++size) {
+ debug("");
+ debug("checking: " + wtu.glEnumToString(gl, info.type) + " with size " + size);
+ var bytesPerElement = size * info.bytesPerComponent;
+ var offsetSet = [
+ 0,
+ 1,
+ info.bytesPerComponent - 1,
+ info.bytesPerComponent,
+ info.bytesPerComponent + 1,
+ info.bytesPerComponent * 2];
+ for (var jj = 0; jj < offsetSet.length; ++jj) {
+ var offset = offsetSet[jj];
+ for (var kk = 0; kk < offsetSet.length; ++kk) {
+ var stride = offsetSet[kk];
+ var err = gl.NO_ERROR;
+ var reason = ""
+ if (offset % info.bytesPerComponent != 0) {
+ reason = "because offset is bad";
+ err = gl.INVALID_OPERATION;
+ }
+ if (stride % info.bytesPerComponent != 0) {
+ reason = "because stride is bad";
+ err = gl.INVALID_OPERATION;
+ }
+ checkVertexAttribIPointer(
+ gl, err, reason, size, info.type, stride, offset);
+ }
+ var stride = Math.floor(255 / info.bytesPerComponent) * info.bytesPerComponent;
+
+ if (offset == 0) {
+ checkVertexAttribIPointer(
+ gl, gl.NO_ERROR, "at stride limit",
+ size, info.type, stride, offset);
+ checkVertexAttribIPointer(
+ gl, gl.INVALID_VALUE, "over stride limit",
+ size, info.type, stride + info.bytesPerComponent, offset);
+ }
+ }
+ }
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/invalid-vertex-attribs.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/invalid-vertex-attribs.html
new file mode 100644
index 0000000000..8f9f975001
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/invalid-vertex-attribs.html
@@ -0,0 +1,73 @@
+<!--
+Copyright (c) 2022 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 draw functions have expected behavior with invalid vertex attribs</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"> </script>
+<script src="../../js/tests/invalid-vertex-attrib-test.js"></script>
+<style>
+body {
+ height: 3000px;
+}
+</style>
+</head>
+<body>
+<!-- Important to put the canvas at the top so that it's always visible even in the test suite runner.
+ Otherwise it just doesn't get composited in Firefox. -->
+<div id="description"></div>
+<canvas id="canvas" width="16" height="16"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+
+description(`\
+This test ensures WebGL implementations correctly generate INVALID_OPERATION
+when an attribute is enabled but no buffer is bound`);
+debug("");
+
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext('canvas', undefined, 2);
+
+async function runInvalidAttribTests() {
+ const invalidAttribTestFn = createInvalidAttribTestFn(gl);
+
+ function drawArrays(gl) {
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ function drawElements(gl) {
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ }
+
+ function drawArraysInstanced(gl) {
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, 1);
+ }
+
+ function drawElementsInstanced(gl) {
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 1);
+ }
+
+ function drawRangeElements(gl) {
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_BYTE, 0);
+ }
+
+ await invalidAttribTestFn(drawArrays);
+ await invalidAttribTestFn(drawElements);
+ await invalidAttribTestFn(drawArraysInstanced);
+ await invalidAttribTestFn(drawElementsInstanced);
+ await invalidAttribTestFn(drawRangeElements);
+ finishTest();
+}
+runInvalidAttribTests();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/render-no-enabled-attrib-arrays.html b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/render-no-enabled-attrib-arrays.html
new file mode 100644
index 0000000000..841119fecb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/attribs/render-no-enabled-attrib-arrays.html
@@ -0,0 +1,66 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<title>Verify drawing without any enabled vertex attribute arrays</title>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in vec4 inColor;
+out vec4 varyingColor;
+void main()
+{
+ varyingColor = inColor;
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_PointSize = 1.0;
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+in vec4 varyingColor;
+layout(location=0) out vec4 oColor;
+void main()
+{
+ oColor = varyingColor;
+}
+</script>
+<script>
+"use strict";
+
+function runTest() {
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("testCanvas", undefined, 2);
+ if (!gl) {
+ testFailed('could not create context');
+ return;
+ }
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ gl.disableVertexAttribArray(0);
+ gl.vertexAttrib4f(0, 0.0, 1.0, 0.0, 1.0);
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.checkCanvas(gl, [ 0, 255, 0, 255 ], "Canvas should be covered by a single green point");
+}
+</script>
+</head>
+<body>
+<canvas id="testCanvas" width="1" height="1" style="width: 32px; height: 32px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description();
+runTest();
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt
new file mode 100644
index 0000000000..21e4bb2bc4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt
@@ -0,0 +1,13 @@
+bound-buffer-size-change-test.html
+buffer-copying-contents.html
+buffer-copying-restrictions.html
+buffer-data-and-buffer-sub-data-sub-source.html
+buffer-type-restrictions.html
+buffer-overflow-test.html
+--min-version 2.0.1 delete-buffer.html
+get-buffer-sub-data.html
+--min-version 2.0.1 get-buffer-sub-data-validity.html
+one-large-uniform-buffer.html
+uniform-buffers.html
+--min-version 2.0.1 uniform-buffers-second-compile.html
+--min-version 2.0.1 uniform-buffers-state-restoration.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html
new file mode 100644
index 0000000000..a61d154eb1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html
@@ -0,0 +1,119 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL buffer size change test for bindBufferBase/bindBufferRange</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("WebGL buffer size change for bindings through bindBufferBase/bindBufferRange");
+
+// This test verifies the ES3 behavior, that the bound buffer range (offset, size) is not
+// limited by the actual buffer size, and the driver is responsible that no out-of-range
+// access may happen.
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+debug("");
+debug("bindBufferBase with TRANSFORM_FEEDBACK_BUFFER target");
+var buffer1 = gl.createBuffer();
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferBase on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "buffer1");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer1");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "0");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "0");
+
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer1");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "0");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "0");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("bindBufferBase with UNIFORM_BUFFER target");
+var buffer2 = gl.createBuffer();
+gl.bindBufferBase(gl.UNIFORM_BUFFER, 1, buffer2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferBase on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "buffer2");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer2");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "0");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "0");
+
+gl.bufferData(gl.UNIFORM_BUFFER, 8, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer2");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "0");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "0");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("bindBufferRange with TRANSFORM_FEEDBACK_BUFFER target");
+var buffer3 = gl.createBuffer();
+gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer3, 4, 8);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4");
+
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4");
+
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 12, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "buffer3");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)", "8");
+shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)", "4");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("bindBufferRange with UNIFORM_BUFFER target");
+var buffer4 = gl.createBuffer();
+var offset = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+gl.bindBufferRange(gl.UNIFORM_BUFFER, 1, buffer4, offset, 12);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where no storage is allocated should succeed.");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "12");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "offset");
+
+gl.bufferData(gl.UNIFORM_BUFFER, offset + 8, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "12");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "offset");
+
+gl.bufferData(gl.UNIFORM_BUFFER, offset + 12, gl.STATIC_DRAW);
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)", "buffer4");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)", "12");
+shouldBe("gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)", "offset");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html
new file mode 100644
index 0000000000..47d11093b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html
@@ -0,0 +1,176 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL buffer copying contents 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test copying a buffer's contents to another buffer governed by the WebGL 2 spec.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var vertices = [
+ 1.1, 1.0, 1.3,
+ -1.0, -1.0, -5.0,
+ 5.3, -1.0, 1.0
+];
+
+debug("");
+debug("Test copying between buffers returns correct data");
+
+function testCopyBuffers(srcTarget, dstTarget, copyRead, copyWrite) {
+ var msg = "Copying from " + targetToString(gl, srcTarget) +
+ " to " + targetToString(gl, dstTarget)
+ if (copyRead && copyWrite)
+ msg += " via COPY_READ_BUFFER and COPY_WRITE_BUFFER"
+ else if (copyRead)
+ msg += " via COPY_READ_BUFFER"
+ else if (copyWrite)
+ msg += " via COPY_WRITE_BUFFER"
+ else
+ msg += " directly"
+ debug("")
+ debug(msg)
+
+ var srcBuffer = gl.createBuffer(), dstBuffer = gl.createBuffer();
+ var originalData = new Float32Array(vertices);
+ var length = vertices.length * 4;
+
+ gl.bindBuffer(srcTarget, srcBuffer);
+ gl.bufferData(srcTarget, originalData, gl.STATIC_DRAW);
+ if (copyRead)
+ gl.bindBuffer(gl.COPY_READ_BUFFER, srcBuffer);
+
+ gl.bindBuffer(dstTarget, dstBuffer);
+ gl.bufferData(dstTarget, new Float32Array(length), gl.STATIC_DRAW);
+ if (copyWrite)
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, dstBuffer);
+
+ var expectedGLError = gl.NO_ERROR;
+
+ if (srcTarget == dstTarget) {
+ if (!copyRead && copyWrite) {
+ // srcBuffer isn't bound to any targets because of setting up dstBuffer.
+ gl.bindBuffer(srcTarget, srcBuffer);
+ }
+ if (!copyRead && !copyWrite) {
+ // Same buffer object, overlapping range.
+ expectedGLError = gl.INVALID_VALUE;
+ }
+ }
+ if ((srcTarget == gl.ELEMENT_ARRAY_BUFFER &&
+ dstTarget != gl.ELEMENT_ARRAY_BUFFER) ||
+ (srcTarget != gl.ELEMENT_ARRAY_BUFFER &&
+ dstTarget == gl.ELEMENT_ARRAY_BUFFER)) {
+ expectedGLError = gl.INVALID_OPERATION;
+ }
+
+ gl.copyBufferSubData(copyRead ? gl.COPY_READ_BUFFER : srcTarget,
+ copyWrite ? gl.COPY_WRITE_BUFFER : dstTarget,
+ 0, 0, length);
+ if (expectedGLError == gl.NO_ERROR) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Copying should work");
+
+ var retBuffer = new Uint8Array(length);
+ gl.getBufferSubData(dstTarget, 0, retBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(" + targetToString(gl, dstTarget) +
+ ", 0, retBuffer) should work");
+
+ var failed = false;
+ var retArray = new Float32Array(retBuffer.buffer);
+ for (var i = 0; i < vertices.length; i++) {
+ if (originalData[i] != retArray[i]) {
+ failed = true;
+ break;
+ }
+ }
+ if (failed)
+ testFailed("The returned array buffer fails to match original data");
+ else
+ testPassed("The returned array buffer matches original data");
+ } else {
+ wtu.glErrorShouldBe(gl, expectedGLError, "Copying should fail");
+ }
+
+ gl.deleteBuffer(srcBuffer);
+ gl.deleteBuffer(dstBuffer);
+ shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.COPY_READ_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.COPY_WRITE_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.PIXEL_PACK_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.PIXEL_UNPACK_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+}
+
+function targetToString(gl, target) {
+ switch (target) {
+ case gl.ARRAY_BUFFER:
+ return "ARRAY_BUFFER";
+ case gl.COPY_READ_BUFFER:
+ return "COPY_READ_BUFFER";
+ case gl.COPY_WRITE_BUFFER:
+ return "COPY_WRITE_BUFFER";
+ case gl.ELEMENT_ARRAY_BUFFER:
+ return "ELEMENT_ARRAY_BUFFER";
+ case gl.PIXEL_PACK_BUFFER:
+ return "PIXEL_PACK_BUFFER";
+ case gl.PIXEL_UNPACK_BUFFER:
+ return "PIXEL_UNPACK_BUFFER";
+ case gl.TRANSFORM_FEEDBACK_BUFFER:
+ return "TRANSFORM_FEEDBACK_BUFFER";
+ case gl.UNIFORM_BUFFER:
+ return "UNIFORM_BUFFER";
+ default:
+ return "UNKNOWN BUFFER";
+ }
+}
+
+var targets = [
+ gl.ARRAY_BUFFER,
+ gl.ELEMENT_ARRAY_BUFFER,
+ gl.PIXEL_PACK_BUFFER,
+ gl.PIXEL_UNPACK_BUFFER,
+ gl.TRANSFORM_FEEDBACK_BUFFER,
+ gl.UNIFORM_BUFFER,
+]
+
+for (var srcIndex in targets) {
+ for (var dstIndex in targets) {
+ if (targets[srcIndex] != gl.TRANSFORM_FEEDBACK_BUFFER &&
+ targets[dstIndex] != gl.TRANSFORM_FEEDBACK_BUFFER) {
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], true, true);
+ }
+ if (targets[srcIndex] != gl.TRANSFORM_FEEDBACK_BUFFER) {
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], true, false);
+ }
+ if (targets[dstIndex] != gl.TRANSFORM_FEEDBACK_BUFFER) {
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], false, true);
+ }
+ testCopyBuffers(targets[srcIndex], targets[dstIndex], false, false);
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html
new file mode 100644
index 0000000000..3bfe0e3e80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html
@@ -0,0 +1,102 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL buffer copying restrictions 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test buffer copying restrictions governed by the WebGL 2 spec. The test makes sure that copyBufferSubData acts as expected.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var validTargets = [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];
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var testCopyBuffer = function(srcTarget, dstTarget) {
+ var srcTargetStr = wtu.glEnumToString(gl, srcTarget),
+ dstTargetStr = wtu.glEnumToString(gl, dstTarget);
+ var srcBuffer = gl.createBuffer(),
+ dstBuffer = gl.createBuffer();
+ var testCopyStr = "copying from a gl." + wtu.glEnumToString(gl, srcTarget) + " buffer to a gl."
+ + wtu.glEnumToString(gl, dstTarget) + " buffer"
+
+ gl.bindBuffer(srcTarget, srcBuffer);
+ gl.bufferData(srcTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.bindBuffer(dstTarget, dstBuffer);
+ gl.bufferData(dstTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.copyBufferSubData(srcTarget, dstTarget, 8, 0, 4);
+ if (srcTarget == dstTarget)
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, testCopyStr + " should work.");
+ else if (srcTarget == gl.ELEMENT_ARRAY_BUFFER || dstTarget == gl.ELEMENT_ARRAY_BUFFER )
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, testCopyStr + " should fail.");
+ else
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, testCopyStr + " should work.");
+
+ // Special case: COPY_READ_BUFFER and COPY_WRITE_BUFFER are compatible with ELEMENT_ARRAY_BUFFER
+ // only if the buffer had been initially bound to an ELEMENT_ARRAY_BUFFER
+ if (srcTarget == gl.ELEMENT_ARRAY_BUFFER &&
+ (dstTarget == gl.COPY_READ_BUFFER || dstTarget == gl.COPY_WRITE_BUFFER)) {
+ dstBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, dstBuffer);
+ } else if (dstTarget == gl.ELEMENT_ARRAY_BUFFER &&
+ (srcTarget == gl.COPY_READ_BUFFER || srcTarget == gl.COPY_WRITE_BUFFER)) {
+ srcBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, srcBuffer);
+ } else {
+ return;
+ }
+
+ gl.bindBuffer(srcTarget, srcBuffer);
+ gl.bufferData(srcTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.bindBuffer(dstTarget, dstBuffer);
+ gl.bufferData(dstTarget, new Float32Array(32), gl.STATIC_DRAW);
+ gl.copyBufferSubData(srcTarget, dstTarget, 8, 0, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, testCopyStr + " should work if all buffers were initially bound to ELEMENT_ARRAY_BUFFER.");
+};
+
+for (var i = 0; i < validTargets.length; i++) {
+ debug("");
+ debug("Copying data from a " + wtu.glEnumToString(gl, validTargets[i])
+ + " buffer to another target");
+ for (var j = 0; j < validTargets.length; j++)
+ testCopyBuffer(validTargets[i], validTargets[j]);
+}
+
+debug("");
+debug("Test copying a buffer of other data (gl.ARRAY_BUFFER) bound to gl.COPY_READ_BUFFER to a "
+ + "buffer bound to gl.ELEMENT_ARRAY_BUFFER");
+var srcBuffer = gl.createBuffer(), dstBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, srcBuffer);
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, dstBuffer);
+gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Float32Array(32), gl.STATIC_DRAW);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(32), gl.STATIC_DRAW);
+gl.bindBuffer(gl.COPY_READ_BUFFER, srcBuffer);
+gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ELEMENT_ARRAY_BUFFER, 0, 0, 4);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Copying gl.ARRAY_BUFFER bound to "
+ + "gl.COPY_READ_BUFFER to a buffer bound to gl.ELEMENT_ARRAY_BUFFER should fail.");
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html
new file mode 100644
index 0000000000..ed9a131f77
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html
@@ -0,0 +1,183 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Test bufferData/bufferSubData with ArrayBufferView sub source input");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+function verifyBufferData(testCase, sourceByteOffset, size, data) {
+ var readbackBuffer = new ArrayBuffer(testCase.size * size);
+ var readbackView = new window[testCase.type](readbackBuffer);
+ gl.getBufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, readbackView);
+ var pass = true;
+ var offset = sourceByteOffset / testCase.size;
+ for (var ii = 0; ii < size; ++ii) {
+ if (readbackView[ii] != data[ii]) {
+ testFailed("expected data at " + ii + ": " + data[ii] + ", got " + readbackView[ii]);
+ pass = false;
+ }
+ }
+ if (pass) {
+ testPassed("buffer data uploaded correctly");
+ }
+}
+
+function bufferDataTest(testCases) {
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+ debug("");
+ debug("Test bufferData with " + test.type);
+
+ var buf = gl.createBuffer();
+ shouldBeNonNull(buf);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var count = 4;
+ var arrayBuffer = new ArrayBuffer(test.size * count);
+ var view = new window[test.type](arrayBuffer);
+ for (var ii = 0; ii < count; ++ii) {
+ view[ii] = ii;
+ }
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, 0, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferData when srcOffset + length is larger than source size");
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferData when srcOffset + length is larger than source size");
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, count - 1, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferData when srcOffset + length is larger than source size");
+
+ var offset = 2;
+ var size = count - offset;
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, offset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferData with valid sub source should succeed");
+ verifyBufferData(test, 0, size, view.slice(offset, offset + size));
+
+ offset = 1;
+ size = 1;
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, offset, size);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferData with valid sub source should succeed");
+ verifyBufferData(test, 0, size, view.slice(offset, offset + size));
+
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.STATIC_DRAW, count);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferData with valid sub source of size 0 should succeed");
+
+ gl.deleteBuffer(buf);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no GL error");
+ }
+}
+
+function bufferSubDataTest(testCases) {
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+ debug("");
+ debug("Test bufferSubData with " + test.type);
+
+ var count = 4;
+ var totalBufferBytes = test.size * count * 2;
+ var buf = gl.createBuffer();
+ shouldBeNonNull(buf);
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, totalBufferBytes, gl.STATIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var arrayBuffer = new ArrayBuffer(test.size * count);
+ var view = new window[test.type](arrayBuffer);
+ for (var ii = 0; ii < count; ++ii) {
+ view[ii] = ii;
+ }
+
+ var sourceByteOffset = test.size * 2;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, 0, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferSubData when srcOffset + length is larger than source size");
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, count + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferSubData when srcOffset + length is larger than source size");
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, count - 1, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling bufferSubData when srcOffset + length is larger than source size");
+
+ var offset = 2;
+ var size = count - offset;
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, offset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferSubData with valid sub source should succeed");
+ verifyBufferData(test, sourceByteOffset, size, view.slice(offset, offset + size));
+
+ offset = 1;
+ size = 1;
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, offset, size);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferSubData with valid sub source should succeed");
+ verifyBufferData(test, sourceByteOffset, size, view.slice(offset, offset + size));
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, sourceByteOffset, view, count);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling bufferSubData with valid sub source of size 0 should succeed");
+
+ gl.deleteBuffer(buf);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no GL error");
+ }
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ var testCases = [
+ {type: "Uint8Array", size: 1},
+ {type: "Int8Array", size: 1},
+ {type: "Int16Array", size: 2},
+ {type: "Uint16Array", size: 2},
+ {type: "Uint32Array", size: 4},
+ {type: "Int32Array", size: 4},
+ {type: "Float32Array", size: 4},
+ {type: "Float64Array", size: 8}
+ ];
+
+ bufferDataTest(testCases);
+ bufferSubDataTest(testCases);
+}
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html
new file mode 100644
index 0000000000..9334ba5cb6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html
@@ -0,0 +1,51 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL buffer overflow test for bindBufferRange</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("WebGL buffer overflow test: buffer overflow will not lead to failure in bindBufferRange");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+debug("");
+var buffer1 = gl.createBuffer();
+gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer1, 0, 4);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where no storage is allocated should succeed.");
+shouldBe("buffer1", "gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)");
+shouldBe("4", "gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0)");
+shouldBe("0", "gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0)");
+
+var buffer2 = gl.createBuffer();
+gl.bindBuffer(gl.UNIFORM_BUFFER, buffer2);
+gl.bufferData(gl.UNIFORM_BUFFER, 4, gl.STATIC_DRAW);
+gl.bindBufferRange(gl.UNIFORM_BUFFER, 1, buffer2, 0, 8);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Calling bindBufferRange on a buffer where the storage is not big enough should succeed.");
+shouldBe("buffer2", "gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1)");
+shouldBe("8", "gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1)");
+shouldBe("0", "gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1)");
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html
new file mode 100644
index 0000000000..438b66df02
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html
@@ -0,0 +1,110 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL buffer binding restrictions 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test binding restrictions governed by the WebGL 2 spec. The test makes sure that bindBuffer,"
+ + "bindBufferRange, and bindBufferBase acts as expected with every target combination.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var validTargets = [gl.ARRAY_BUFFER, gl.ELEMENT_ARRAY_BUFFER, gl.COPY_READ_BUFFER,
+ gl.COPY_WRITE_BUFFER, gl.PIXEL_PACK_BUFFER, gl.PIXEL_UNPACK_BUFFER,
+ gl.TRANSFORM_FEEDBACK_BUFFER, gl.UNIFORM_BUFFER];
+
+var bindFunctions = ["bindBuffer", "bindBufferRange", "bindBufferBase"];
+
+var isCopyTarget = function(target) {
+ return target == gl.COPY_READ_BUFFER || target == gl.COPY_WRITE_BUFFER;
+}
+
+var noElementArrayVsOtherDataConflicts = function(first, second) {
+ return isCopyTarget(second) || ((first == gl.ELEMENT_ARRAY_BUFFER) == (second == gl.ELEMENT_ARRAY_BUFFER));
+};
+
+
+var bind = function(bindFn, target, buffer) {
+ if (bindFn == "bindBuffer")
+ gl.bindBuffer(target, buffer);
+ else if (bindFn == "bindBufferRange")
+ gl.bindBufferRange(target, 0, buffer, 0, 4);
+ else if (bindFn == "bindBufferBase")
+ gl.bindBufferBase(target, 0, buffer);
+ else
+ throw new Error("Cannot bind unknown function: " + bindFn);
+}
+
+var testBindingFn = function(firstBindFn, secondBindFn, firstTarget, secondTarget) {
+ var firstTargetStr = wtu.glEnumToString(gl, firstTarget),
+ secondTargetStr = wtu.glEnumToString(gl, secondTarget);
+ var buffer = gl.createBuffer();
+
+ bind(firstBindFn, firstTarget, buffer);
+ bind(firstBindFn, firstTarget, null);
+ bind(secondBindFn, secondTarget, buffer);
+ bind(secondBindFn, secondTarget, null);
+
+ var messagePrefix = "Binding buffer first with " + firstBindFn + " to gl." + firstTargetStr
+ + " and then binding buffer with " + secondBindFn + " to gl." + secondTargetStr + " should ";
+ if (firstTarget == secondTarget || noElementArrayVsOtherDataConflicts(firstTarget, secondTarget))
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, messagePrefix + "WORK");
+ else
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, messagePrefix + "FAIL");
+}
+
+var testBinding = function(firstTarget, secondTarget) {
+ for (var i = 0; i < bindFunctions.length; i++)
+ if (i == 0 || firstTarget == gl.UNIFORM_BUFFER || firstTarget == gl.TRANSFORM_FEEDBACK_BUFFER)
+ for (var j = 0; j < bindFunctions.length; j++)
+ if (j == 0 || secondTarget == gl.UNIFORM_BUFFER || secondTarget == gl.TRANSFORM_FEEDBACK_BUFFER)
+ testBindingFn(bindFunctions[i], bindFunctions[j], firstTarget, secondTarget);
+};
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+debug("");
+debug("Testing each binding function");
+
+var buffer1 = gl.createBuffer();
+bind("bindBuffer", gl.ARRAY_BUFFER, buffer1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBuffer(gl.ARRAY_BUFFER, buffer1) should WORK");
+
+var buffer2 = gl.createBuffer();
+bind("bindBufferRange", gl.UNIFORM_BUFFER, buffer2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBufferRange(gl.UNIFORM_BUFFER, 0, buffer2, 0, 4) should WORK");
+
+var buffer3 = gl.createBuffer();
+bind("bindBufferBase", gl.UNIFORM_BUFFER, buffer3);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBufferBase(gl.UNIFORM_BUFFER, 0, buffer3) should WORK");
+
+for (var i = 0; i < validTargets.length; i++) {
+ debug("");
+ debug("Testing binding a buffer first to " + wtu.glEnumToString(gl, validTargets[i])
+ + " and then to another target");
+ for (var j = 0; j < validTargets.length; j++)
+ testBinding(validTargets[i], validTargets[j]);
+}
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/delete-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/delete-buffer.html
new file mode 100644
index 0000000000..d438d65521
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/delete-buffer.html
@@ -0,0 +1,80 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL buffer deletion behavior 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test buffer deletion behavior.");
+// This is a regression test for https://crbug.com/822976
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+function runTexImageTest(gl) {
+ debug("");
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, 4, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, buffer);
+ gl.deleteBuffer(buffer);
+ // Indexed uniform buffer bindings should not prevent a buffer from being
+ // deleted. Therefore, PIXEL_UNPACK_BUFFER binding should also be 0.
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ var data = new Uint8Array(1024);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 16, 16, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D should succeed");
+
+ // Clean up bindings just in case an implementation gets it wrong.
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, null);
+}
+
+function runReadPixelsTest(gl) {
+ debug("");
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, 4, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, buffer);
+ gl.deleteBuffer(buffer);
+ // Indexed transform feedback buffer bindings should not prevent a buffer
+ // from being deleted. Therefore, PIXEL_PACK_BUFFER binding should also be 0.
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+
+ var buffer = new Uint8Array(1024);
+ gl.readPixels(0, 0, 16, 16, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should succeed");
+
+ // Clean up bindings just in case an implementation gets it wrong.
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, null);
+}
+
+runTexImageTest(gl);
+runReadPixelsTest(gl);
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html
new file mode 100644
index 0000000000..06ce2ecb5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html
@@ -0,0 +1,250 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 getBufferSubData validity tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"> </script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in uint in_data;
+flat out uint out_data;
+void main() {
+ out_data = in_data;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+void main() {}
+</script>
+
+<script>
+"use strict";
+description("Test that getBufferSubData returns valid data in edge cases");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+const srcData = new Uint8Array([ 1, 2, 3, 4, 5, 6, 7, 8 ]);
+const noData = new Uint8Array(8);
+
+const srcBuffer = gl.createBuffer();
+gl.bindBuffer(gl.COPY_READ_BUFFER, srcBuffer);
+gl.bufferData(gl.COPY_READ_BUFFER, srcData, gl.STATIC_DRAW);
+
+const badBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, 8, gl.STATIC_DRAW);
+
+let readbackBuffer;
+function deleteReadbackBuffer() {
+ gl.deleteBuffer(readbackBuffer);
+}
+function recreateReadbackBuffer() {
+ readbackBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
+ gl.bufferData(gl.COPY_WRITE_BUFFER, 8, gl.STREAM_READ);
+}
+recreateReadbackBuffer();
+
+const dest = new Uint8Array(8);
+
+// Makes a new "resolvable" Promise
+function resolvable() {
+ let resolve;
+ const promise = new Promise(res => { resolve = res; });
+ promise.resolve = resolve;
+ return promise;
+}
+
+function wait() {
+ return new Promise(res => {
+ setTimeout(res, 0);
+ });
+}
+
+async function fence() {
+ const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ gl.flush();
+
+ let status;
+ do {
+ await wait();
+ status = gl.clientWaitSync(sync, 0, 0);
+ } while (status != gl.ALREADY_SIGNALED && status != gl.CONDITION_SATISFIED);
+ gl.deleteSync(sync);
+}
+
+function checkGetBufferSubData(err, data) {
+ dest.fill(0);
+ wtu.shouldGenerateGLError(gl, err, "gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)");
+ if (!err) {
+ shouldBeTrue(`areArraysEqual(dest, ${data})`);
+ }
+}
+
+const tfProgram = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_data"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+shouldBeNonNull("tfProgram");
+const tf = gl.createTransformFeedback();
+
+function copyBufferUsingTransformFeedback(src, dst) {
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, src);
+ gl.vertexAttribIPointer(0, 1, gl.UNSIGNED_INT, 0, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, dst);
+
+ gl.drawBuffers([gl.NONE]);
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.beginTransformFeedback(gl.POINTS);
+ // treats the input and output data as two uint32s
+ gl.drawArrays(gl.POINTS, 0, 2);
+ gl.endTransformFeedback();
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+}
+
+(async () => {
+ debug("");
+ debug("write-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("fence-wait-write-read");
+ await fence();
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-read-fence-wait");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+ await fence();
+
+ debug("");
+ debug("write-fence-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ fence(); // no await
+ await fence();
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await fence();
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-wait-write-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await fence();
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-write-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await p;
+ }
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-transformfeedback-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
+ copyBufferUsingTransformFeedback(srcBuffer, readbackBuffer);
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
+ await p;
+ }
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-unbind-fence-wait-bind-read");
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, readbackBuffer);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ARRAY_BUFFER, 0, 0, 8);
+ gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
+ await fence();
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
+ checkGetBufferSubData(gl.NO_ERROR, "srcData");
+
+ debug("");
+ debug("write-fence-wait-delete-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ await fence();
+ deleteReadbackBuffer();
+ checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
+ recreateReadbackBuffer();
+
+ debug("");
+ debug("write-fence-delete-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ deleteReadbackBuffer();
+ await p;
+ }
+ checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
+ recreateReadbackBuffer();
+
+ debug("");
+ debug("write-fence-delete-wait-read");
+ gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ deleteReadbackBuffer();
+ await fence();
+ checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
+ recreateReadbackBuffer();
+
+ // crbug.com/941930
+ {
+ debug("");
+ debug("write-delete-recreate-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ deleteReadbackBuffer();
+ recreateReadbackBuffer();
+ await fence();
+ checkGetBufferSubData(gl.NO_ERROR, "noData");
+
+ debug("");
+ debug("write-delete-fence-wait-read");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
+ {
+ const p = fence();
+ deleteReadbackBuffer();
+ await p;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+
+ finishTest();
+})();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html
new file mode 100644
index 0000000000..5919a86996
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html
@@ -0,0 +1,223 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL getBufferSubData 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test makes sure that getBufferSubData acts as expected governed by WebGL 2.");
+
+var wtu = WebGLTestUtils;
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+var vertices = [
+ 1.1, 1.0, 1.3,
+ -1.0, -1.0, -5.0,
+ 5.3, -1.0, 1.0
+];
+var floatArray = new Float32Array(vertices);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var buffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW);
+
+var uninitializedBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, uninitializedBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, 36, gl.STATIC_DRAW);
+gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from buffer setup.");
+
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+debug("");
+debug("Test that getBufferSubData successfully works reading buffer data from gl.ARRAY_BUFFER");
+var retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+
+debug("Argument must be ArrayBufferView, not ArrayBuffer")
+shouldThrow("gl.getBufferSubData(gl.ARRAY_BUFFER, 0, new ArrayBuffer(4))");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should not generate GL error");
+debug("Argument must be ArrayBufferView, not null")
+shouldThrow("gl.getBufferSubData(gl.ARRAY_BUFFER, 0, null)");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should not generate GL error");
+
+debug("Check array data to match original data set by the buffer");
+shouldBeTrue("areArraysEqual(retArray, floatArray)");
+
+debug("Test that getBufferSubData successfully works with dstOffset");
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2), floatArray.slice(0, floatArray.length - 2))");
+
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length)");
+shouldBeTrue("areArraysEqual(retArray, [0, 0, 0, 0, 0, 0, 0, 0, 0])");
+
+debug("Test that getBufferSubData fails when given a dstOffset beyond the end of retArray");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length + 1)");
+
+debug("Test that getBufferSubData successfully works with dstOffset and length");
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2, 4), floatArray.slice(0, 2))");
+shouldBeTrue("areArraysEqual(retArray.slice(4), [0, 0, 0, 0, 0])");
+
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 1)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 8), [0, 0, 0, 0, 0, 0, 0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(8), floatArray.slice(0, 1))");
+
+debug("Test that getBufferSubData fails when given a dstOffset+length beyond the end of retArray");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 2)");
+
+debug("Test that getBufferSubData successfully works with srcByteOffset");
+retArray = new Float32Array(vertices.length - 2);
+const float32Size = Float32Array.BYTES_PER_ELEMENT;
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 2*float32Size, retArray)");
+shouldBeTrue("areArraysEqual(retArray, floatArray.slice(2))");
+
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 2*float32Size, retArray, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2), floatArray.slice(2))");
+
+retArray = new Float32Array(vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 4*float32Size, retArray, 3, 3)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 3), [0, 0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(3, 6), floatArray.slice(4, 7))");
+shouldBeTrue("areArraysEqual(retArray.slice(6), [0, 0, 0])");
+
+debug("Test that getBufferSubData fails when given a buffer with its size larger than the original data");
+var extraLargeBuffer = new Float32Array(vertices.length + 1);
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, extraLargeBuffer)",
+ "Extra length should generate INVALID_VALUE.");
+extraLargeBuffer = new Float32Array(vertices.length - 1);
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 2*float32Size, extraLargeBuffer)",
+ "Extra length should generate INVALID_VALUE.");
+
+debug("Test that getBufferSubData fails when offset summed with buffer length is larger than the size of the original data size");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, retArray.byteLength + 1, retArray)");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 1, retArray)");
+
+debug("Test that getBufferSubData successfully works with offset view into ArrayBuffer");
+const verticesLengthInBytes = vertices.length * float32Size;
+const retStorage = new ArrayBuffer(4* verticesLengthInBytes); // Over allocate 4x
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+shouldBeTrue("areArraysEqual(retArray, floatArray)");
+
+debug("Test that getBufferSubData successfully works with offset view into ArrayBuffer and dstOffset");
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2), floatArray.slice(0, floatArray.length - 2))");
+
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length)");
+shouldBeTrue("areArraysEqual(retArray, [0, 0, 0, 0, 0, 0, 0, 0, 0])");
+
+debug("Test that getBufferSubData fails when given a dstOffset beyond the end of offset view into ArrayBuffer");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length + 1)");
+
+debug("Test that getBufferSubData successfully works with offset view into ArrayBuffer and dstOffset and length");
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2, 4), floatArray.slice(0, 2))");
+shouldBeTrue("areArraysEqual(retArray.slice(4), [0, 0, 0, 0, 0])");
+
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 1)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 8), [0, 0, 0, 0, 0, 0, 0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(8), floatArray.slice(0, 1))");
+
+debug("Test that getBufferSubData fails when given a dstOffset+length beyond the end of offset view into ArrayBuffer");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 2)");
+
+debug("Test that getBufferSubData successfully works with offset view into ArrayBuffer and srcByteOffset");
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length - 2);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 2*float32Size, retArray)");
+shouldBeTrue("areArraysEqual(retArray, floatArray.slice(2))");
+
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 2*float32Size, retArray, 2)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 2), [0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(2), floatArray.slice(2))");
+
+retArray = new Float32Array(retStorage, verticesLengthInBytes, vertices.length);
+retArray.fill(0);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getBufferSubData(gl.ARRAY_BUFFER, 4*float32Size, retArray, 3, 3)");
+shouldBeTrue("areArraysEqual(retArray.slice(0, 3), [0, 0, 0])");
+shouldBeTrue("areArraysEqual(retArray.slice(3, 6), floatArray.slice(4, 7))");
+shouldBeTrue("areArraysEqual(retArray.slice(6), [0, 0, 0])");
+
+debug("Test that getBufferSubData fails when 0 is bound to the target");
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION,
+ "gl.getBufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, retArray)");
+
+debug("Test that getBufferSubData fails when offset is less than 0");
+wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, "gl.getBufferSubData(gl.ARRAY_BUFFER, -1, retArray)");
+
+debug("");
+debug("Test that getBufferSubData successfully works with uninitialized buffers");
+retArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+gl.bindBuffer(gl.ARRAY_BUFFER, uninitializedBuffer);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+shouldBeTrue("areArraysEqual(retArray, [0, 0, 0, 0, 0, 0, 0, 0, 0])");
+
+debug("");
+debug("Test that getBufferSubData works when a buffer is immediately resized to be too small");
+
+retArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+gl.bufferData(gl.ARRAY_BUFFER, 4, gl.STATIC_DRAW);
+shouldBeTrue("areArraysEqual(retArray, floatArray)");
+
+debug("");
+debug("Test that getBufferSubData works when a buffer is immediately deleted");
+retArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW);
+wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
+ "gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray)");
+gl.deleteBuffer(buffer);
+shouldBeTrue("areArraysEqual(retArray, floatArray)");
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html
new file mode 100644
index 0000000000..a2bddce04c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html
@@ -0,0 +1,195 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Uniform Buffers Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 position;
+void main()
+{
+ gl_Position = position;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform uni {
+ vec4 color;
+};
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = color;
+}
+</script>
+<script>
+"use strict";
+description("This test covers ANGLE bugs when using a large uniform blocks. ANGLE would confuse an internal clipped uniform buffer size and produce an assert or error. Also there were issues with readback of large UBOs. See http://crbug.com/660670.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var quadVB;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("");
+ debug("Testing uniform block with large data store");
+ runTest();
+
+ debug("");
+ debug("Testing readback on uniform block with large data store");
+ runReadbackTest();
+}
+
+function getQuadVerts(depth) {
+ var quadVerts = new Float32Array(3 * 6);
+ quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth;
+ quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth;
+ quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth;
+ quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth;
+ quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth;
+ quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth;
+ return quadVerts;
+}
+
+function drawQuad(depth) {
+ if (!quadVB) {
+ quadVB = gl.createBuffer()
+ }
+
+ var quadVerts = getQuadVerts(depth);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, quadVB);
+ gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+}
+
+function runTest() {
+
+ // Create the program
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"]);
+ if (!program) {
+ testFailed("Failed to set up the program");
+ return;
+ }
+
+ // Init uniform buffer. To trigger the bug, it's necessary to use the
+ // DYNAMIC_DRAW usage. This makes ANGLE attempt to map the buffer internally
+ // with an incorrect copy size.
+ var ubo = gl.createBuffer();
+ var big_size = 4096 * 64;
+ var data = new Float32Array([0.5, 0.75, 0.25, 1.0]);
+ gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
+ gl.bufferData(gl.UNIFORM_BUFFER, big_size, gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
+
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo);
+ var buffer_index = gl.getUniformBlockIndex(program, "uni");
+ if (buffer_index == -1) {
+ testFailed("Failed to get uniform block index");
+ return;
+ }
+ gl.uniformBlockBinding(program, buffer_index, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up uniform block should succeed");
+
+ // Draw the quad
+ gl.useProgram(program);
+ drawQuad(0.5);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw with uniform block should succeed");
+
+ // Verify the output color
+ var color = [127, 191, 64, 255];
+ wtu.checkCanvas(gl, color, "canvas should be same as input uniform", 1);
+}
+
+function runReadbackTest() {
+
+ // Create the program
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"]);
+ if (!program) {
+ testFailed("Failed to set up the program");
+ return;
+ }
+
+ // Init uniform buffer. To trigger the bug, it's necessary to use the
+ // DYNAMIC_DRAW usage. This makes ANGLE attempt to map the buffer internally
+ // with an incorrect copy size.
+ var ubo = gl.createBuffer();
+ var num_floats = 4096 * 16;
+ var expected_data = new Float32Array(num_floats);
+ for (var index = 0; index < num_floats; ++index) {
+ expected_data[index] = index;
+ }
+
+ expected_data[0] = 0.5;
+ expected_data[1] = 0.75;
+ expected_data[2] = 0.25;
+ expected_data[3] = 1.0;
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
+ gl.bufferData(gl.UNIFORM_BUFFER, expected_data, gl.DYNAMIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, expected_data);
+
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo);
+ var buffer_index = gl.getUniformBlockIndex(program, "uni");
+ if (buffer_index == -1) {
+ testFailed("Failed to get uniform block index");
+ return;
+ }
+ gl.uniformBlockBinding(program, buffer_index, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up uniform block should succeed");
+
+ // Draw the quad
+ gl.useProgram(program);
+ drawQuad(0.5);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw with uniform block should succeed");
+
+ // Verify the output color
+ var color = [127, 191, 64, 255];
+ wtu.checkCanvas(gl, color, "canvas should be same as input uniform", 1);
+
+ // Verify readback
+ var actual_data = new Float32Array(num_floats);
+ gl.getBufferSubData(gl.UNIFORM_BUFFER, 0, actual_data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Readback from uniform block should succeed");
+
+ for (var index = 0; index < num_floats; ++index) {
+ if (actual_data[index] != expected_data[index]) {
+ testFailed("Expected and actual buffer data do not match");
+ return;
+ }
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-second-compile.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-second-compile.html
new file mode 100644
index 0000000000..936126856e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-second-compile.html
@@ -0,0 +1,104 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Uniform Buffers should work on second compile</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>
+#version 300 es
+
+layout(location=0) in vec4 position;
+layout(std140, column_major) uniform Uniforms1 {
+ mat4 transform;
+};
+out vec3 vColor;
+
+void main() {
+ gl_Position = transform * position;
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>
+#version 300 es
+precision highp float;
+
+layout(std140) uniform Uniforms2 {
+ vec4 color;
+};
+out vec4 fragColor;
+
+void main(){
+ fragColor = color;
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies that getUniformBlockIndex isn't broken on second compile.");
+
+debug("This is a regression test for <a href='http://crbug.com/716018'>http://crbug.com/716018</a>");
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+// Initialize
+gl.clearColor(0, 0, 0, 1);
+var vsSource = document.getElementById("vshader").text.trim();
+var fsSource = document.getElementById("fshader").text.trim();
+
+function runTest() {
+ // Run twice to make sure that the second build does not cause errors
+ // (i.e. due to caching).
+ for (var i = 0; i < 2; ++i) {
+ debug("Compile/test iteration " + i);
+
+ var vertexShader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vertexShader, vsSource);
+ gl.compileShader(vertexShader);
+ // Note: if COMPILE_STATUS is retrieved here, it hides the bug.
+
+ var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragmentShader, fsSource);
+ gl.compileShader(fragmentShader);
+ // Note: if COMPILE_STATUS is retrieved here, it hides the bug.
+
+ var program = gl.createProgram();
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ gl.useProgram(program);
+
+ var uniforms1Location = gl.getUniformBlockIndex(program, "Uniforms1");
+ gl.uniformBlockBinding(program, uniforms1Location, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uniforms1Location was " + uniforms1Location);
+
+ var uniforms2Location = gl.getUniformBlockIndex(program, "Uniforms2");
+ gl.uniformBlockBinding(program, uniforms2Location, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uniforms2Location was " + uniforms2Location);
+
+ debug("");
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-state-restoration.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-state-restoration.html
new file mode 100644
index 0000000000..51edd6ec07
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-state-restoration.html
@@ -0,0 +1,101 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Uniform Buffers State Restoration Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in vec3 p;
+void main()
+{
+ gl_Position = vec4(p.xyz, 1.0);
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ vec4 uboColor;
+};
+
+void main()
+{
+ oColor = uboColor;
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This is a regression test verifying that uniform buffer bindings persist correctly across frames: <a href='http://crbug.com/722060'>crbug.com/722060</a>");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var greenBuf = null;
+var throwawayBuf = null;
+var red = new Float32Array([1, 0, 0, 1]);
+var green = new Float32Array([0, 1, 0, 1]);
+var frame = 0;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ initTest();
+ wtu.waitForComposite(runTest);
+}
+
+function initTest() {
+ wtu.setupUnitQuad(gl);
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ if (!program) {
+ testFailed("Could not compile shader with uniform blocks without error");
+ return;
+ }
+ var uboLocation = gl.getUniformBlockIndex(program, "UBOData");
+ gl.uniformBlockBinding(program, uboLocation, 0);
+
+ greenBuf = gl.createBuffer();
+ throwawayBuf = gl.createBuffer();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createBuffer should not set an error");
+
+ // Bind uniform buffer (both index 0 AND generic binding points) to greenBuf
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, greenBuf);
+ gl.bufferData(gl.UNIFORM_BUFFER, green, gl.STATIC_DRAW);
+ // Bind throwaray uniform buffer (from only the generic binding point)
+ gl.bindBuffer(gl.UNIFORM_BUFFER, throwawayBuf);
+}
+
+function runTest() {
+ // ONLY the binding point at index 0 (not the generic binding point) should be greenBuf.
+ // (The generic binding point should point at throwawayBuf.)
+ // So this bufferData should go into throwawayBuf.
+ gl.bufferData(gl.UNIFORM_BUFFER, red, gl.STATIC_DRAW);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "draw call should set canvas to green", 2);
+ finishTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html
new file mode 100644
index 0000000000..a6bd1b4bc9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html
@@ -0,0 +1,576 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Uniform Buffers Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in vec3 p;
+void main()
+{
+ gl_Position = vec4(p.xyz, 1.0);
+}
+</script>
+<script id='fbadshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float UBORed;
+ float UBOGreen;
+ float UBOBlue;
+};
+
+uniform Color {
+ float Red;
+ float UBOGreen;
+ float Blue;
+};
+
+void main()
+{
+ oColor = vec4(UBORed * Red, UBOGreen * UBOGreen, UBOBlue * Blue, 1.0);
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float UBORed;
+ float UBOGreen;
+ float UBOBlue;
+};
+
+uniform UBOD {
+ float UBOR;
+ float UBOG;
+ float UBOB;
+};
+
+void main()
+{
+ oColor = vec4(UBORed * UBOR, UBOGreen * UBOG, UBOBlue * UBOB, 1.0);
+}
+</script>
+<script id='fshadernamed' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float Red;
+ float Green;
+ float Blue;
+} UBOA;
+
+void main()
+{
+ oColor = vec4(UBOA.Red, UBOA.Green, UBOA.Blue, 1.0);
+}
+</script>
+<script id='fshadernamedarray' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float Red;
+ float Green;
+ float Blue;
+} UBOA[2];
+
+void main()
+{
+ oColor = vec4((UBOA[0].Red + UBOA[1].Red) / 2.0,
+ (UBOA[0].Green + UBOA[1].Green) / 2.0,
+ (UBOA[0].Blue + UBOA[1].Blue) / 2.0, 1.0);
+}
+</script>
+<script id='fshadernestedstruct' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+struct color_t {
+ float red;
+ float green;
+ float blue;
+};
+
+struct wrapper_t {
+ color_t color;
+};
+
+uniform UBOData {
+ wrapper_t UBOStruct;
+};
+
+// This is intended to reproduce a specific ANGLE bug that triggers when the wrapper struct is passed to a function.
+// https://bugs.chromium.org/p/angleproject/issues/detail?id=2084
+void processColor(wrapper_t wrapper) {
+ oColor = vec4(wrapper.color.red, wrapper.color.green, wrapper.color.blue, 1.0);
+}
+
+void main()
+{
+ processColor(UBOStruct);
+}
+</script>
+<script id='fshaderarrayofstructs' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+struct color_t {
+ float red;
+ float green;
+ float blue;
+};
+
+uniform UBOData {
+ color_t UBOColors[2];
+};
+
+// This is intended to reproduce a specific ANGLE bug that triggers when a struct from an array of structs in an interface block is passed to a function.
+// https://bugs.chromium.org/p/angleproject/issues/detail?id=2084
+vec3 processColor(color_t color) {
+ return vec3(color.red, color.green, color.blue);
+}
+
+void main()
+{
+ oColor = vec4(processColor(UBOColors[0]) + processColor(UBOColors[1]), 1.0);
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the Uniform Buffer objects");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var b1 = null;
+var b2 = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ wtu.setupUnitQuad(gl);
+
+ runBindingTest();
+ runBadShaderTest();
+ runUniformBufferOffsetAlignmentTest();
+ runDrawTest();
+ runNamedDrawTest();
+ runNamedArrayDrawTest();
+ runNestedStructsDrawTest();
+ runArrayOfStructsDrawTest();
+}
+
+function runBindingTest() {
+ debug("");
+ debug("Testing uniform buffer binding behavior");
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "UNIFORM_BUFFER_BINDING query should succeed");
+
+ debug("Testing basic uniform buffer binding and unbinding");
+ b1 = gl.createBuffer();
+ b2 = gl.createBuffer();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createBuffer should not set an error");
+ shouldBeNonNull("b1");
+ shouldBeNonNull("b2");
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to bind uniform buffer");
+ shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "b1");
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to update uniform buffer binding");
+ shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "b2");
+ gl.bindBuffer(gl.UNIFORM_BUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to unbind uniform buffer");
+
+ debug("Testing deleting uniform buffers");
+ gl.deleteBuffer(b1);
+ gl.deleteBuffer(b2);
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+
+ // Shouldn't be able to bind a deleted buffer.
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted buffer should generate INVALID_OPERATION");
+ shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+}
+
+function runBadShaderTest() {
+ debug("");
+ var testProgram = wtu.setupProgram(gl, ['vshader', 'fbadshader']);
+ if (testProgram) {
+ testFailed("To define the same uniform in two uniform blocks should fail");
+ } else {
+ testPassed("To define the same uniform in two uniform blocks should fail");
+ }
+}
+
+function runUniformBufferOffsetAlignmentTest() {
+ debug("");
+ var offsetAlignment = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+
+ if (offsetAlignment % 4 != 0) {
+ testFailed("Unexpected UNIFORM_BUFFER_OFFSET_ALIGNMENT - should be aligned on a 4-byte boundary");
+ } else {
+ testPassed("UNIFORM_BUFFER_OFFSET_ALIGNMENT is divisible by four");
+ }
+}
+
+function setRGBValuesToFloat32Array(floatView, red, green, blue) {
+ floatView[0] = red;
+ floatView[1] = green;
+ floatView[2] = blue;
+}
+
+function checkFloat32UniformOffsetsInStd140Layout(uniformOffsets, expectedInitialOffset) {
+ if (expectedInitialOffset === undefined)
+ {
+ expectedInitialOffset = 0;
+ }
+ // Verify that the uniform offsets are set according to the std140 layout, which WebGL enforces.
+ // This function checks this for 32-bit float values, which are expected to be tightly packed.
+ for (var i = 0; i < uniformOffsets.length; ++i)
+ {
+ if (uniformOffsets[i] != expectedInitialOffset + i * Float32Array.BYTES_PER_ELEMENT)
+ {
+ testFailed("Uniform offsets are not according to std140 layout");
+ return false;
+ }
+ }
+ return true;
+}
+
+function runDrawTest() {
+ debug("");
+ debug("Testing drawing with uniform buffers");
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ if (!program) {
+ testFailed("Could not compile shader with uniform blocks without error");
+ return;
+ }
+
+ var blockIndex_1 = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize_1 = gl.getActiveUniformBlockParameter(program, blockIndex_1, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices_1 = gl.getUniformIndices(program, ["UBORed", "UBOGreen", "UBOBlue"]);
+ var uniformOffsets_1 = gl.getActiveUniforms(program, uniformIndices_1, gl.UNIFORM_OFFSET);
+ var blockIndex_2 = gl.getUniformBlockIndex(program, "UBOD");
+ var blockSize_2 = gl.getActiveUniformBlockParameter(program, blockIndex_2, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices_2 = gl.getUniformIndices(program, ["UBOR", "UBOG", "UBOB"]);
+ var uniformOffsets_2 = gl.getActiveUniforms(program, uniformIndices_2, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+
+ if (uniformOffsets_1.length < 3 || uniformOffsets_2.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ if (!checkFloat32UniformOffsetsInStd140Layout(uniformOffsets_1) || !checkFloat32UniformOffsetsInStd140Layout(uniformOffsets_2))
+ {
+ return;
+ }
+
+ var uboArray_1 = new ArrayBuffer(blockSize_1);
+ var uboFloatView_1 = new Float32Array(uboArray_1);
+ setRGBValuesToFloat32Array(uboFloatView_1, 1.0, 0.0, 0.0); // UBORed, UBOGreen, UBOBlue
+ var uboArray_2 = new ArrayBuffer(blockSize_2);
+ var uboFloatView_2 = new Float32Array(uboArray_2);
+ setRGBValuesToFloat32Array(uboFloatView_2, 1.0, 1.0, 1.0); // UBOR, UBOG, UBOB
+
+ var b_1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b_1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView_1, gl.DYNAMIC_DRAW);
+ var b_2 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b_2);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView_2, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var bindings = [1, 2];
+ gl.uniformBlockBinding(program, blockIndex_1, bindings[0]);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindings[0], b_1);
+ gl.uniformBlockBinding(program, blockIndex_2, bindings[1]);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, bindings[1], b_2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferBase without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ setRGBValuesToFloat32Array(uboFloatView_1, 0.0, 0.0, 1.0); // UBORed, UBOGreen, UBOBlue
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b_1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView_1, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "draw call should set canvas to blue", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runNamedDrawTest() {
+ debug("");
+ debug("Testing drawing with named uniform buffers");
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshadernamed']);
+ if (!program) {
+ testFailed("Could not compile shader with named uniform blocks without error");
+ return;
+ }
+
+ var blockIndex = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices = gl.getUniformIndices(program, ["UBOData.Red", "UBOData.Green", "UBOData.Blue"]);
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ if (!checkFloat32UniformOffsetsInStd140Layout(uniformOffsets))
+ {
+ return;
+ }
+
+ var uboArray = new ArrayBuffer(blockSize);
+ var uboFloatView = new Float32Array(uboArray);
+ setRGBValuesToFloat32Array(uboFloatView, 1.0, 0.0, 0.0);
+
+ b1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var binding = 3;
+ gl.uniformBlockBinding(program, blockIndex, binding);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, b1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferBase without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ setRGBValuesToFloat32Array(uboFloatView, 0.0, 0.0, 1.0);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "draw call should set canvas to blue", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runNamedArrayDrawTest() {
+ debug("");
+ debug("Testing drawing with named uniform buffer arrays");
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshadernamedarray']);
+ if (!program) {
+ testFailed("could not compile shader with named uniform block arrays without error");
+ return;
+ }
+
+ var blockIndex = [gl.getUniformBlockIndex(program, "UBOData[0]"),
+ gl.getUniformBlockIndex(program, "UBOData[1]")];
+ if (blockIndex[0] == gl.INVALID_INDEX ||
+ blockIndex[1] == gl.INVALID_INDEX) {
+ testFailed("Could not query uniform block index");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block indices without error");
+ var blockSize = [gl.getActiveUniformBlockParameter(program, blockIndex[0], gl.UNIFORM_BLOCK_DATA_SIZE),
+ gl.getActiveUniformBlockParameter(program, blockIndex[1], gl.UNIFORM_BLOCK_DATA_SIZE)];
+ if (blockSize[0] != blockSize[1]) {
+ testFailed("uniform block instance array with different block sizes");
+ }
+ var uniformIndices = gl.getUniformIndices(program, ["UBOData.Red", "UBOData.Green", "UBOData.Blue"]);
+ if (uniformIndices < 3 ||
+ uniformIndices[0] == gl.INVALID_INDEX ||
+ uniformIndices[1] == gl.INVALID_INDEX ||
+ uniformIndices[2] == gl.INVALID_INDEX) {
+ testFailed("Could not query uniform indices");
+ return;
+ }
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ if (!checkFloat32UniformOffsetsInStd140Layout(uniformOffsets))
+ {
+ return;
+ }
+
+ var offsetAlignment = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ var offset = Math.ceil(blockSize[0] / offsetAlignment) * offsetAlignment;
+
+ var bufferSize = offset + blockSize[1];
+ var uboArray = new ArrayBuffer(bufferSize);
+ var uboFloatView = new Float32Array(uboArray);
+ setRGBValuesToFloat32Array(uboFloatView, 1.0, 0.0, 0.0);
+ var uboFloatView2 = new Float32Array(uboArray, offset);
+ setRGBValuesToFloat32Array(uboFloatView2, 0.0, 0.0, 1.0);
+
+ b1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var bindings = [4, 5];
+ gl.uniformBlockBinding(program, blockIndex[0], bindings[0]);
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, bindings[0], b1, 0, blockSize[0]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferRange without errors");
+ gl.uniformBlockBinding(program, blockIndex[1], bindings[1]);
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, bindings[1], b1, offset, blockSize[1]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferRange without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [127, 0, 127, 255], "draw call should set canvas to (0.5, 0, 0.5)", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ setRGBValuesToFloat32Array(uboFloatView, 0.0, 1.0, 1.0);
+ setRGBValuesToFloat32Array(uboFloatView2, 0.0, 0.0, 1.0);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 127, 255, 255], "draw call should set canvas to (0, 0.5, 1)", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runNestedStructsDrawTest() {
+ debug("");
+ debug("Testing drawing with nested struct inside uniform block. The wrapper struct is passed to a function.");
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshadernestedstruct'], undefined, undefined, true);
+ if (!program) {
+ testFailed("Could not compile shader with nested structs without error");
+ return;
+ }
+
+ var blockIndex = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices = gl.getUniformIndices(program, ["UBOStruct.color.red", "UBOStruct.color.green", "UBOStruct.color.blue"]);
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ if (!checkFloat32UniformOffsetsInStd140Layout(uniformOffsets))
+ {
+ return;
+ }
+
+ var uboArray = new ArrayBuffer(blockSize);
+ var uboFloatView = new Float32Array(uboArray);
+ setRGBValuesToFloat32Array(uboFloatView, 0.0, 1.0, 0.0);
+
+ b1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var binding = 3;
+ gl.uniformBlockBinding(program, blockIndex, binding);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, b1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferBase without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "draw call should set canvas to green", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ setRGBValuesToFloat32Array(uboFloatView, 0.0, 0.0, 1.0);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "draw call should set canvas to blue", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runArrayOfStructsDrawTest() {
+ debug("");
+ debug("Testing drawing with array of structs inside uniform block. A struct in the block is passed to a function.");
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshaderarrayofstructs'], undefined, undefined, true);
+ if (!program) {
+ testFailed("Could not compile shader with an array of structs in an interface block without error");
+ return;
+ }
+
+ var blockIndex = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices = gl.getUniformIndices(program, ["UBOColors[0].red", "UBOColors[0].green", "UBOColors[0].blue"]);
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+ var uniformIndices_2 = gl.getUniformIndices(program, ["UBOColors[1].red", "UBOColors[1].green", "UBOColors[1].blue"]);
+ var uniformOffsets_2 = gl.getActiveUniforms(program, uniformIndices_2, gl.UNIFORM_OFFSET);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to query uniform block information without error");
+
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ if (!checkFloat32UniformOffsetsInStd140Layout(uniformOffsets))
+ {
+ return;
+ }
+ if (!checkFloat32UniformOffsetsInStd140Layout(uniformOffsets_2, uniformOffsets_2[0]))
+ {
+ return;
+ }
+
+ var uboArray = new ArrayBuffer(blockSize);
+ var uboFloatView = new Float32Array(uboArray);
+ setRGBValuesToFloat32Array(uboFloatView, 0.0, 0.5, 0.0);
+ var uboFloatView2 = new Float32Array(uboArray, uniformOffsets_2[0]);
+ setRGBValuesToFloat32Array(uboFloatView2, 0.0, 0.5, 0.0);
+
+ b1 = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, b1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to set UBO data with no errors");
+
+ var binding = 3;
+ gl.uniformBlockBinding(program, blockIndex, binding);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, b1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call bindBufferBase without errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "draw call should set canvas to green", 2);
+
+ debug("Changing the data in the uniform buffer should automatically update the uniforms exposed to the draw call");
+ setRGBValuesToFloat32Array(uboFloatView, 1.0, 0.0, 0.0);
+ setRGBValuesToFloat32Array(uboFloatView2, 0.0, 0.0, 1.0);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboArray, gl.DYNAMIC_DRAW);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 255, 255], "draw call should set canvas to purple", 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/00_test_list.txt
new file mode 100644
index 0000000000..35e011f3bf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/00_test_list.txt
@@ -0,0 +1 @@
+--min-version 2.0.1 to-data-url-with-pack-params.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/compositing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/compositing.html
new file mode 100644
index 0000000000..cd9bf594fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/compositing.html
@@ -0,0 +1,92 @@
+<!--
+Copyright (c) 2022 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 draw functions have expected behavior with compositing</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"> </script>
+<script src="../../js/tests/compositing-test.js"></script>
+<style>
+body {
+ height: 3000px;
+}
+</style>
+</head>
+<body>
+<!-- Important to put the canvas at the top so that it's always visible even in the test suite runner.
+ Otherwise it just doesn't get composited in Firefox. -->
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+description(`\
+This test ensures WebGL implementations correctly clear the drawing buffer
+on composite if preserveDrawingBuffer is false and is not cleared if
+preserveDrawingBuffer is true.`);
+debug("");
+
+const wtu = WebGLTestUtils;
+
+async function runCompositingTests() {
+ const compositingTestFn = createCompositingTestFn({
+ webglVersion: 2,
+ shadersFn(gl) {
+ const vs = `\
+ #version 300 es
+ in vec4 position;
+ void main() {
+ gl_Position = position;
+ }
+ `;
+ const fs = `\
+ #version 300 es
+ precision mediump float;
+ out vec4 fragColor;
+ void main() {
+ fragColor = vec4(1, 0, 0, 1);
+ }
+ `;
+ return [vs, fs];
+ },
+ });
+
+ function drawArrays(gl) {
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ function drawElements(gl) {
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ }
+
+ function drawArraysInstanced(gl) {
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, 1);
+ }
+
+ function drawElementsInstanced(gl) {
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 1);
+ }
+
+ function drawRangeElements(gl) {
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_BYTE, 0);
+ }
+
+ await compositingTestFn(drawArrays);
+ await compositingTestFn(drawElements);
+ await compositingTestFn(drawArraysInstanced);
+ await compositingTestFn(drawElementsInstanced);
+ await compositingTestFn(drawRangeElements);
+ finishTest();
+}
+runCompositingTests();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/to-data-url-with-pack-params.html b/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/to-data-url-with-pack-params.html
new file mode 100644
index 0000000000..354ac2642f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/canvas/to-data-url-with-pack-params.html
@@ -0,0 +1,73 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>toDataURL() runs fine with WebGL2 PIXEL PACK parameters</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="test"></canvas>
+<script>
+"use strict";
+description("This test verifies toDataURL() runs fine with WebGL2 PIXEL PACK parameters");
+// This is a regression test for crbug.com/740603
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("test");
+var gl = wtu.create3DContext(canvas, null, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Testing PACK_SKIP_ROWS");
+ gl.pixelStorei(gl.PACK_SKIP_ROWS, 100);
+ var img = new Image();
+ img.src = canvas.toDataURL(); // This should not crash in ASAN
+ gl.pixelStorei(gl.PACK_SKIP_ROWS, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Test should not generate GL error");
+
+ debug("");
+ debug("Testing PACK_SKIP_PIXELS");
+ gl.pixelStorei(gl.PACK_SKIP_PIXELS, 10000);
+ img = new Image();
+ img.src = canvas.toDataURL(); // This should not crash in ASAN
+ gl.pixelStorei(gl.PACK_SKIP_PIXELS, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Test should not generate GL error");
+
+ debug("");
+ debug("Testing PACK_ROW_LENGTH");
+ gl.pixelStorei(gl.PACK_ROW_LENGTH, 2048);
+ img = new Image();
+ img.src = canvas.toDataURL(); // This should not crash in ASAN
+ gl.pixelStorei(gl.PACK_ROW_LENGTH, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Test should not generate GL error");
+
+ debug("");
+ debug("Testing PIXEL_PACK_BUFFER");
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer);
+ img = new Image();
+ img.src = canvas.toDataURL(); // This should not crash in ASAN
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Test should not generate GL error");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/context/00_test_list.txt
new file mode 100644
index 0000000000..fc4f8b8c07
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/00_test_list.txt
@@ -0,0 +1,10 @@
+constants-and-properties-2.html
+context-attributes-depth-stencil-antialias-obeyed.html
+--min-version 2.0.1 context-mode.html
+--min-version 2.0.1 context-sharing-texture2darray-texture3d-data-bug.html
+context-type-test-2.html
+--min-version 2.0.1 context-resize-changes-buffer-binding-bug.html
+--min-version 2.0.1 incorrect-context-object-behaviour.html
+methods-2.html
+--min-version 2.0.1 no-experimental-webgl2.html
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/constants-and-properties-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/constants-and-properties-2.html
new file mode 100644
index 0000000000..f4e2bfc30e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/constants-and-properties-2.html
@@ -0,0 +1,835 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Constants and Properties 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<script>
+"use strict";
+description("This test ensures that the WebGL context has all the constants and (non-function) properties in the specification.");
+
+var constants = {
+ /* ClearBufferMask */
+DEPTH_BUFFER_BIT : 0x00000100,
+STENCIL_BUFFER_BIT : 0x00000400,
+COLOR_BUFFER_BIT : 0x00004000,
+
+ /* BeginMode */
+POINTS : 0x0000,
+LINES : 0x0001,
+LINE_LOOP : 0x0002,
+LINE_STRIP : 0x0003,
+TRIANGLES : 0x0004,
+TRIANGLE_STRIP : 0x0005,
+TRIANGLE_FAN : 0x0006,
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ZERO : 0,
+ONE : 1,
+SRC_COLOR : 0x0300,
+ONE_MINUS_SRC_COLOR : 0x0301,
+SRC_ALPHA : 0x0302,
+ONE_MINUS_SRC_ALPHA : 0x0303,
+DST_ALPHA : 0x0304,
+ONE_MINUS_DST_ALPHA : 0x0305,
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+DST_COLOR : 0x0306,
+ONE_MINUS_DST_COLOR : 0x0307,
+SRC_ALPHA_SATURATE : 0x0308,
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+FUNC_ADD : 0x8006,
+BLEND_EQUATION : 0x8009,
+BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */
+BLEND_EQUATION_ALPHA : 0x883D,
+
+ /* BlendSubtract */
+FUNC_SUBTRACT : 0x800A,
+FUNC_REVERSE_SUBTRACT : 0x800B,
+
+ /* Separate Blend Functions */
+BLEND_DST_RGB : 0x80C8,
+BLEND_SRC_RGB : 0x80C9,
+BLEND_DST_ALPHA : 0x80CA,
+BLEND_SRC_ALPHA : 0x80CB,
+CONSTANT_COLOR : 0x8001,
+ONE_MINUS_CONSTANT_COLOR : 0x8002,
+CONSTANT_ALPHA : 0x8003,
+ONE_MINUS_CONSTANT_ALPHA : 0x8004,
+BLEND_COLOR : 0x8005,
+
+ /* Buffer Objects */
+ARRAY_BUFFER : 0x8892,
+ELEMENT_ARRAY_BUFFER : 0x8893,
+ARRAY_BUFFER_BINDING : 0x8894,
+ELEMENT_ARRAY_BUFFER_BINDING : 0x8895,
+
+STREAM_DRAW : 0x88E0,
+STATIC_DRAW : 0x88E4,
+DYNAMIC_DRAW : 0x88E8,
+
+BUFFER_SIZE : 0x8764,
+BUFFER_USAGE : 0x8765,
+
+CURRENT_VERTEX_ATTRIB : 0x8626,
+
+ /* CullFaceMode */
+FRONT : 0x0404,
+BACK : 0x0405,
+FRONT_AND_BACK : 0x0408,
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ /* TEXTURE_2D */
+CULL_FACE : 0x0B44,
+BLEND : 0x0BE2,
+DITHER : 0x0BD0,
+STENCIL_TEST : 0x0B90,
+DEPTH_TEST : 0x0B71,
+SCISSOR_TEST : 0x0C11,
+POLYGON_OFFSET_FILL : 0x8037,
+SAMPLE_ALPHA_TO_COVERAGE : 0x809E,
+SAMPLE_COVERAGE : 0x80A0,
+
+ /* ErrorCode */
+NO_ERROR : 0,
+INVALID_ENUM : 0x0500,
+INVALID_VALUE : 0x0501,
+INVALID_OPERATION : 0x0502,
+OUT_OF_MEMORY : 0x0505,
+
+ /* FrontFaceDirection */
+CW : 0x0900,
+CCW : 0x0901,
+
+ /* GetPName */
+LINE_WIDTH : 0x0B21,
+ALIASED_POINT_SIZE_RANGE : 0x846D,
+ALIASED_LINE_WIDTH_RANGE : 0x846E,
+CULL_FACE_MODE : 0x0B45,
+FRONT_FACE : 0x0B46,
+DEPTH_RANGE : 0x0B70,
+DEPTH_WRITEMASK : 0x0B72,
+DEPTH_CLEAR_VALUE : 0x0B73,
+DEPTH_FUNC : 0x0B74,
+STENCIL_CLEAR_VALUE : 0x0B91,
+STENCIL_FUNC : 0x0B92,
+STENCIL_FAIL : 0x0B94,
+STENCIL_PASS_DEPTH_FAIL : 0x0B95,
+STENCIL_PASS_DEPTH_PASS : 0x0B96,
+STENCIL_REF : 0x0B97,
+STENCIL_VALUE_MASK : 0x0B93,
+STENCIL_WRITEMASK : 0x0B98,
+STENCIL_BACK_FUNC : 0x8800,
+STENCIL_BACK_FAIL : 0x8801,
+STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802,
+STENCIL_BACK_PASS_DEPTH_PASS : 0x8803,
+STENCIL_BACK_REF : 0x8CA3,
+STENCIL_BACK_VALUE_MASK : 0x8CA4,
+STENCIL_BACK_WRITEMASK : 0x8CA5,
+VIEWPORT : 0x0BA2,
+SCISSOR_BOX : 0x0C10,
+ /* SCISSOR_TEST */
+COLOR_CLEAR_VALUE : 0x0C22,
+COLOR_WRITEMASK : 0x0C23,
+UNPACK_ALIGNMENT : 0x0CF5,
+PACK_ALIGNMENT : 0x0D05,
+MAX_TEXTURE_SIZE : 0x0D33,
+MAX_VIEWPORT_DIMS : 0x0D3A,
+SUBPIXEL_BITS : 0x0D50,
+RED_BITS : 0x0D52,
+GREEN_BITS : 0x0D53,
+BLUE_BITS : 0x0D54,
+ALPHA_BITS : 0x0D55,
+DEPTH_BITS : 0x0D56,
+STENCIL_BITS : 0x0D57,
+POLYGON_OFFSET_UNITS : 0x2A00,
+ /* POLYGON_OFFSET_FILL */
+POLYGON_OFFSET_FACTOR : 0x8038,
+TEXTURE_BINDING_2D : 0x8069,
+SAMPLE_BUFFERS : 0x80A8,
+SAMPLES : 0x80A9,
+SAMPLE_COVERAGE_VALUE : 0x80AA,
+SAMPLE_COVERAGE_INVERT : 0x80AB,
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+COMPRESSED_TEXTURE_FORMATS : 0x86A3,
+
+ /* HintMode */
+DONT_CARE : 0x1100,
+FASTEST : 0x1101,
+NICEST : 0x1102,
+
+ /* HintTarget */
+GENERATE_MIPMAP_HINT : 0x8192,
+
+ /* DataType */
+BYTE : 0x1400,
+UNSIGNED_BYTE : 0x1401,
+SHORT : 0x1402,
+UNSIGNED_SHORT : 0x1403,
+INT : 0x1404,
+UNSIGNED_INT : 0x1405,
+FLOAT : 0x1406,
+
+ /* PixelFormat */
+DEPTH_COMPONENT : 0x1902,
+ALPHA : 0x1906,
+RGB : 0x1907,
+RGBA : 0x1908,
+LUMINANCE : 0x1909,
+LUMINANCE_ALPHA : 0x190A,
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+UNSIGNED_SHORT_4_4_4_4 : 0x8033,
+UNSIGNED_SHORT_5_5_5_1 : 0x8034,
+UNSIGNED_SHORT_5_6_5 : 0x8363,
+
+ /* Shaders */
+FRAGMENT_SHADER : 0x8B30,
+VERTEX_SHADER : 0x8B31,
+MAX_VERTEX_ATTRIBS : 0x8869,
+MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB,
+MAX_VARYING_VECTORS : 0x8DFC,
+MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
+MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C,
+MAX_TEXTURE_IMAGE_UNITS : 0x8872,
+MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD,
+SHADER_TYPE : 0x8B4F,
+DELETE_STATUS : 0x8B80,
+LINK_STATUS : 0x8B82,
+VALIDATE_STATUS : 0x8B83,
+ATTACHED_SHADERS : 0x8B85,
+ACTIVE_UNIFORMS : 0x8B86,
+ACTIVE_ATTRIBUTES : 0x8B89,
+SHADING_LANGUAGE_VERSION : 0x8B8C,
+CURRENT_PROGRAM : 0x8B8D,
+
+ /* StencilFunction */
+NEVER : 0x0200,
+LESS : 0x0201,
+EQUAL : 0x0202,
+LEQUAL : 0x0203,
+GREATER : 0x0204,
+NOTEQUAL : 0x0205,
+GEQUAL : 0x0206,
+ALWAYS : 0x0207,
+
+ /* StencilOp */
+ /* ZERO */
+KEEP : 0x1E00,
+REPLACE : 0x1E01,
+INCR : 0x1E02,
+DECR : 0x1E03,
+INVERT : 0x150A,
+INCR_WRAP : 0x8507,
+DECR_WRAP : 0x8508,
+
+ /* StringName */
+VENDOR : 0x1F00,
+RENDERER : 0x1F01,
+VERSION : 0x1F02,
+
+ /* TextureMagFilter */
+NEAREST : 0x2600,
+LINEAR : 0x2601,
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+NEAREST_MIPMAP_NEAREST : 0x2700,
+LINEAR_MIPMAP_NEAREST : 0x2701,
+NEAREST_MIPMAP_LINEAR : 0x2702,
+LINEAR_MIPMAP_LINEAR : 0x2703,
+
+ /* TextureParameterName */
+TEXTURE_MAG_FILTER : 0x2800,
+TEXTURE_MIN_FILTER : 0x2801,
+TEXTURE_WRAP_S : 0x2802,
+TEXTURE_WRAP_T : 0x2803,
+
+ /* TextureTarget */
+TEXTURE_2D : 0x0DE1,
+TEXTURE : 0x1702,
+
+TEXTURE_CUBE_MAP : 0x8513,
+TEXTURE_BINDING_CUBE_MAP : 0x8514,
+TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515,
+TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516,
+TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517,
+TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518,
+TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519,
+TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A,
+MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C,
+
+ /* TextureUnit */
+TEXTURE0 : 0x84C0,
+TEXTURE1 : 0x84C1,
+TEXTURE2 : 0x84C2,
+TEXTURE3 : 0x84C3,
+TEXTURE4 : 0x84C4,
+TEXTURE5 : 0x84C5,
+TEXTURE6 : 0x84C6,
+TEXTURE7 : 0x84C7,
+TEXTURE8 : 0x84C8,
+TEXTURE9 : 0x84C9,
+TEXTURE10 : 0x84CA,
+TEXTURE11 : 0x84CB,
+TEXTURE12 : 0x84CC,
+TEXTURE13 : 0x84CD,
+TEXTURE14 : 0x84CE,
+TEXTURE15 : 0x84CF,
+TEXTURE16 : 0x84D0,
+TEXTURE17 : 0x84D1,
+TEXTURE18 : 0x84D2,
+TEXTURE19 : 0x84D3,
+TEXTURE20 : 0x84D4,
+TEXTURE21 : 0x84D5,
+TEXTURE22 : 0x84D6,
+TEXTURE23 : 0x84D7,
+TEXTURE24 : 0x84D8,
+TEXTURE25 : 0x84D9,
+TEXTURE26 : 0x84DA,
+TEXTURE27 : 0x84DB,
+TEXTURE28 : 0x84DC,
+TEXTURE29 : 0x84DD,
+TEXTURE30 : 0x84DE,
+TEXTURE31 : 0x84DF,
+ACTIVE_TEXTURE : 0x84E0,
+
+ /* TextureWrapMode */
+REPEAT : 0x2901,
+CLAMP_TO_EDGE : 0x812F,
+MIRRORED_REPEAT : 0x8370,
+
+ /* Uniform Types */
+FLOAT_VEC2 : 0x8B50,
+FLOAT_VEC3 : 0x8B51,
+FLOAT_VEC4 : 0x8B52,
+INT_VEC2 : 0x8B53,
+INT_VEC3 : 0x8B54,
+INT_VEC4 : 0x8B55,
+BOOL : 0x8B56,
+BOOL_VEC2 : 0x8B57,
+BOOL_VEC3 : 0x8B58,
+BOOL_VEC4 : 0x8B59,
+FLOAT_MAT2 : 0x8B5A,
+FLOAT_MAT3 : 0x8B5B,
+FLOAT_MAT4 : 0x8B5C,
+SAMPLER_2D : 0x8B5E,
+SAMPLER_CUBE : 0x8B60,
+
+ /* Vertex Arrays */
+VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622,
+VERTEX_ATTRIB_ARRAY_SIZE : 0x8623,
+VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624,
+VERTEX_ATTRIB_ARRAY_TYPE : 0x8625,
+VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
+VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
+VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
+
+ /* Shader Source */
+COMPILE_STATUS : 0x8B81,
+
+ /* Shader Precision-Specified Types */
+LOW_FLOAT : 0x8DF0,
+MEDIUM_FLOAT : 0x8DF1,
+HIGH_FLOAT : 0x8DF2,
+LOW_INT : 0x8DF3,
+MEDIUM_INT : 0x8DF4,
+HIGH_INT : 0x8DF5,
+
+ /* Framebuffer Object. */
+FRAMEBUFFER : 0x8D40,
+RENDERBUFFER : 0x8D41,
+
+RGBA4 : 0x8056,
+RGB5_A1 : 0x8057,
+RGB565 : 0x8D62,
+DEPTH_COMPONENT16 : 0x81A5,
+STENCIL_INDEX8 : 0x8D48,
+DEPTH_STENCIL : 0x84F9,
+
+RENDERBUFFER_WIDTH : 0x8D42,
+RENDERBUFFER_HEIGHT : 0x8D43,
+RENDERBUFFER_INTERNAL_FORMAT : 0x8D44,
+RENDERBUFFER_RED_SIZE : 0x8D50,
+RENDERBUFFER_GREEN_SIZE : 0x8D51,
+RENDERBUFFER_BLUE_SIZE : 0x8D52,
+RENDERBUFFER_ALPHA_SIZE : 0x8D53,
+RENDERBUFFER_DEPTH_SIZE : 0x8D54,
+RENDERBUFFER_STENCIL_SIZE : 0x8D55,
+
+FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0,
+FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1,
+FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2,
+FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
+
+COLOR_ATTACHMENT0 : 0x8CE0,
+DEPTH_ATTACHMENT : 0x8D00,
+STENCIL_ATTACHMENT : 0x8D20,
+DEPTH_STENCIL_ATTACHMENT : 0x821A,
+
+NONE : 0,
+
+FRAMEBUFFER_COMPLETE : 0x8CD5,
+FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6,
+FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
+FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9,
+FRAMEBUFFER_UNSUPPORTED : 0x8CDD,
+
+FRAMEBUFFER_BINDING : 0x8CA6,
+RENDERBUFFER_BINDING : 0x8CA7,
+MAX_RENDERBUFFER_SIZE : 0x84E8,
+
+INVALID_FRAMEBUFFER_OPERATION : 0x0506,
+
+IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A,
+IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B,
+
+/* WebGL-specific enums */
+UNPACK_FLIP_Y_WEBGL : 0x9240,
+UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
+CONTEXT_LOST_WEBGL : 0x9242,
+UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
+BROWSER_DEFAULT_WEBGL : 0x9244,
+
+/* WebGL2 enums */
+READ_BUFFER : 0x0C02,
+UNPACK_ROW_LENGTH : 0x0CF2,
+UNPACK_SKIP_ROWS : 0x0CF3,
+UNPACK_SKIP_PIXELS : 0x0CF4,
+PACK_ROW_LENGTH : 0x0D02,
+PACK_SKIP_ROWS : 0x0D03,
+PACK_SKIP_PIXELS : 0x0D04,
+COLOR : 0x1800,
+DEPTH : 0x1801,
+STENCIL : 0x1802,
+RED : 0x1903,
+RGB8 : 0x8051,
+RGBA8 : 0x8058,
+RGB10_A2 : 0x8059,
+TEXTURE_BINDING_3D : 0x806A,
+UNPACK_SKIP_IMAGES : 0x806D,
+UNPACK_IMAGE_HEIGHT : 0x806E,
+TEXTURE_3D : 0x806F,
+TEXTURE_WRAP_R : 0x8072,
+MAX_3D_TEXTURE_SIZE : 0x8073,
+UNSIGNED_INT_2_10_10_10_REV : 0x8368,
+MAX_ELEMENTS_VERTICES : 0x80E8,
+MAX_ELEMENTS_INDICES : 0x80E9,
+TEXTURE_MIN_LOD : 0x813A,
+TEXTURE_MAX_LOD : 0x813B,
+TEXTURE_BASE_LEVEL : 0x813C,
+TEXTURE_MAX_LEVEL : 0x813D,
+MIN : 0x8007,
+MAX : 0x8008,
+DEPTH_COMPONENT24 : 0x81A6,
+MAX_TEXTURE_LOD_BIAS : 0x84FD,
+TEXTURE_COMPARE_MODE : 0x884C,
+TEXTURE_COMPARE_FUNC : 0x884D,
+CURRENT_QUERY : 0x8865,
+QUERY_RESULT : 0x8866,
+QUERY_RESULT_AVAILABLE : 0x8867,
+STREAM_READ : 0x88E1,
+STREAM_COPY : 0x88E2,
+STATIC_READ : 0x88E5,
+STATIC_COPY : 0x88E6,
+DYNAMIC_READ : 0x88E9,
+DYNAMIC_COPY : 0x88EA,
+MAX_DRAW_BUFFERS : 0x8824,
+DRAW_BUFFER0 : 0x8825,
+DRAW_BUFFER1 : 0x8826,
+DRAW_BUFFER2 : 0x8827,
+DRAW_BUFFER3 : 0x8828,
+DRAW_BUFFER4 : 0x8829,
+DRAW_BUFFER5 : 0x882A,
+DRAW_BUFFER6 : 0x882B,
+DRAW_BUFFER7 : 0x882C,
+DRAW_BUFFER8 : 0x882D,
+DRAW_BUFFER9 : 0x882E,
+DRAW_BUFFER10 : 0x882F,
+DRAW_BUFFER11 : 0x8830,
+DRAW_BUFFER12 : 0x8831,
+DRAW_BUFFER13 : 0x8832,
+DRAW_BUFFER14 : 0x8833,
+DRAW_BUFFER15 : 0x8834,
+MAX_FRAGMENT_UNIFORM_COMPONENTS : 0x8B49,
+MAX_VERTEX_UNIFORM_COMPONENTS : 0x8B4A,
+SAMPLER_3D : 0x8B5F,
+SAMPLER_2D_SHADOW : 0x8B62,
+FRAGMENT_SHADER_DERIVATIVE_HINT : 0x8B8B,
+PIXEL_PACK_BUFFER : 0x88EB,
+PIXEL_UNPACK_BUFFER : 0x88EC,
+PIXEL_PACK_BUFFER_BINDING : 0x88ED,
+PIXEL_UNPACK_BUFFER_BINDING : 0x88EF,
+FLOAT_MAT2x3 : 0x8B65,
+FLOAT_MAT2x4 : 0x8B66,
+FLOAT_MAT3x2 : 0x8B67,
+FLOAT_MAT3x4 : 0x8B68,
+FLOAT_MAT4x2 : 0x8B69,
+FLOAT_MAT4x3 : 0x8B6A,
+SRGB : 0x8C40,
+SRGB8 : 0x8C41,
+SRGB8_ALPHA8 : 0x8C43,
+COMPARE_REF_TO_TEXTURE : 0x884E,
+RGBA32F : 0x8814,
+RGB32F : 0x8815,
+RGBA16F : 0x881A,
+RGB16F : 0x881B,
+VERTEX_ATTRIB_ARRAY_INTEGER : 0x88FD,
+MAX_ARRAY_TEXTURE_LAYERS : 0x88FF,
+MIN_PROGRAM_TEXEL_OFFSET : 0x8904,
+MAX_PROGRAM_TEXEL_OFFSET : 0x8905,
+MAX_VARYING_COMPONENTS : 0x8B4B,
+TEXTURE_2D_ARRAY : 0x8C1A,
+TEXTURE_BINDING_2D_ARRAY : 0x8C1D,
+R11F_G11F_B10F : 0x8C3A,
+UNSIGNED_INT_10F_11F_11F_REV : 0x8C3B,
+RGB9_E5 : 0x8C3D,
+UNSIGNED_INT_5_9_9_9_REV : 0x8C3E,
+TRANSFORM_FEEDBACK_BUFFER_MODE : 0x8C7F,
+MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS : 0x8C80,
+TRANSFORM_FEEDBACK_VARYINGS : 0x8C83,
+TRANSFORM_FEEDBACK_BUFFER_START : 0x8C84,
+TRANSFORM_FEEDBACK_BUFFER_SIZE : 0x8C85,
+TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN : 0x8C88,
+RASTERIZER_DISCARD : 0x8C89,
+MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS : 0x8C8A,
+MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS : 0x8C8B,
+INTERLEAVED_ATTRIBS : 0x8C8C,
+SEPARATE_ATTRIBS : 0x8C8D,
+TRANSFORM_FEEDBACK_BUFFER : 0x8C8E,
+TRANSFORM_FEEDBACK_BUFFER_BINDING : 0x8C8F,
+RGBA32UI : 0x8D70,
+RGB32UI : 0x8D71,
+RGBA16UI : 0x8D76,
+RGB16UI : 0x8D77,
+RGBA8UI : 0x8D7C,
+RGB8UI : 0x8D7D,
+RGBA32I : 0x8D82,
+RGB32I : 0x8D83,
+RGBA16I : 0x8D88,
+RGB16I : 0x8D89,
+RGBA8I : 0x8D8E,
+RGB8I : 0x8D8F,
+RED_INTEGER : 0x8D94,
+RGB_INTEGER : 0x8D98,
+RGBA_INTEGER : 0x8D99,
+SAMPLER_2D_ARRAY : 0x8DC1,
+SAMPLER_2D_ARRAY_SHADOW : 0x8DC4,
+SAMPLER_CUBE_SHADOW : 0x8DC5,
+UNSIGNED_INT_VEC2 : 0x8DC6,
+UNSIGNED_INT_VEC3 : 0x8DC7,
+UNSIGNED_INT_VEC4 : 0x8DC8,
+INT_SAMPLER_2D : 0x8DCA,
+INT_SAMPLER_3D : 0x8DCB,
+INT_SAMPLER_CUBE : 0x8DCC,
+INT_SAMPLER_2D_ARRAY : 0x8DCF,
+UNSIGNED_INT_SAMPLER_2D : 0x8DD2,
+UNSIGNED_INT_SAMPLER_3D : 0x8DD3,
+UNSIGNED_INT_SAMPLER_CUBE : 0x8DD4,
+UNSIGNED_INT_SAMPLER_2D_ARRAY : 0x8DD7,
+DEPTH_COMPONENT32F : 0x8CAC,
+DEPTH32F_STENCIL8 : 0x8CAD,
+FLOAT_32_UNSIGNED_INT_24_8_REV : 0x8DAD,
+FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : 0x8210,
+FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE : 0x8211,
+FRAMEBUFFER_ATTACHMENT_RED_SIZE : 0x8212,
+FRAMEBUFFER_ATTACHMENT_GREEN_SIZE : 0x8213,
+FRAMEBUFFER_ATTACHMENT_BLUE_SIZE : 0x8214,
+FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE : 0x8215,
+FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE : 0x8216,
+FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE : 0x8217,
+FRAMEBUFFER_DEFAULT : 0x8218,
+UNSIGNED_INT_24_8 : 0x84FA,
+DEPTH24_STENCIL8 : 0x88F0,
+UNSIGNED_NORMALIZED : 0x8C17,
+DRAW_FRAMEBUFFER_BINDING : 0x8CA6,
+READ_FRAMEBUFFER : 0x8CA8,
+DRAW_FRAMEBUFFER : 0x8CA9,
+READ_FRAMEBUFFER_BINDING : 0x8CAA,
+RENDERBUFFER_SAMPLES : 0x8CAB,
+FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER : 0x8CD4,
+MAX_COLOR_ATTACHMENTS : 0x8CDF,
+COLOR_ATTACHMENT1 : 0x8CE1,
+COLOR_ATTACHMENT2 : 0x8CE2,
+COLOR_ATTACHMENT3 : 0x8CE3,
+COLOR_ATTACHMENT4 : 0x8CE4,
+COLOR_ATTACHMENT5 : 0x8CE5,
+COLOR_ATTACHMENT6 : 0x8CE6,
+COLOR_ATTACHMENT7 : 0x8CE7,
+COLOR_ATTACHMENT8 : 0x8CE8,
+COLOR_ATTACHMENT9 : 0x8CE9,
+COLOR_ATTACHMENT10 : 0x8CEA,
+COLOR_ATTACHMENT11 : 0x8CEB,
+COLOR_ATTACHMENT12 : 0x8CEC,
+COLOR_ATTACHMENT13 : 0x8CED,
+COLOR_ATTACHMENT14 : 0x8CEE,
+COLOR_ATTACHMENT15 : 0x8CEF,
+FRAMEBUFFER_INCOMPLETE_MULTISAMPLE : 0x8D56,
+MAX_SAMPLES : 0x8D57,
+HALF_FLOAT : 0x140B,
+RG : 0x8227,
+RG_INTEGER : 0x8228,
+R8 : 0x8229,
+RG8 : 0x822B,
+R16F : 0x822D,
+R32F : 0x822E,
+RG16F : 0x822F,
+RG32F : 0x8230,
+R8I : 0x8231,
+R8UI : 0x8232,
+R16I : 0x8233,
+R16UI : 0x8234,
+R32I : 0x8235,
+R32UI : 0x8236,
+RG8I : 0x8237,
+RG8UI : 0x8238,
+RG16I : 0x8239,
+RG16UI : 0x823A,
+RG32I : 0x823B,
+RG32UI : 0x823C,
+VERTEX_ARRAY_BINDING : 0x85B5,
+R8_SNORM : 0x8F94,
+RG8_SNORM : 0x8F95,
+RGB8_SNORM : 0x8F96,
+RGBA8_SNORM : 0x8F97,
+SIGNED_NORMALIZED : 0x8F9C,
+COPY_READ_BUFFER : 0x8F36,
+COPY_WRITE_BUFFER : 0x8F37,
+COPY_READ_BUFFER_BINDING : 0x8F36,
+COPY_WRITE_BUFFER_BINDING : 0x8F37,
+UNIFORM_BUFFER : 0x8A11,
+UNIFORM_BUFFER_BINDING : 0x8A28,
+UNIFORM_BUFFER_START : 0x8A29,
+UNIFORM_BUFFER_SIZE : 0x8A2A,
+MAX_VERTEX_UNIFORM_BLOCKS : 0x8A2B,
+MAX_FRAGMENT_UNIFORM_BLOCKS : 0x8A2D,
+MAX_COMBINED_UNIFORM_BLOCKS : 0x8A2E,
+MAX_UNIFORM_BUFFER_BINDINGS : 0x8A2F,
+MAX_UNIFORM_BLOCK_SIZE : 0x8A30,
+MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS : 0x8A31,
+MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS : 0x8A33,
+UNIFORM_BUFFER_OFFSET_ALIGNMENT : 0x8A34,
+ACTIVE_UNIFORM_BLOCKS : 0x8A36,
+UNIFORM_TYPE : 0x8A37,
+UNIFORM_SIZE : 0x8A38,
+UNIFORM_BLOCK_INDEX : 0x8A3A,
+UNIFORM_OFFSET : 0x8A3B,
+UNIFORM_ARRAY_STRIDE : 0x8A3C,
+UNIFORM_MATRIX_STRIDE : 0x8A3D,
+UNIFORM_IS_ROW_MAJOR : 0x8A3E,
+UNIFORM_BLOCK_BINDING : 0x8A3F,
+UNIFORM_BLOCK_DATA_SIZE : 0x8A40,
+UNIFORM_BLOCK_ACTIVE_UNIFORMS : 0x8A42,
+UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES : 0x8A43,
+UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER : 0x8A44,
+UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER : 0x8A46,
+INVALID_INDEX : 0xFFFFFFFF,
+MAX_VERTEX_OUTPUT_COMPONENTS : 0x9122,
+MAX_FRAGMENT_INPUT_COMPONENTS : 0x9125,
+MAX_SERVER_WAIT_TIMEOUT : 0x9111,
+OBJECT_TYPE : 0x9112,
+SYNC_CONDITION : 0x9113,
+SYNC_STATUS : 0x9114,
+SYNC_FLAGS : 0x9115,
+SYNC_FENCE : 0x9116,
+SYNC_GPU_COMMANDS_COMPLETE : 0x9117,
+UNSIGNALED : 0x9118,
+SIGNALED : 0x9119,
+ALREADY_SIGNALED : 0x911A,
+TIMEOUT_EXPIRED : 0x911B,
+CONDITION_SATISFIED : 0x911C,
+WAIT_FAILED : 0x911D,
+SYNC_FLUSH_COMMANDS_BIT : 0x00000001,
+TIMEOUT_IGNORED : -1,
+VERTEX_ATTRIB_ARRAY_DIVISOR : 0x88FE,
+ANY_SAMPLES_PASSED : 0x8C2F,
+ANY_SAMPLES_PASSED_CONSERVATIVE : 0x8D6A,
+SAMPLER_BINDING : 0x8919,
+RGB10_A2UI : 0x906F,
+INT_2_10_10_10_REV : 0x8D9F,
+TRANSFORM_FEEDBACK : 0x8E22,
+TRANSFORM_FEEDBACK_PAUSED : 0x8E23,
+TRANSFORM_FEEDBACK_ACTIVE : 0x8E24,
+TRANSFORM_FEEDBACK_BINDING : 0x8E25,
+TEXTURE_IMMUTABLE_FORMAT : 0x912F,
+MAX_ELEMENT_INDEX : 0x8D6B,
+TEXTURE_IMMUTABLE_LEVELS : 0x82DF,
+
+/* WebGL-specific enums */
+MAX_CLIENT_WAIT_TIMEOUT_WEBGL: 0x9247
+};
+
+// Other non-function properties on the WebGL object
+var otherProperties = {
+drawingBufferWidth : "number",
+drawingBufferHeight : "number",
+drawingBufferColorSpace : "string",
+unpackColorSpace : "string",
+canvas : "implementation-dependent"
+};
+
+// Properties to be ignored (as a list of strings) because they were
+// added in versions of the spec that are backward-compatible with
+// this version
+var ignoredProperties = [
+];
+
+// Constants removed from the WebGL spec compared to ES 3.0
+var removedConstants = {
+BUFFER_ACCESS_FLAGS : 0x911F,
+BUFFER_MAP_LENGTH : 0x9120,
+BUFFER_MAP_OFFSET : 0x9121,
+NUM_COMPRESSED_TEXTURE_FORMATS : 0x86A2,
+FIXED : 0x140C,
+ACTIVE_UNIFORM_MAX_LENGTH : 0x8B87,
+ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH : 0x8A35,
+ACTIVE_ATTRIBUTE_MAX_LENGTH : 0x8B8A,
+EXTENSIONS : 0x1F03,
+UNIFORM_NAME_LENGTH : 0x8A39,
+UNIFORM_BLOCK_NAME_LENGTH : 0x8A41,
+INFO_LOG_LENGTH : 0x8B84,
+MAP_READ_BIT : 0x0001,
+MAP_WRITE_BIT : 0x0002,
+MAP_INVALIDATE_RANGE_BIT : 0x0004,
+MAP_INVALIDATE_BUFFER_BIT : 0x0008,
+MAP_FLUSH_EXPLICIT_BIT : 0x0010,
+MAP_UNSYNCHRONIZED_BIT : 0x0020,
+SHADER_SOURCE_LENGTH : 0x8B88,
+SHADER_COMPILER : 0x8DFA,
+SHADER_BINARY_FORMATS : 0x8DF8,
+NUM_SHADER_BINARY_FORMATS : 0x8DF9,
+TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH : 0x8C76,
+FRAMEBUFFER_UNDEFINED : 0x8219,
+PROGRAM_BINARY_RETRIEVABLE_HINT : 0x8257,
+PROGRAM_BINARY_LENGTH : 0x8741,
+PROGRAM_BINARY_FORMATS : 0x87FE,
+NUM_PROGRAM_BINARY_FORMATS : 0x87FF,
+TEXTURE_SWIZZLE_A : 0x8E45,
+TEXTURE_SWIZZLE_B : 0x8E44,
+TEXTURE_SWIZZLE_G : 0x8E43,
+TEXTURE_SWIZZLE_R : 0x8E42,
+PRIMITIVE_RESTART_FIXED_INDEX : 0x8D69,
+};
+
+function assertProperty(v, p) {
+ if (p in v) {
+ return true;
+ } else {
+ testFailed("Property does not exist: " + p)
+ return false;
+ }
+}
+
+function assertNoProperty(v, p) {
+ if (p in v) {
+ testFailed("Property is defined and should not be: " + p)
+ return false;
+ } else {
+ return true;
+ }
+}
+
+function assertMsg_(bool, msg) {
+ if (!bool) // show only failures to avoid spamming result list
+ assertMsg(bool, msg);
+ return bool;
+}
+
+debug("");
+debug("Canvas.getContext");
+
+var canvas = document.getElementById("canvas");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(canvas, null, 2);
+var passed = true;
+for (var i in constants) {
+ var r = assertProperty(gl, i) && assertMsg_(gl[i] == constants[i], "Property "+i+" value test "+gl[i]+" == "+constants[i]);
+ passed = passed && r;
+}
+if (passed) {
+ testPassed("All WebGL constants found to have correct values.");
+}
+passed = true;
+for (var i in removedConstants) {
+ var r = assertNoProperty(gl, i);
+ passed = passed && r;
+}
+if (passed) {
+ testPassed("All constants removed from WebGL spec were absent from WebGL context.");
+}
+var extended = false;
+for (var i in gl) {
+ if (constants[i] !== undefined) {
+ // OK; known constant
+ } else if (ignoredProperties.indexOf(i) != -1) {
+ // OK; constant that should be ignored because it was added in a later version of the spec
+ } else if (otherProperties[i] !== undefined &&
+ (otherProperties[i] == "implementation-dependent" || typeof gl[i] == otherProperties[i])) {
+ // OK; known property of known type
+ } else if (typeof gl[i] != "function" && removedConstants[i] === undefined) {
+ if (!extended) {
+ extended = true;
+ testFailed("Also found the following extra properties:");
+ }
+ testFailed(i);
+ }
+}
+
+if (!extended) {
+ testPassed("No extra properties found on WebGL context.");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html
new file mode 100644
index 0000000000..7cd91959f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html
@@ -0,0 +1,89 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+function getWebGL(attribs) {
+ var canvas = document.createElement("canvas");
+ if (!canvas)
+ return null;
+
+ // We can't use wtu.create3DContext because it defaults to antialias=false.
+ var names = ["webgl2"];
+ var gl = null;
+ for (var i = 0; i < names.length; ++i) {
+ try {
+ gl = canvas.getContext(names[i], attribs);
+ } catch (e) {
+ }
+ if (gl) {
+ break;
+ }
+ }
+ if (!gl)
+ return null;
+ return gl;
+}
+
+function testAttribs(attribs) {
+ var antialias, depth, stencil;
+ if (!attribs) {
+ antialias = true;
+ depth = true;
+ stencil = false;
+ debug("Testing default attributes: { antialias: true, depth: true, stencil:false }");
+ } else {
+ antialias = attribs.antialias;
+ depth = attribs.depth;
+ stencil = attribs.stencil;
+ debug("Testing specified attributes: { antialias: " + antialias + ", depth: " + depth + ", stencil: " + stencil + " }");
+ }
+ var gl = getWebGL(attribs);
+ if (!gl) {
+ testFailed("Fail to create a context");
+ return;
+ }
+ var actual_attribs = gl.getContextAttributes();
+ if (antialias != actual_attribs.antialias)
+ testFailed("antialias = " + antialias + " is not obeyed")
+ if (depth != actual_attribs.depth)
+ testFailed("depth = " + depth + " is not obeyed")
+ if (stencil != actual_attribs.stencil)
+ testFailed("stencil = " + stencil + " is not obeyed")
+ if (antialias == actual_attribs.antialias &&
+ depth == actual_attribs.depth &&
+ stencil == actual_attribs.stencil) {
+ testPassed("Context created with the correct antialias, depth, and stencil.");
+ }
+}
+
+description('Verify WebGLContextAttributes are working as specified, including depth, stencil, antialias');
+testAttribs(null); // Default attribs
+testAttribs({antialias: true, depth: true, stencil: true});
+testAttribs({antialias: false, depth: true, stencil: true});
+testAttribs({antialias: true, depth: false, stencil: true});
+testAttribs({antialias: false, depth: false, stencil: true});
+testAttribs({antialias: true, depth: true, stencil: false});
+testAttribs({antialias: false, depth: true, stencil: false});
+testAttribs({antialias: true, depth: false, stencil: false});
+testAttribs({antialias: false, depth: false, stencil: false});
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-mode.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-mode.html
new file mode 100644
index 0000000000..d896604c50
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-mode.html
@@ -0,0 +1,56 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Canvas Context Mode Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test ensures WebGL 2.0 implementations respect the canvas's context mode.");
+
+debug("");
+
+assertMsg(window.WebGLRenderingContext,
+ "WebGL2RenderingContext should be a member of window");
+assertMsg('WebGL2RenderingContext' in window,
+ "WebGL2RenderingContext should be 'in' window");
+
+function testContextMode(mode, altMode) {
+ debug("Testing " + mode + " context type");
+
+ let c = document.createElement('canvas');
+ c.width = 2;
+ c.height = 2;
+ let gl = c.getContext(mode);
+ assertMsg(c.getContext(mode) == gl,
+ "Canvas.getContext('" + mode + "') should return the same value every time");
+ try {
+ assertMsg(c.getContext(altMode) == null,
+ "Canvas.getContext('" + altMode + "') after getContext('" + mode + "') should return null");
+ } catch (e) {
+ testFailed("Canvas.getContext('" + altMode + "') after getContext('" + mode + "') should not throw an exception");
+ }
+}
+
+testContextMode('webgl2', 'webgl');
+testContextMode('webgl', 'webgl2');
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-resize-changes-buffer-binding-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-resize-changes-buffer-binding-bug.html
new file mode 100644
index 0000000000..e6682295a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-resize-changes-buffer-binding-bug.html
@@ -0,0 +1,49 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Context Resize Bug 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="test"></canvas>
+<script>
+"use strict";
+description("This test verifies canvas resize does not affect PIXEL_UNPACK_BUFFER binding.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("test");
+var gl = wtu.create3DContext(canvas, null, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+ var texture1= gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, texture1);
+ var buffer0= gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer0);
+
+ canvas.width = 682;
+ // Resizing canvas incorrectly cleared the PIXEL_UNPACK_BUFFER binding to 0
+ // and caused a crash from the following line in Chrome. crbug.com/673929.
+ gl.texImage3D(gl.TEXTURE_3D, 1, gl.R8, 225,664 , 143, 0,
+ gl.LUMINANCE_ALPHA, gl.UNSIGNED_SHORT_4_4_4_4, 0x41414141);
+ testPassed("no crash from texImage3D");
+}
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html
new file mode 100644
index 0000000000..8ef6dd74b3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html
@@ -0,0 +1,150 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Multiple WebGL2 Context sharing texture2darray/texture3d data bug 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas1" width="64" height="64"> </canvas>
+<canvas id="canvas2" width="64" height="64"> </canvas>
+<div id="console"></div>
+
+<!-- WebGL 2 Shaders -->
+<script id="vs" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+in vec4 a_position;
+in vec2 a_coord;
+out vec2 v_coord;
+void main() {
+ gl_Position = a_position;
+ v_coord = a_coord;
+}
+</script>
+
+<script id="fs_texture_3d" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+in vec2 v_coord;
+uniform mediump sampler3D u_sampler;
+out vec4 o_color;
+void main () {
+ o_color = texture(u_sampler, vec3(v_coord, 0.0));
+}
+</script>
+
+<script id="fs_texture_2d_array" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+in vec2 v_coord;
+uniform mediump sampler2DArray u_sampler;
+out vec4 o_color;
+void main () {
+ o_color = texture(u_sampler, vec3(v_coord, 0.0));
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies that 2 different contexts both using 2d array texture or 3d texture does not share the texture data among them due to context save/restore bug. https://bugs.chromium.org/p/chromium/issues/detail?id=788448");
+debug("");
+
+function render(gl, width, height, expectedColor, msg) {
+ wtu.setupUnitQuad(gl, 0, 1);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, msg);
+}
+
+function StateSetup(gl, texture_type, texture_color, width, height) {
+
+ // create a buffer to hold texture data
+ const depth = 4;
+ var size = width * height * depth * 4;
+ var buf = new Uint8Array(size);
+ for (var i = 0; i < size; i += 4) {
+ buf[i + 0] = texture_color[0];
+ buf[i + 1] = texture_color[1];
+ buf[i + 2] = texture_color[2];
+ buf[i + 3] = texture_color[3];
+ }
+ gl.viewport(0, 0, width, height);
+
+ // choose texture type and fragment shader type
+ var tex_type = gl.TEXTURE_2D;
+ var fragment_shader = "", vertex_shader = "vs";
+ if(texture_type === "3d") {
+ tex_type = gl.TEXTURE_3D, fragment_shader = "fs_texture_3d";
+ } else if(texture_type === "2d_array") {
+ tex_type = gl.TEXTURE_2D_ARRAY, fragment_shader = "fs_texture_2d_array";
+ } else {
+ testFailed("Texture type must be 3d or 2darray");
+ }
+
+ var program = wtu.setupProgram(gl, [vertex_shader, fragment_shader], ['a_position', 'a_coord'], [0, 1]);
+
+ // create a texture
+ var texture = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0);
+
+ // program texture parameters
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(tex_type, texture);
+ gl.texImage3D(tex_type, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ gl.texParameteri(tex_type, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(tex_type, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ // bind sampler to the texture
+ var samplerLoc = gl.getUniformLocation(program, "u_sampler");
+ gl.uniform1i(samplerLoc, 0);
+
+ // flush all gl commands
+ gl.flush();
+}
+
+var wtu = WebGLTestUtils;
+var canvas1 = document.getElementById("canvas1");
+var gl1 = wtu.create3DContext(canvas1, null, 2); //context1
+
+var canvas2 = document.getElementById("canvas2");
+var gl2 = wtu.create3DContext(canvas2, null, 2); // context2
+
+if (gl1 && gl2)
+{
+ testPassed("Created 2 WebGL2 context successfully");
+ var red = [255, 0, 0, 255], green = [0,255,0,255], blue = [0,0,255,255];
+ var width = 64, height = 64;
+ var texture_type = "3d", texture_color = green;
+ StateSetup(gl1,texture_type, texture_color, width, height);// context1 state setup
+ texture_color = red;
+ StateSetup(gl2, texture_type, texture_color, width, height);// context2 state setup
+ render(gl1, width, height, green, "Result pixels rendering from context1 with 3d texture should be green");// render context1
+
+ texture_type = "2d_array", texture_color = blue;
+ StateSetup(gl1, texture_type, texture_color, width, height);// context1 state setup
+ texture_color = green;
+ StateSetup(gl2, texture_type, texture_color, width, height);// context2 state setup
+ render(gl1, width, height, blue, "Result pixels rendering from context1 with 2darray texture should be blue");//render context1
+}
+else if(!gl1)
+{
+ testFailed("Fail to get 1st WebGL2 context");
+}
+else
+{
+ testFailed("Fail to get 2nd WebGL2 context");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-type-test-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-type-test-2.html
new file mode 100644
index 0000000000..42ca0f3742
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/context-type-test-2.html
@@ -0,0 +1,80 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Canvas Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas1" style="width: 50px; height: 50px;"> </canvas>
+<canvas id="canvas2" style="width: 50px; height: 50px;"> </canvas>
+<script>
+"use strict";
+description("This test ensures WebGL2 implementations interact correctly with the canvas tag.");
+
+debug("");
+debug("Canvas.getContext");
+
+function runTest() {
+ assertMsg(window.WebGL2RenderingContext,
+ "WebGL2RenderingContext should be a member of window");
+ assertMsg('WebGL2RenderingContext' in window,
+ "WebGL2RenderingContext should be 'in' window");
+
+ const wtu = WebGLTestUtils;
+ let canvas2 = document.getElementById("canvas2");
+ let gl2 = wtu.create3DContext(canvas2, null, 2);
+ if (!gl2) {
+ testFailed("Could not fetch WebGL 2.0 context");
+ return;
+ }
+ testPassed("Fetched WebGL2 context successfully");
+
+ debug("Checking WebGL2 context type");
+ assertMsg(gl2 instanceof WebGL2RenderingContext,
+ "context type should be WebGL2RenderingContext");
+
+ // WebGL1 contexts do not respond to the WebGL2 context type, and vice versa.
+ let canvas1 = document.getElementById("canvas1");
+ let gl1 = wtu.create3DContext(canvas1, null, 1);
+ if (!gl1) {
+ testFailed("Could not fetch WebGL 1.0 context");
+ return;
+ }
+
+ debug("Checking WebGL1 context type");
+ assertMsg(gl1 instanceof WebGLRenderingContext,
+ "context type should be WebGLRenderingContext");
+
+ let msg1 = "A canvas which has created a WebGL 1.0 context should not return it for a 'webgl2' context request";
+ if (canvas1.getContext("webgl2"))
+ testFailed(msg1);
+ else
+ testPassed(msg1);
+
+ let msg2 = "A canvas which has created a WebGL 2.0 context should not return it for a 'webgl' context request";
+ if (canvas2.getContext("webgl"))
+ testFailed(msg2);
+ else
+ testPassed(msg2);
+}
+
+runTest();
+debug("");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/incorrect-context-object-behaviour.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/incorrect-context-object-behaviour.html
new file mode 100644
index 0000000000..3f0b54fc6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/incorrect-context-object-behaviour.html
@@ -0,0 +1,230 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="tf-vshader" type="x-shader/x-vertex">#version 300 es
+in uint in_data;
+flat out uint out_data;
+void main() {
+ out_data = in_data;
+}
+</script>
+<script id="tf-fshader" type="x-shader/x-fragment">#version 300 es
+void main() {}
+</script>
+
+<script>
+"use strict";
+description("Tests calling WebGL 2.0 APIs with objects from other contexts");
+
+function loadTFProgram(context) {
+ const tfProgram = wtu.setupTransformFeedbackProgram(context, ["tf-vshader", "tf-fshader"],
+ ["out_data"], context.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(context, context.NO_ERROR, "linking transform feedback shader should not set an error");
+ return tfProgram;
+}
+
+function create2DTextureArray4x4x4(context) {
+ const texture = context.createTexture();
+ context.bindTexture(context.TEXTURE_2D_ARRAY, texture);
+ context.texImage3D(context.TEXTURE_2D_ARRAY, 0, context.RGBA8, 4, 4, 4, 0, context.RGBA, context.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(context, context.NO_ERROR, "allocating 2D texture array should not set an error");
+ return texture;
+}
+
+var wtu = WebGLTestUtils;
+var contextA = wtu.create3DContext(undefined, undefined, 2);
+var contextB = wtu.create3DContext(undefined, undefined, 2);
+var bufferA = contextA.createBuffer();
+var bufferB = contextB.createBuffer();
+var frameBufferA = contextA.createFramebuffer();
+var frameBufferB = contextB.createFramebuffer();
+var programB = wtu.loadStandardProgram(contextB);
+var queryB = contextB.createQuery();
+var samplerA = contextA.createSampler();
+var samplerB = contextB.createSampler();
+var syncB = contextB.fenceSync(contextB.SYNC_GPU_COMMANDS_COMPLETE, 0);
+var transformFeedbackA = contextA.createTransformFeedback();
+var transformFeedbackB = contextB.createTransformFeedback();
+var vertexArrayA = contextA.createVertexArray();
+var vertexArrayB = contextB.createVertexArray();
+var tfProgramB = loadTFProgram(contextB);
+var texture2DArrayA = create2DTextureArray4x4x4(contextA);
+var texture2DArrayB = create2DTextureArray4x4x4(contextB);
+var locationB = contextB.getUniformLocation(programB, 'u_modelViewProjMatrix');
+var uniformData = [];
+
+function generateFloat32Array(length) {
+ uniformData = new Float32Array(length);
+}
+
+function generateFloatArray(length) {
+ uniformData = new Array(length);
+ for (var i = 0; i < length; i++) {
+ uniformData[i] = 0.0;
+ }
+}
+
+function generateInt32Array(length) {
+ uniformData = new Int32Array(length);
+}
+
+function generateIntArray(length) {
+ uniformData = new Array(length);
+ for (var i = 0; i < length; i++) {
+ uniformData[i] = 0;
+ }
+}
+
+function generateUint32Array(length) {
+ uniformData = new Uint32Array(length);
+}
+
+// Make the bindable objects valid in both contexts first.
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindBuffer(contextA.ARRAY_BUFFER, bufferA)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindBuffer(contextA.ARRAY_BUFFER, null)");
+wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindBuffer(contextB.ARRAY_BUFFER, bufferB)");
+wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindBuffer(contextB.ARRAY_BUFFER, null)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindTransformFeedback(contextA.TRANSFORM_FEEDBACK, transformFeedbackA)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindTransformFeedback(contextA.TRANSFORM_FEEDBACK, null)");
+wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindTransformFeedback(contextB.TRANSFORM_FEEDBACK, transformFeedbackB)");
+wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindTransformFeedback(contextB.TRANSFORM_FEEDBACK, null)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindVertexArray(vertexArrayA)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindVertexArray(null)");
+wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindVertexArray(vertexArrayB)");
+wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindVertexArray(null)");
+
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferA)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferTextureLayer(contextA.FRAMEBUFFER, contextA.COLOR_ATTACHMENT0, texture2DArrayB, 0, 0)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getFragDataLocation(tfProgramB, 'nonexistent_variable')");
+// Unsigned int uniforms
+ wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1ui(locationB, 0)");
+generateUint32Array(1); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1uiv(locationB, uniformData)");
+generateIntArray(1); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1uiv(locationB, uniformData)");
+ wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2ui(locationB, 0, 0)");
+generateUint32Array(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2uiv(locationB, uniformData)");
+generateIntArray(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2uiv(locationB, uniformData)");
+ wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3ui(locationB, 0, 0, 0)");
+generateUint32Array(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3uiv(locationB, uniformData)");
+generateIntArray(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3uiv(locationB, uniformData)");
+ wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4ui(locationB, 0, 0, 0, 0)");
+generateUint32Array(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4uiv(locationB, uniformData)");
+generateIntArray(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4uiv(locationB, uniformData)");
+// New uniform entry points with offsets
+generateFloat32Array(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1fv(locationB, uniformData, 1)");
+generateFloatArray(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1fv(locationB, uniformData, 1)");
+generateInt32Array(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1iv(locationB, uniformData, 1)");
+generateIntArray(2); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1iv(locationB, uniformData, 1)");
+generateFloat32Array(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2fv(locationB, uniformData, 1)");
+generateFloatArray(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2fv(locationB, uniformData, 1)");
+generateInt32Array(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2iv(locationB, uniformData, 1)");
+generateIntArray(3); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2iv(locationB, uniformData, 1)");
+generateFloat32Array(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3fv(locationB, uniformData, 1)");
+generateFloatArray(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3fv(locationB, uniformData, 1)");
+generateInt32Array(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3iv(locationB, uniformData, 1)");
+generateIntArray(4); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3iv(locationB, uniformData, 1)");
+generateFloat32Array(5); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4fv(locationB, uniformData, 1)");
+generateFloatArray(5); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4fv(locationB, uniformData, 1)");
+generateInt32Array(5); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4iv(locationB, uniformData, 1)");
+generateIntArray(5); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4iv(locationB, uniformData, 1)");
+generateFloat32Array(5); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2fv(locationB, false, uniformData, 1)");
+generateFloatArray(5); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2fv(locationB, false, uniformData, 1)");
+generateFloat32Array(10); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3fv(locationB, false, uniformData, 1)");
+generateFloatArray(10); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3fv(locationB, false, uniformData, 1)");
+generateFloat32Array(17); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4fv(locationB, false, uniformData, 1)");
+generateFloatArray(17); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4fv(locationB, false, uniformData, 1)");
+// Non-rectangular matrix uniform entry points
+generateFloat32Array(6);
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3x2fv(locationB, false, uniformData)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2x3fv(locationB, false, uniformData)");
+generateFloatArray(6);
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3x2fv(locationB, false, uniformData)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2x3fv(locationB, false, uniformData)");
+generateFloat32Array(8);
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4x2fv(locationB, false, uniformData)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2x4fv(locationB, false, uniformData)");
+generateFloatArray(8);
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4x2fv(locationB, false, uniformData)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2x4fv(locationB, false, uniformData)");
+generateFloat32Array(12);
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4x3fv(locationB, false, uniformData)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3x4fv(locationB, false, uniformData)");
+generateFloatArray(12);
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4x3fv(locationB, false, uniformData)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3x4fv(locationB, false, uniformData)");
+
+// Query objects
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteQuery(queryB)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isQuery(queryB)");
+shouldBeFalse("contextA.isQuery(queryB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.beginQuery(contextA.ANY_SAMPLES_PASSED, queryB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getQueryParameter(queryB, contextA.QUERY_RESULT_AVAILABLE)");
+
+// Sampler objects
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteSampler(samplerB)");
+wtu.shouldGenerateGLError(contextB, contextB.INVALID_OPERATION, "contextB.deleteSampler(samplerA)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindSampler(0, samplerB)");
+wtu.shouldGenerateGLError(contextB, contextB.INVALID_OPERATION, "contextB.bindSampler(0, samplerA)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isSampler(samplerB)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextB.isSampler(samplerA)");
+shouldBeFalse("contextA.isSampler(samplerB)");
+shouldBeFalse("contextB.isSampler(samplerA)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.samplerParameteri(samplerB, contextA.TEXTURE_WRAP_S, contextA.CLAMP_TO_EDGE)");
+wtu.shouldGenerateGLError(contextB, contextB.INVALID_OPERATION, "contextB.samplerParameteri(samplerA, contextB.TEXTURE_WRAP_S, contextB.CLAMP_TO_EDGE)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.samplerParameterf(samplerB, contextA.TEXTURE_MIN_LOD, -500.5)");
+wtu.shouldGenerateGLError(contextB, contextB.INVALID_OPERATION, "contextB.samplerParameterf(samplerA, contextB.TEXTURE_MIN_LOD, -500.5)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getSamplerParameter(samplerB, contextA.TEXTURE_WRAP_S)");
+wtu.shouldGenerateGLError(contextB, contextB.INVALID_OPERATION, "contextB.getSamplerParameter(samplerA, contextB.TEXTURE_WRAP_S)");
+
+// Sync objects
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteSync(syncB)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isSync(syncB)");
+shouldBeFalse("contextA.isSync(syncB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.clientWaitSync(syncB, 0, 0)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.waitSync(syncB, 0, contextA.TIMEOUT_IGNORED)");
+
+// Transform feedback
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteTransformFeedback(transformFeedbackB)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isTransformFeedback(transformFeedbackB)");
+shouldBeFalse("contextA.isTransformFeedback(transformFeedbackB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindTransformFeedback(contextA.TRANSFORM_FEEDBACK, transformFeedbackB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.transformFeedbackVaryings(tfProgramB, ['out_data'], contextA.SEPARATE_ATTRIBS)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getTransformFeedbackVarying(tfProgramB, 0)");
+
+// Uniform buffer objects and transform feedback buffers
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindBufferBase(contextA.UNIFORM_BUFFER, 0, bufferB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindBufferRange(contextA.UNIFORM_BUFFER, 0, bufferB, 0, 4)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniformIndices(programB, ['u_modelViewProjMatrix'])");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveUniforms(programB, [0], contextA.UNIFORM_TYPE)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniformBlockIndex(programB, 'nonexistent_uniform_block_name')");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveUniformBlockParameter(programB, 0, contextA.UNIFORM_BLOCK_BINDING)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveUniformBlockName(programB, 0)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformBlockBinding(programB, 0, 0)");
+
+// Vertex Array objects
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteVertexArray(vertexArrayB)");
+wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isVertexArray(vertexArrayB)");
+shouldBeFalse("contextA.isVertexArray(vertexArrayB)");
+wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindVertexArray(vertexArrayB)");
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/methods-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/methods-2.html
new file mode 100644
index 0000000000..a389329aa3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/methods-2.html
@@ -0,0 +1,268 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Methods 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="../../js/tests/context-methods.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<script>
+"use strict";
+description("This test ensures that the WebGL context has all the methods in the specification.");
+
+const methods = [
+ "getContextAttributes",
+ "activeTexture",
+ "attachShader",
+ "bindAttribLocation",
+ "bindBuffer",
+ "bindFramebuffer",
+ "bindRenderbuffer",
+ "bindTexture",
+ "blendColor",
+ "blendEquation",
+ "blendEquationSeparate",
+ "blendFunc",
+ "blendFuncSeparate",
+ "bufferData",
+ "bufferSubData",
+ "checkFramebufferStatus",
+ "clear",
+ "clearColor",
+ "clearDepth",
+ "clearStencil",
+ "colorMask",
+ "compileShader",
+ "compressedTexImage2D",
+ "compressedTexSubImage2D",
+ "copyTexImage2D",
+ "copyTexSubImage2D",
+ "createBuffer",
+ "createFramebuffer",
+ "createProgram",
+ "createRenderbuffer",
+ "createShader",
+ "createTexture",
+ "cullFace",
+ "deleteBuffer",
+ "deleteFramebuffer",
+ "deleteProgram",
+ "deleteRenderbuffer",
+ "deleteShader",
+ "deleteTexture",
+ "depthFunc",
+ "depthMask",
+ "depthRange",
+ "detachShader",
+ "disable",
+ "disableVertexAttribArray",
+ "drawArrays",
+ "drawElements",
+ "enable",
+ "enableVertexAttribArray",
+ "finish",
+ "flush",
+ "framebufferRenderbuffer",
+ "framebufferTexture2D",
+ "frontFace",
+ "generateMipmap",
+ "getActiveAttrib",
+ "getActiveUniform",
+ "getAttachedShaders",
+ "getAttribLocation",
+ "getParameter",
+ "getBufferParameter",
+ "getError",
+ "getExtension",
+ "getFramebufferAttachmentParameter",
+ "getProgramParameter",
+ "getProgramInfoLog",
+ "getRenderbufferParameter",
+ "getShaderParameter",
+ "getShaderInfoLog",
+ "getShaderPrecisionFormat",
+ "getShaderSource",
+ "getSupportedExtensions",
+ "getTexParameter",
+ "getUniform",
+ "getUniformLocation",
+ "getVertexAttrib",
+ "getVertexAttribOffset",
+ "hint",
+ "isBuffer",
+ "isContextLost",
+ "isEnabled",
+ "isFramebuffer",
+ "isProgram",
+ "isRenderbuffer",
+ "isShader",
+ "isTexture",
+ "lineWidth",
+ "linkProgram",
+ "pixelStorei",
+ "polygonOffset",
+ "readPixels",
+ "renderbufferStorage",
+ "sampleCoverage",
+ "scissor",
+ "shaderSource",
+ "stencilFunc",
+ "stencilFuncSeparate",
+ "stencilMask",
+ "stencilMaskSeparate",
+ "stencilOp",
+ "stencilOpSeparate",
+ "texImage2D",
+ "texParameterf",
+ "texParameteri",
+ "texSubImage2D",
+ "uniform1f",
+ "uniform1fv",
+ "uniform1i",
+ "uniform1iv",
+ "uniform2f",
+ "uniform2fv",
+ "uniform2i",
+ "uniform2iv",
+ "uniform3f",
+ "uniform3fv",
+ "uniform3i",
+ "uniform3iv",
+ "uniform4f",
+ "uniform4fv",
+ "uniform4i",
+ "uniform4iv",
+ "uniformMatrix2fv",
+ "uniformMatrix3fv",
+ "uniformMatrix4fv",
+ "useProgram",
+ "validateProgram",
+ "vertexAttrib1f",
+ "vertexAttrib1fv",
+ "vertexAttrib2f",
+ "vertexAttrib2fv",
+ "vertexAttrib3f",
+ "vertexAttrib3fv",
+ "vertexAttrib4f",
+ "vertexAttrib4fv",
+ "vertexAttribPointer",
+ "viewport",
+
+ // WebGL2 methods
+ "getBufferSubData",
+ "copyBufferSubData",
+ "blitFramebuffer",
+ "framebufferTextureLayer",
+ "getInternalformatParameter",
+ "invalidateFramebuffer",
+ "invalidateSubFramebuffer",
+ "readBuffer",
+ "renderbufferStorageMultisample",
+ "texImage3D",
+ "texStorage2D",
+ "texStorage3D",
+ "texSubImage3D",
+ "copyTexSubImage3D",
+ "compressedTexImage3D",
+ "compressedTexSubImage3D",
+ "getFragDataLocation",
+ "uniform1ui",
+ "uniform2ui",
+ "uniform3ui",
+ "uniform4ui",
+ "uniform1uiv",
+ "uniform2uiv",
+ "uniform3uiv",
+ "uniform4uiv",
+ "uniformMatrix2x3fv",
+ "uniformMatrix3x2fv",
+ "uniformMatrix2x4fv",
+ "uniformMatrix4x2fv",
+ "uniformMatrix3x4fv",
+ "uniformMatrix4x3fv",
+ "vertexAttribI4i",
+ "vertexAttribI4iv",
+ "vertexAttribI4ui",
+ "vertexAttribI4uiv",
+ "vertexAttribIPointer",
+ "vertexAttribDivisor",
+ "drawArraysInstanced",
+ "drawElementsInstanced",
+ "drawRangeElements",
+ "drawBuffers",
+ "clearBufferiv",
+ "clearBufferuiv",
+ "clearBufferfv",
+ "clearBufferfi",
+ "createQuery",
+ "deleteQuery",
+ "isQuery",
+ "beginQuery",
+ "endQuery",
+ "getQuery",
+ "getQueryParameter",
+ "createSampler",
+ "deleteSampler",
+ "isSampler",
+ "bindSampler",
+ "samplerParameteri",
+ "samplerParameterf",
+ "getSamplerParameter",
+ "fenceSync",
+ "isSync",
+ "deleteSync",
+ "clientWaitSync",
+ "waitSync",
+ "getSyncParameter",
+ "createTransformFeedback",
+ "deleteTransformFeedback",
+ "isTransformFeedback",
+ "bindTransformFeedback",
+ "beginTransformFeedback",
+ "endTransformFeedback",
+ "transformFeedbackVaryings",
+ "getTransformFeedbackVarying",
+ "pauseTransformFeedback",
+ "resumeTransformFeedback",
+ "bindBufferBase",
+ "bindBufferRange",
+ "getIndexedParameter",
+ "getUniformIndices",
+ "getActiveUniforms",
+ "getUniformBlockIndex",
+ "getActiveUniformBlockParameter",
+ "getActiveUniformBlockName",
+ "uniformBlockBinding",
+ "createVertexArray",
+ "deleteVertexArray",
+ "isVertexArray",
+ "bindVertexArray",
+];
+
+debug("");
+debug("Canvas.getContext");
+
+const wtu = WebGLTestUtils;
+const canvas = document.getElementById("canvas");
+const gl = wtu.create3DContext(canvas, null, 2);
+
+testContextMethods(gl, methods);
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/context/no-experimental-webgl2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/context/no-experimental-webgl2.html
new file mode 100644
index 0000000000..65aa9cb16d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/context/no-experimental-webgl2.html
@@ -0,0 +1,35 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Canvas Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<canvas id="canvas2d" width="40" height="40"> </canvas>
+<script>
+"use strict";
+description("This test ensures WebGL2 implementations do not respond to experimental-webgl2.");
+
+debug("");
+
+var canvas = document.getElementById("canvas");
+shouldBeNull('canvas.getContext("experimental-webgl2")');
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt
new file mode 100644
index 0000000000..559071ff06
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt
@@ -0,0 +1,19 @@
+ext-color-buffer-float.html
+--min-version 2.0.1 ext-color-buffer-half-float.html
+ext-disjoint-timer-query-webgl2.html
+--min-version 2.0.1 ext-texture-filter-anisotropic.html
+--min-version 2.0.1 ext-texture-norm16.html
+promoted-extensions.html
+promoted-extensions-in-shaders.html
+--min-version 2.0.1 oes-draw-buffers-indexed.html
+--min-version 2.0.1 ovr_multiview2.html
+--min-version 2.0.1 ovr_multiview2_depth.html
+--min-version 2.0.1 ovr_multiview2_draw_buffers.html
+--min-version 2.0.1 ovr_multiview2_flat_varying.html
+--min-version 2.0.1 ovr_multiview2_instanced_draw.html
+--min-version 2.0.1 ovr_multiview2_non_multiview_shaders.html
+--min-version 2.0.1 ovr_multiview2_single_view_operations.html
+--min-version 2.0.1 ovr_multiview2_timer_query.html
+--min-version 2.0.1 ovr_multiview2_transform_feedback.html
+--min-version 2.0.1 required-extensions.html
+--min-version 2.0.1 webgl-multi-draw-instanced-base-vertex-base-instance.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html
new file mode 100644
index 0000000000..b57a6ca10d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html
@@ -0,0 +1,508 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_color_buffer_float Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing floating-point textures -->
+<script id="testFragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D tex;
+uniform vec4 subtractor;
+varying vec2 texCoord;
+void main()
+{
+ vec4 color = texture2D(tex, texCoord);
+ if (abs(color.r - subtractor.r) +
+ abs(color.g - subtractor.g) +
+ abs(color.b - subtractor.b) +
+ abs(color.a - subtractor.a) < 16.0) {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ } else {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+}
+</script>
+<!-- Shaders for testing floating-point render targets -->
+<script id="floatingPointFragmentShader" type="x-shader/x-fragment">
+void main()
+{
+ gl_FragColor = vec4(1000.0, 1000.0, 1000.0, 1000.0);
+}
+</script>
+<script>
+"use strict";
+
+function allocateTexture()
+{
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ 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);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed");
+ return texture;
+}
+
+function checkRenderingResults()
+{
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+function arrayToString(arr, size) {
+ var mySize;
+ if (!size)
+ mySize = arr.length;
+ else
+ mySize = size;
+ var out = "[";
+ for (var ii = 0; ii < mySize; ++ii) {
+ if (ii > 0) {
+ out += ", ";
+ }
+ out += arr[ii];
+ }
+ return out + "]";
+}
+
+function runReadbackTest(testProgram, subtractor)
+{
+ // Verify floating point readback
+ debug("Checking readback of floating-point values");
+ var buf = new Float32Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT , buf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels from floating-point framebuffer should succeed");
+ var ok = true;
+ var tolerance = 8.0; // TODO: factor this out from both this test and the subtractor shader above.
+ for (var ii = 0; ii < buf.length; ++ii) {
+ if (Math.abs(buf[ii] - subtractor[ii]) > tolerance) {
+ ok = false;
+ break;
+ }
+ }
+ if (ok) {
+ testPassed("readPixels of float-type data from floating-point framebuffer succeeded");
+ } else {
+ testFailed("readPixels of float-type data from floating-point framebuffer failed: expected "
+ + arrayToString(subtractor, 4) + ", got " + arrayToString(buf));
+ }
+}
+
+function runFloatTextureRenderTargetTest(enabled, internalFormat, format, testProgram, numberOfChannels, subtractor, texSubImageCover)
+{
+ var formatString = wtu.glEnumToString(gl, internalFormat);
+ debug("");
+ debug("testing floating-point " + formatString + " texture render target" + (texSubImageCover > 0 ? " after calling texSubImage" : ""));
+
+ var texture = allocateTexture();
+ var width = 2;
+ var height = 2;
+ gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, width, height, 0, format, gl.FLOAT, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed");
+
+ // Try to use this texture as a render target.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ var completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (!enabled) {
+ if (completeStatus == gl.FRAMEBUFFER_COMPLETE && !enabled)
+ testFailed("floating-point " + formatString + " render target should not be supported without enabling EXT_color_buffer_float");
+ else
+ testPassed("floating-point " + formatString + " render target should not be supported without enabling EXT_color_buffer_float");
+ return;
+ }
+
+ if (completeStatus != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("floating-point " + formatString + " render target not supported");
+ return;
+ }
+
+ if (texSubImageCover > 0) {
+ // Ensure that replacing the whole texture or a part of it with texSubImage2D doesn't affect renderability
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ var data = new Float32Array(width * height * numberOfChannels * texSubImageCover);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height * texSubImageCover, format, gl.FLOAT, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed if EXT_color_buffer_float is enabled");
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("render target support changed after calling texSubImage2D");
+ return;
+ }
+ }
+
+ var renderProgram =
+ wtu.setupProgram(gl,
+ [wtu.simpleVertexShader, "floatingPointFragmentShader"],
+ ['vPosition'],
+ [0]);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering to floating-point texture should succeed");
+
+ // Now sample from the floating-point texture and verify we got the correct values.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.useProgram(testProgram);
+ gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0);
+ gl.uniform4fv(gl.getUniformLocation(testProgram, "subtractor"), subtractor);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering from floating-point texture should succeed");
+ checkRenderingResults();
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ runReadbackTest(testProgram, subtractor);
+}
+
+function runFloatRenderbufferRenderTargetTest(enabled, internalFormat, testProgram, numberOfChannels, subtractor)
+{
+ var formatString = wtu.glEnumToString(gl, internalFormat);
+ var samples = [0];
+ if (enabled) {
+ samples = Array.prototype.slice.call(gl.getInternalformatParameter(gl.RENDERBUFFER, internalFormat, gl.SAMPLES));
+ samples.push(0);
+ }
+ for (var ndx = 0; ndx < samples.length; ++ndx) {
+ debug("");
+ debug("testing floating-point " + formatString + " renderbuffer render target with number of samples " + samples[ndx]);
+
+ var colorbuffer = gl.createRenderbuffer();
+ var width = 2;
+ var height = 2;
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer);
+ if (samples[ndx] == 0)
+ gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, width, height);
+ else
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[ndx], internalFormat, width, height);
+ if (!enabled) {
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "floating-point renderbuffer allocation should fail if EXT_color_buffer_float is not enabled");
+ return;
+ } else {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "floating-point renderbuffer allocation should succeed if EXT_color_buffer_float is enabled");
+ }
+
+ // Try to use this renderbuffer as a render target.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorbuffer);
+
+ var completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (completeStatus != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("floating-point " + formatString + " render target not supported");
+ return;
+ }
+ var resolveColorRbo = null;
+ var resolveFbo = null;
+ if (samples[ndx] > 0) {
+ resolveColorRbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, resolveColorRbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, width, height);
+ resolveFbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, resolveColorRbo);
+ completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (completeStatus != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Failed to create resolve framebuffer");
+ return;
+ }
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.clearColor(1000.0, 1000.0, 1000.0, 1000.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ if (samples[ndx] > 0) {
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFbo);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, resolveFbo);
+ }
+ runReadbackTest(testProgram, subtractor);
+ }
+}
+
+function runRGB16FNegativeTest()
+{
+ debug("");
+ debug("testing RGB16F isn't color renderable");
+
+ var texture = allocateTexture();
+ var width = 2;
+ var height = 2;
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, width, height, 0, gl.RGB, gl.FLOAT, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "RGB16F texture allocation should succeed");
+
+ // Try to use this texture as a render target.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ var completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (completeStatus == gl.FRAMEBUFFER_COMPLETE)
+ testFailed("RGB16F render target should not be supported with or without enabling EXT_color_buffer_float");
+ else
+ testPassed("RGB16F render target should not be supported with or without enabling EXT_color_buffer_float");
+ gl.deleteTexture(texture);
+
+ var colorbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB16F, width, height);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "RGB16F renderbuffer allocation should fail with or without enabling EXT_color_buffer_float");
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(colorbuffer);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+}
+
+function runUniqueObjectTest()
+{
+ debug("");
+ debug("Testing that getExtension() returns the same object each time");
+ gl.getExtension("EXT_color_buffer_float").myProperty = 2;
+ webglHarnessCollectGarbage();
+ shouldBe('gl.getExtension("EXT_color_buffer_float").myProperty', '2');
+}
+
+function runInternalFormatQueryTest()
+{
+ debug("");
+ debug("testing the internal format query");
+
+ var maxSamples = gl.getParameter(gl.MAX_SAMPLES);
+ const formats = [gl.RGBA16F, gl.R32F, gl.RG32F, gl.RGBA32F, gl.R16F, gl.RG16F, gl.R11F_G11F_B10F];
+ var firstMultiOnlyFormat = 4;
+ for (var fmt = 0; fmt < formats.length; ++fmt) {
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, formats[fmt], gl.SAMPLES);
+ if (fmt >= firstMultiOnlyFormat && (samples.length == 0 || samples[0] < maxSamples)) {
+ testFailed("the maximum value in SAMPLES should be at least " + maxSamples);
+ return;
+ }
+
+ var prevSampleCount = 0;
+ var sampleCount;
+ for (var ndx = 0; ndx < samples.length; ++ndx, prevSampleCount = sampleCount) {
+ sampleCount = samples[ndx];
+ // sample count must be > 0
+ if (sampleCount <= 0) {
+ testFailed("Expected sample count to be at least one; got " + sampleCount);
+ return;
+ }
+
+ // samples must be ordered descending
+ if (ndx > 0 && sampleCount >= prevSampleCount) {
+ testFailed("Expected sample count to be ordered in descending order; got " + prevSampleCount + " at index " + (ndx - 1) + ", and " + sampleCount + " at index " + ndx);
+ return;
+ }
+ }
+ }
+ testPassed("Internal format query succeeded");
+}
+
+function runCopyTexImageTest(enabled)
+{
+ var width = 16;
+ var height = 16;
+ var level = 0;
+ var cases = [
+ {
+ internalformat: "RGBA16F",
+ format: "RGBA",
+ type: "HALF_FLOAT",
+ destInternalformat: "R16F",
+ data: new Uint16Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA32F",
+ format: "RGBA",
+ type: "FLOAT",
+ destInternalformat: "R32F",
+ data: new Float32Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA16F",
+ format: "RGBA",
+ type: "HALF_FLOAT",
+ destInternalformat: "RG16F",
+ data: new Uint16Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA32F",
+ format: "RGBA",
+ type: "FLOAT",
+ destInternalformat: "RG32F",
+ data: new Float32Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA16F",
+ format: "RGBA",
+ type: "HALF_FLOAT",
+ destInternalformat: "RGB16F",
+ data: new Uint16Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA32F",
+ format: "RGBA",
+ type: "FLOAT",
+ destInternalformat: "RGB32F",
+ data: new Float32Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA16F",
+ format: "RGBA",
+ type: "HALF_FLOAT",
+ destInternalformat: "RGBA16F",
+ data: new Uint16Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA32F",
+ format: "RGBA",
+ type: "FLOAT",
+ destInternalformat: "RGBA32F",
+ data: new Float32Array(width * height * 4)
+ },
+ {
+ internalformat: "R11F_G11F_B10F",
+ format: "RGB",
+ type: "FLOAT",
+ destInternalformat: "R11F_G11F_B10F",
+ data: new Float32Array(width * height * 3)
+ }
+ ];
+ cases.forEach(function(testcase) {
+ debug("");
+ debug("Testing CopyTexImage2D for internalformat: " + testcase.destInternalformat);
+
+ var internalformat = gl[testcase.internalformat];
+ var format = gl[testcase.format];
+ var type = gl[testcase.type];
+ var destInternalformat = gl[testcase.destInternalformat];
+ var texSrc = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texSrc);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ var data = testcase.data;
+ gl.texImage2D(gl.TEXTURE_2D, level, internalformat, width, height, 0, format, type, data);
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texSrc, level);
+ var texDest = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texDest);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with texture should succeed.");
+ if (enabled) {
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ gl.copyTexImage2D(gl.TEXTURE_2D, level, destInternalformat, 0, 0, width, height, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "CopyTexImage2D should succeed.");
+ } else {
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+ gl.copyTexImage2D(gl.TEXTURE_2D, level, destInternalformat, 0, 0, width, height, 0);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_FRAMEBUFFER_OPERATION], "CopyTexImage2D should fail.");
+ }
+
+ gl.deleteTexture(texDest);
+ gl.deleteTexture(texSrc);
+ gl.deleteFramebuffer(fbo);
+ });
+}
+
+description("This test verifies the functionality of the EXT_color_buffer_float extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ var texturedShaders = [
+ wtu.simpleTextureVertexShader,
+ "testFragmentShader"
+ ];
+ var testProgram =
+ wtu.setupProgram(gl,
+ texturedShaders,
+ ['vPosition', 'texCoord0'],
+ [0, 1]);
+ var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+
+ // Ensure these formats can't be used for rendering if the extension is disabled
+ runFloatTextureRenderTargetTest(false, gl.R16F, gl.RED);
+ runFloatTextureRenderTargetTest(false, gl.RG16F, gl.RG);
+ runFloatTextureRenderTargetTest(false, gl.RGBA16F, gl.RGBA);
+ runFloatTextureRenderTargetTest(false, gl.R32F, gl.RED);
+ runFloatTextureRenderTargetTest(false, gl.RG32F, gl.RG);
+ runFloatTextureRenderTargetTest(false, gl.RGBA32F, gl.RGBA);
+ runFloatTextureRenderTargetTest(false, gl.R11F_G11F_B10F, gl.RGB);
+
+ runFloatRenderbufferRenderTargetTest(false, gl.R16F);
+ runFloatRenderbufferRenderTargetTest(false, gl.RG16F);
+ runFloatRenderbufferRenderTargetTest(false, gl.RGBA16F);
+ runFloatRenderbufferRenderTargetTest(false, gl.R32F);
+ runFloatRenderbufferRenderTargetTest(false, gl.RG32F);
+ runFloatRenderbufferRenderTargetTest(false, gl.RGBA32F);
+ runFloatRenderbufferRenderTargetTest(false, gl.R11F_G11F_B10F);
+
+ // Ensure RGB16F can't be used for rendering.
+ runRGB16FNegativeTest();
+
+ runCopyTexImageTest(false);
+
+ if (!gl.getExtension("EXT_color_buffer_float")) {
+ testPassed("No EXT_color_buffer_float support -- this is legal");
+ } else {
+ testPassed("Successfully enabled EXT_color_buffer_float extension");
+
+ runInternalFormatQueryTest();
+
+ runFloatTextureRenderTargetTest(true, gl.R16F, gl.RED, testProgram, 1, [1000, 1, 1, 1], 0);
+ runFloatTextureRenderTargetTest(true, gl.RG16F, gl.RG, testProgram, 2, [1000, 1000, 1, 1], 0);
+ runFloatTextureRenderTargetTest(true, gl.RGBA16F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 0);
+ runFloatTextureRenderTargetTest(true, gl.R32F, gl.RED, testProgram, 1, [1000, 1, 1, 1], 0);
+ runFloatTextureRenderTargetTest(true, gl.RG32F, gl.RG, testProgram, 2, [1000, 1000, 1, 1], 0);
+ runFloatTextureRenderTargetTest(true, gl.RGBA32F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 0);
+ runFloatTextureRenderTargetTest(true, gl.R11F_G11F_B10F, gl.RGB, testProgram, 3, [1000, 1000, 1000, 1], 0);
+ runFloatTextureRenderTargetTest(true, gl.RGBA32F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 1);
+ runFloatTextureRenderTargetTest(true, gl.RGBA32F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 0.5);
+
+ runFloatRenderbufferRenderTargetTest(true, gl.R16F, testProgram, 1, [1000, 1, 1, 1]);
+ runFloatRenderbufferRenderTargetTest(true, gl.RG16F, testProgram, 2, [1000, 1000, 1, 1]);
+ runFloatRenderbufferRenderTargetTest(true, gl.RGBA16F, testProgram, 4, [1000, 1000, 1000, 1000]);
+ runFloatRenderbufferRenderTargetTest(true, gl.R32F, testProgram, 1, [1000, 1, 1, 1]);
+ runFloatRenderbufferRenderTargetTest(true, gl.RG32F, testProgram, 2, [1000, 1000, 1, 1]);
+ runFloatRenderbufferRenderTargetTest(true, gl.RGBA32F, testProgram, 4, [1000, 1000, 1000, 1000]);
+ runFloatRenderbufferRenderTargetTest(true, gl.R11F_G11F_B10F, testProgram, 3, [1000, 1000, 1000, 1]);
+
+ // Ensure EXT_color_buffer_float does not enable RGB16F as color renderable.
+ runRGB16FNegativeTest();
+
+ runCopyTexImageTest(true);
+
+ runUniqueObjectTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-half-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-half-float.html
new file mode 100644
index 0000000000..4ced76e0fd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-half-float.html
@@ -0,0 +1,27 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 EXT_color_buffer_half_float Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head> 
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+var version = 2;
+</script>
+<script src="../../js/tests/ext-color-buffer-half-float.js"></script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html
new file mode 100644
index 0000000000..c051fa36a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html
@@ -0,0 +1,316 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 EXT_disjoint_timer_query_webgl2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_disjoint_timer_query_webgl2 extension, if it is available.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var ext = null;
+var query = null;
+var query2 = null;
+var elapsed_query = null;
+var timestamp_query1 = null;
+var timestamp_query2 = null;
+var availability_retry = 500;
+var timestamp_counter_bits = 0;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+ finishTest();
+} else {
+ testPassed("WebGL context exists");
+
+ // Query the extension and store globally so shouldBe can access it
+ ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_disjoint_timer_query_webgl2");
+ if (!ext) {
+ testPassed("No EXT_disjoint_timer_query_webgl2 support -- this is legal");
+ finishTest();
+ } else {
+ runSanityTests();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ // Clear disjoint value.
+ gl.getParameter(ext.GPU_DISJOINT_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ runElapsedTimeTest();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ timestamp_counter_bits = gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT);
+ if (timestamp_counter_bits > 0) {
+ runTimeStampTest();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+ verifyQueryResultsNotAvailable();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ window.requestAnimationFrame(checkQueryResults);
+ }
+}
+
+function runSanityTests() {
+ debug("");
+ debug("Testing other query types");
+ query = gl.createQuery();
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
+ shouldBeTrue("gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY) !== null");
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "enabling EXT_disjoint_timer_query_webgl2 should not break other queries");
+
+ debug("");
+ debug("Testing timer query expectations");
+
+ shouldBe("ext.QUERY_COUNTER_BITS_EXT", "0x8864");
+ shouldBe("ext.TIME_ELAPSED_EXT", "0x88BF");
+ shouldBe("ext.TIMESTAMP_EXT", "0x8E28");
+ shouldBe("ext.GPU_DISJOINT_EXT", "0x8FBB");
+
+ shouldBe("gl.isQuery(null)", "false");
+
+ shouldBeTrue("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY) === null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeTrue("gl.getQuery(ext.TIME_ELAPSED_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ shouldBeTrue("gl.getQuery(ext.TIMESTAMP_EXT, gl.CURRENT_QUERY) === null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ // Certain drivers set timestamp counter bits to 0 as they don't support timestamps
+ shouldBeTrue("gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30 || " +
+ "gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) === 0");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Testing time elapsed query lifecycle");
+ query = gl.createQuery();
+ shouldBe("gl.isQuery(query)", "false");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query creation must succeed.");
+ gl.beginQuery(ext.TIMESTAMP_EXT, query);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Beginning a timestamp query should fail.");
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
+ shouldBe("gl.isQuery(query)", "true");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Beginning an inactive time elapsed query should succeed.");
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to begin an active query should fail.");
+ gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability of an active query should fail.");
+ gl.getQueryParameter(query, gl.QUERY_RESULT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result of an active query should fail.");
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
+ gl.endQuery(ext.TIME_ELAPSED_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Ending an active time elapsed query should succeed.");
+ gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Fetching query result availability after query end should succeed.");
+ gl.endQuery(ext.TIME_ELAPSED_EXT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to end an inactive query should fail.");
+ ext.queryCounterEXT(query, ext.TIMESTAMP_EXT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should not be able to use time elapsed query to store a timestamp.");
+ gl.deleteQuery(query);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query deletion must succeed.");
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning a deleted query must fail.");
+ gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability after query deletion should fail.");
+ shouldBe("gl.isQuery(query)", "false");
+
+ debug("");
+ debug("Testing timestamp counter");
+ query = gl.createQuery();
+ shouldThrow("ext.queryCounterEXT(null, ext.TIMESTAMP_EXT)");
+ ext.queryCounterEXT(query, ext.TIMESTAMP_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp counter queries should work.");
+ gl.deleteQuery(query);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Performing parameter sanity checks");
+ gl.getParameter(ext.TIMESTAMP_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter timestamp calls should work.");
+ gl.getParameter(ext.GPU_DISJOINT_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter disjoint calls should work.");
+
+ debug("");
+ debug("Testing current query conditions");
+ query = gl.createQuery();
+ query2 = gl.createQuery();
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null");
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Testing failed begin query should not change the current query.");
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning an elapsed query without ending should fail.");
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Testing beginning a timestamp query is invalid and should not change the elapsed query.");
+ gl.beginQuery(ext.TIMESTAMP_EXT, query2)
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Testing timestamp queries end immediately so are never current.");
+ ext.queryCounterEXT(query2, ext.TIMESTAMP_EXT);
+ shouldBe("gl.getQuery(ext.TIMESTAMP_EXT, gl.CURRENT_QUERY)", "null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Testing ending the query should clear the current query.");
+ gl.endQuery(ext.TIME_ELAPSED_EXT);
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Testing beginning a elapsed query using a timestamp query should fail and not affect current query.")
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Switching query targets should fail.");
+ shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.deleteQuery(query);
+ gl.deleteQuery(query2);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at end of sanity tests");
+}
+
+function runElapsedTimeTest() {
+ debug("");
+ debug("Testing elapsed time query");
+
+ elapsed_query = gl.createQuery();
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, elapsed_query);
+ gl.clearColor(0, 0, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.endQuery(ext.TIME_ELAPSED_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Time elapsed query should have no errors");
+}
+
+function runTimeStampTest() {
+ debug("");
+ debug("Testing timestamp query");
+
+ timestamp_query1 = gl.createQuery();
+ timestamp_query2 = gl.createQuery();
+ ext.queryCounterEXT(timestamp_query1, ext.TIMESTAMP_EXT);
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ ext.queryCounterEXT(timestamp_query2, ext.TIMESTAMP_EXT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp queries should have no errors");
+}
+
+function verifyQueryResultsNotAvailable() {
+ debug("");
+ debug("Verifying queries' results don't become available too early");
+
+ // Verify as best as possible that the implementation doesn't
+ // allow a query's result to become available the same frame, by
+ // spin-looping for some time and ensuring that none of the
+ // queries' results become available.
+ var startTime = Date.now();
+ while (Date.now() - startTime < 2000) {
+ gl.finish();
+ if (gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE)) {
+ testFailed("One of the queries' results became available too early");
+ return;
+ }
+ if (timestamp_counter_bits > 0) {
+ if (gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_AVAILABLE) ||
+ gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE)) {
+ testFailed("One of the queries' results became available too early");
+ return;
+ }
+ }
+ }
+
+ testPassed("Queries' results didn't become available in a spin loop");
+}
+
+function checkQueryResults() {
+ if (availability_retry > 0) {
+ // Make a reasonable attempt to wait for the queries' results to become available.
+ if (!gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE) ||
+ (timestamp_counter_bits > 0 && !gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE))) {
+ var error = gl.getError();
+ if (error != gl.NO_ERROR) {
+ testFailed("getQueryParameter should have no errors: " + wtu.glEnumToString(gl, error));
+ debug("");
+ finishTest();
+ return;
+ }
+ availability_retry--;
+ window.requestAnimationFrame(checkQueryResults);
+ return;
+ }
+ }
+
+ debug("");
+ debug("Testing query results");
+
+ // Make sure queries are available.
+ shouldBe("gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE)", "true");
+ if (timestamp_counter_bits > 0) {
+ shouldBe("gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_AVAILABLE)", "true");
+ shouldBe("gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE)", "true");
+ }
+
+ var disjoint_value = gl.getParameter(ext.GPU_DISJOINT_EXT);
+ if (disjoint_value) {
+ // Cannot validate results make sense, but this is okay.
+ testPassed("Disjoint triggered.");
+ } else {
+ var elapsed_result = gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT);
+ if (timestamp_counter_bits > 0) {
+ var timestamp_result1 = gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT);
+ var timestamp_result2 = gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT);
+ }
+ // Do some basic validity checking of the elapsed time query. There's no way it should
+ // take more than about half a second for a no-op query.
+ var halfSecondInNanos = 0.5 * 1000 * 1000 * 1000;
+ if (elapsed_result < 0 || elapsed_result > halfSecondInNanos) {
+ testFailed("Time elapsed query returned invalid data: " + elapsed_result);
+ } else {
+ testPassed("Time elapsed query results were valid.");
+ }
+
+ if (timestamp_counter_bits > 0) {
+ if (timestamp_result1 <= 0 ||
+ timestamp_result2 <= 0 ||
+ timestamp_result2 <= timestamp_result1) {
+ testFailed("Timestamp queries returned invalid data: timestamp_result1 = " +
+ timestamp_result1 + ", timestamp_result2 = " + timestamp_result2);
+ } else {
+ testPassed("Timestamp query results were valid.");
+ }
+ }
+ }
+
+ debug("");
+ finishTest();
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-filter-anisotropic.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-filter-anisotropic.html
new file mode 100644
index 0000000000..c75a8e0cae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-filter-anisotropic.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2.0 EXT_texture_filter_anisotropic Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/ext-texture-filter-anisotropic.js"></script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-norm16.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-norm16.html
new file mode 100644
index 0000000000..add9fc038d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-norm16.html
@@ -0,0 +1,253 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_texture_norm16 Conformance Tests</title>
+<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the EXT_texture_norm16 extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(null, null, 2);
+var ext;
+
+var formats = null;
+var textures;
+var fbos;
+var renderbuffer;
+var readbackBuf = new Uint16Array(4);
+
+function generateFormatColor(format, value, alpha) {
+ alpha = alpha !== undefined ? alpha : 255;
+ switch(format) {
+ case gl.RED:
+ return [value, 0, 0, alpha];
+ case gl.RG:
+ return [value, value, 0, alpha];
+ case gl.RGB:
+ return [value, value, value, alpha];
+ case gl.RGBA:
+ return [value, value, value, value];
+ default:
+ wtu.error("Unreachable: Unknown format.");
+ return null;
+ }
+}
+
+function testNorm16Texture(internalFormat, format, type, error="NO_ERROR") {
+ debug(`\ntestNorm16Texture(${[].slice.call(arguments).join(", ")})`);
+ let pixelValue;
+ let expectedValue;
+ let imageData;
+
+ switch(gl[type]) {
+ case gl.SHORT:
+ pixelValue = 0x7fff;
+ expectedValue = 0xff;
+ imageData = new Int16Array(4).fill(pixelValue);
+ break;
+ case gl.UNSIGNED_SHORT:
+ pixelValue = 0x6a35;
+ expectedValue = pixelValue >> 8;
+ imageData = new Uint16Array(4).fill(pixelValue);
+ break;
+ default:
+ wtu.error("Unreachable: Unknown texture type.");
+ break;
+ }
+
+ // Texture sampled from
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, textures[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, ext[internalFormat] || gl[internalFormat],
+ 1, 1, 0, gl[format], gl[type], imageData);
+
+ wtu.glErrorShouldBe(gl, gl[error], `texImage should generate error:${error}`);
+ if (gl[error]) return;
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ // Read back as gl.UNSIGNED_BYTE
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(gl[format], expectedValue));
+}
+
+function testNorm16Render(interalFormat, format, type, tolerance) {
+ // Only UNSIGNED_SHORT are renderable
+ let pixelValue = 0x6a35;
+ let expectedValue = pixelValue;
+ let imageData = new Uint16Array(4).fill(pixelValue);
+
+ // Render to fbo texture attachment test
+ gl.bindTexture(gl.TEXTURE_2D, textures[1]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, interalFormat, 1, 1, 0, format, type, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rtt bindings succeed");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textures[1], 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fbo bindings succeed");
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, textures[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, interalFormat, 1, 1, 0, format, type, imageData);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture bindings succeed");
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(format, expectedValue, 0xffff), undefined, tolerance, readbackBuf, type);
+
+ // Renderbuffer test
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[1]);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, interalFormat, 1, 1);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER,
+ renderbuffer);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "renderbuffer bindings succeed");
+
+ gl.clearColor(1, 1, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(format, 0xffff, 0xffff), undefined, tolerance, readbackBuf, type);
+
+ // Copy from renderbuffer to textures[1] test
+ gl.bindTexture(gl.TEXTURE_2D, textures[1]);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copy succeed");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(format, 0xffff, 0xffff), undefined, tolerance, readbackBuf, type);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+}
+
+function testExtFormatUnrenderable(internalFormatName, format, type) {
+ gl.bindTexture(gl.TEXTURE_2D, textures[1]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, ext[internalFormatName], 1, 1, 0, format, type, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture definition succeeded");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textures[1], 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fbo binding succeeded");
+
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [ gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT, gl.FRAMEBUFFER_UNSUPPORTED ],
+ `framebuffer should not be complete with ${internalFormatName} texture attached`);
+}
+
+function runInternalFormatQueryTest()
+{
+ debug("");
+ debug("testing the internal format query");
+
+ var maxSamples = gl.getParameter(gl.MAX_SAMPLES);
+ const formats = [ext.R16_EXT, ext.RG16_EXT, ext.RGBA16_EXT];
+ for (const format of formats) {
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);
+ if (samples == null || samples.length == 0 || samples[0] < maxSamples) {
+ testFailed("the maximum value in SAMPLES should be at least " + maxSamples);
+ return;
+ }
+ }
+ testPassed("Internal format query succeeded");
+}
+
+function runTestExtension() {
+ textures = [gl.createTexture(), gl.createTexture()];
+ fbos = [gl.createFramebuffer(), gl.createFramebuffer()];
+ renderbuffer = gl.createRenderbuffer();
+
+ for (let i = 0; i < 2; i++) {
+ gl.bindTexture(gl.TEXTURE_2D, textures[i]);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ }
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture and framebuffer setup succeed");
+
+ let program300 = wtu.setupSimpleTextureProgramESSL300(gl);
+ let program100 = wtu.setupTexturedQuad(gl, 0, 1, wtu.simpleHighPrecisionTextureFragmentShader);
+
+ debug("");
+ debug("Texture creation");
+ testNorm16Texture("R16_EXT", "RED", "UNSIGNED_SHORT");
+ testNorm16Texture("RG16_EXT", "RG", "UNSIGNED_SHORT");
+ testNorm16Texture("RGB16_EXT", "RGB", "UNSIGNED_SHORT");
+ testNorm16Texture("RGBA16_EXT", "RGBA", "UNSIGNED_SHORT");
+ testNorm16Texture("R16_SNORM_EXT", "RED", "SHORT");
+ testNorm16Texture("RG16_SNORM_EXT", "RG", "SHORT");
+ testNorm16Texture("RGB16_SNORM_EXT", "RGB", "SHORT");
+ testNorm16Texture("RGBA16_SNORM_EXT", "RGBA", "SHORT");
+
+ testNorm16Texture("RGBA", "RGBA", "UNSIGNED_SHORT", "INVALID_OPERATION");
+ testNorm16Texture("RGBA", "RGBA", "SHORT", "INVALID_OPERATION");
+
+ debug("");
+ debug("Texture renderability");
+
+ testNorm16Render(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT, 8);
+ testNorm16Render(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT, 8);
+ testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 8);
+
+ gl.useProgram(program300);
+
+ testNorm16Render(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT, 0);
+ testNorm16Render(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT, 0);
+ testExtFormatUnrenderable("RGB16_EXT", gl.RGB, gl.UNSIGNED_SHORT);
+ testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 0);
+
+ testExtFormatUnrenderable("R16_SNORM_EXT", gl.RED, gl.SHORT);
+ testExtFormatUnrenderable("RG16_SNORM_EXT", gl.RG, gl.SHORT);
+ testExtFormatUnrenderable("RGB16_SNORM_EXT", gl.RGB, gl.SHORT);
+ testExtFormatUnrenderable("RGBA16_SNORM_EXT", gl.RGBA, gl.SHORT);
+};
+
+function runTest() {
+ if (!gl) {
+ testFailed("context does not exist");
+ } else {
+ testPassed("context exists");
+
+ ext = gl.getExtension("EXT_texture_norm16");
+
+ wtu.runExtensionSupportedTest(gl, "EXT_texture_norm16", ext !== null);
+
+ if (ext !== null) {
+ runInternalFormatQueryTest();
+ runTestExtension();
+ } else {
+ testPassed("No EXT_texture_norm16 support -- this is legal");
+ }
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html
new file mode 100644
index 0000000000..700bb053c1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html
@@ -0,0 +1,573 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OES_draw_buffers_indexed Conformance Tests</title>
+<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas width="20" height="20" style="border: 1px solid blue;" id="c"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the OES_draw_buffers_indexed extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c", null, 2);
+var ext;
+
+const vs = `#version 300 es
+layout(location=0) in vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+`;
+
+const fs = `#version 300 es
+precision lowp float;
+layout(location = 0) out vec4 o_color0;
+layout(location = 1) out vec4 o_color1;
+void main()
+{
+ o_color0 = vec4(1, 0, 0, 0);
+ o_color1 = vec4(1, 0, 0, 0);
+}
+`;
+
+function setup() {
+ const program = wtu.setupProgram(gl, [vs, fs]);
+ gl.useProgram(program);
+ wtu.setupUnitQuad(gl, 0);
+ wtu.glErrorShouldBe(gl, 0, 'No errors from program');
+
+ const tex1 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, 0, 'Create texture 1 successfully');
+
+ const tex2 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, 0, 'Create texture 2 successfully');
+
+ const attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1];
+
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, tex1, 0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, tex2, 0);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.drawBuffers(attachments);
+ wtu.glErrorShouldBe(gl, 0, 'Set draw buffers without errors');
+}
+
+function enableDisableTest() {
+ debug("Testing enableiOES/disableiOES");
+
+ // Invalid input
+ ext.enableiOES(gl.DEPTH_TEST, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND');
+
+ ext.disableiOES(gl.DEPTH_TEST, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND');
+
+ gl.disable(gl.BLEND);
+
+ // Valid input
+ ext.enableiOES(gl.BLEND, 0);
+ shouldBe('gl.isEnabled(gl.BLEND)', 'true');
+ ext.disableiOES(gl.BLEND, 0);
+ ext.enableiOES(gl.BLEND, 1);
+ shouldBe('gl.isEnabled(gl.BLEND)', 'false');
+ gl.enable(gl.BLEND);
+ shouldBe('gl.isEnabled(gl.BLEND)', 'true');
+ wtu.glErrorShouldBe(gl, 0, 'No errors from enable and disable draw buffers blend state');
+}
+
+function constantAlphaBlendColorValidationTest() {
+ debug("Testing CONSTANT_COLOR/ALPHA blend functions limit validation");
+ function isConstantColorAndAlphaBlendFunctions(first, second)
+ {
+ return (first == gl.CONSTANT_COLOR || first == gl.ONE_MINUS_CONSTANT_COLOR) &&
+ (second == gl.CONSTANT_ALPHA || second == gl.ONE_MINUS_CONSTANT_ALPHA);
+ }
+
+ function checkBlendFunctions(src, dst)
+ {
+ if (isConstantColorAndAlphaBlendFunctions(src, dst) ||
+ isConstantColorAndAlphaBlendFunctions(dst, src))
+ {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'invalid combinations');
+ return false;
+ }
+ else
+ {
+ wtu.glErrorShouldBe(gl, 0, 'No error');
+ return true;
+ }
+ }
+
+ const srcFunc = [
+ 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,
+ ];
+
+ const dstFunc = [
+ 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,
+ ];
+
+ let src, dst;
+
+ // CONSTANT_COLOR/ALPHA invalid combination check
+ for (let i = 0, leni = srcFunc.length; i < leni; i++)
+ {
+ src = srcFunc[i];
+ for (let j = 0, lenj = dstFunc.length; j < lenj; j++)
+ {
+ dst = dstFunc[j];
+ ext.blendFunciOES(0, src, dst);
+ checkBlendFunctions(src, dst);
+ ext.blendFuncSeparateiOES(0, src, dst, gl.ONE, gl.ONE);
+ checkBlendFunctions(src, dst);
+ }
+ }
+}
+
+function indexedBlendColorTest() {
+ debug('');
+ debug("Testing blendEquationiOES and blendFunciOES");
+ wtu.glErrorShouldBe(gl, 0, 'top of indexedBlendColorTest');
+
+ gl.clearColor(0, 0, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ ext.blendEquationiOES(0, gl.FUNC_ADD);
+ ext.blendFunciOES(0, gl.ONE, gl.ONE);
+ ext.blendEquationiOES(1, gl.FUNC_ADD);
+ ext.blendFunciOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 255]);
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]);
+
+ debug("Testing blendEquationSeparateiOES and blendFuncSeparateiOES");
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ ext.blendEquationSeparateiOES(0, gl.FUNC_ADD, gl.FUNC_SUBTRACT);
+ ext.blendFuncSeparateiOES(0, gl.ONE, gl.ONE, gl.ZERO, gl.ZERO);
+ ext.blendEquationSeparateiOES(1, gl.FUNC_ADD, gl.FUNC_SUBTRACT);
+ ext.blendFuncSeparateiOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ZERO);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 0]);
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]);
+
+ debug("Testing colorMaskiOES");
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ ext.colorMaskiOES(0, false, false, false, false);
+ ext.colorMaskiOES(1, true, true, true, true);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]);
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]);
+
+ debug('');
+ debug(`Testing that new tokens aren't on the extension.`);
+ shouldBe('ext.BLEND_EQUATION_RGB', 'undefined');
+ shouldBe('ext.BLEND_EQUATION_ALPHA', 'undefined');
+ shouldBe('ext.BLEND_SRC_RGB', 'undefined');
+ shouldBe('ext.BLEND_SRC_ALPHA', 'undefined');
+ shouldBe('ext.BLEND_DST_RGB', 'undefined');
+ shouldBe('ext.BLEND_DST_ALPHA', 'undefined');
+ shouldBe('ext.COLOR_WRITEMASK', 'undefined');
+
+ debug("Testing new tokens for getIndexedParameterTest");
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_ADD');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_SUBTRACT');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.ONE');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ZERO');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ZERO');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_ADD');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_SUBTRACT');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.SRC_ALPHA');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.ONE_MINUS_SRC_ALPHA');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ZERO');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ZERO');
+
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[false, false, false, false]');
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, true, true, true]');
+
+ debug("Testing non-indexed getParamter get state from draw buffer 0");
+ shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE');
+ shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.ONE');
+ shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ZERO');
+ shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ZERO');
+ shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_ADD');
+ shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_SUBTRACT');
+ shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[false, false, false, false]');
+
+ debug("Testing non-indexed calls modify all draw buffers state");
+ gl.blendEquationSeparate(gl.FUNC_SUBTRACT, gl.FUNC_ADD);
+ gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE);
+ gl.colorMask(true, false, true, false);
+ wtu.glErrorShouldBe(gl, 0, 'Non-indexed state set without errors');
+
+ shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_SUBTRACT');
+ shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_ADD');
+ shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE_MINUS_DST_ALPHA');
+ shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.DST_ALPHA');
+ shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ONE');
+ shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ONE');
+ shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[true, false, true, false]');
+
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_SUBTRACT');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_ADD');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE_MINUS_DST_ALPHA');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.DST_ALPHA');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ONE');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ONE');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_SUBTRACT');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_ADD');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.ONE_MINUS_DST_ALPHA');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.DST_ALPHA');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ONE');
+ shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ONE');
+
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, true, false]');
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, false, true, false]');
+}
+
+function runTestExtension() {
+ setup();
+
+ testInvalidValues();
+
+ enableDisableTest();
+
+ // blending should be enabled for drawBuffers 0 and 1 at this point
+
+ constantAlphaBlendColorValidationTest();
+
+ indexedBlendColorTest();
+
+ testColorMaskDrawNoOp();
+
+ testColorMaskAfterComposite();
+}
+
+function runInvalidEnumsTest() {
+ debug("Testing new enums for getIndexedParameterTest being invalid before requesting the extension");
+ shouldBeNull("gl.getIndexedParameter(0x8009, 0)"); // BLEND_EQUATION_RGB
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_RGB');
+ shouldBeNull("gl.getIndexedParameter(0x883D, 0)"); // BLEND_EQUATION_ALPHA
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_ALPHA');
+ shouldBeNull("gl.getIndexedParameter(0x80C9, 0)"); // BLEND_SRC_RGB
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_RGB');
+ shouldBeNull("gl.getIndexedParameter(0x80CB, 0)"); // BLEND_SRC_ALPHA
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_ALPHA');
+ shouldBeNull("gl.getIndexedParameter(0x80C8, 0)"); // BLEND_DST_RGB
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_RGB');
+ shouldBeNull("gl.getIndexedParameter(0x80CA, 0)"); // BLEND_DST_ALPHA
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_ALPHA');
+ shouldBeNull("gl.getIndexedParameter(0x0C23, 0)"); // COLOR_WRITEMASK
+ wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], 'invalid operations or invalid enums for COLOR_WRITEMASK');
+}
+
+function testInvalidValues() {
+ const numDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS);
+ if (!numDrawBuffers) throw new Error('!numDrawBuffers');
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, -1)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, ${numDrawBuffers})`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.enableiOES(gl.BLEND, ${numDrawBuffers-1})`);
+
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, -1)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, ${numDrawBuffers})`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.disableiOES(gl.BLEND, ${numDrawBuffers-1})`);
+
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(-1, gl.FUNC_ADD)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(${numDrawBuffers}, gl.FUNC_ADD)`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationiOES(${numDrawBuffers-1}, gl.FUNC_ADD)`);
+
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(-1, gl.FUNC_ADD, gl.FUNC_ADD)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(${numDrawBuffers}, gl.FUNC_ADD, gl.FUNC_ADD)`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationSeparateiOES(${numDrawBuffers-1}, gl.FUNC_ADD, gl.FUNC_ADD)`);
+
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(-1, gl.ONE, gl.ONE)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(${numDrawBuffers}, gl.ONE, gl.ONE)`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.blendFunciOES(${numDrawBuffers-1}, gl.ONE, gl.ONE)`);
+
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(-1, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(${numDrawBuffers}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.blendFuncSeparateiOES(${numDrawBuffers-1}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
+
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(-1, 1,1,1,1)`);
+ wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(${numDrawBuffers}, 1,1,1,1)`);
+ wtu.shouldGenerateGLError(gl, 0, `ext.colorMaskiOES(${numDrawBuffers-1}, 1,1,1,1)`);
+}
+
+function* range(n) {
+ for (let i = 0; i < n; i++) {
+ yield i;
+ }
+}
+
+function testColorMaskDrawNoOp() {
+ debug('');
+ debug('testColorMaskDrawNoOp')
+ // > If any draw buffer with an attachment does not have a defined
+ // fragment shader output, draws generate INVALID_OPERATION,
+ // unless all 4 channels of colorMask are set to false.
+ const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+ shouldBeTrue(`${NUM_OUTPUTS} > 1`);
+
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.viewport(0,0,1,1);
+
+ const DRAW_BUFFERS = [];
+ for (const i of range(NUM_OUTPUTS)) {
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 1, 1);
+ const ca = gl.COLOR_ATTACHMENT0+i;
+ DRAW_BUFFERS.push(ca)
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, ca,
+ gl.TEXTURE_2D, tex, 0);
+ }
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.drawBuffers(DRAW_BUFFERS);
+ gl.colorMask(1, 1, 1, 1);
+ gl.disable(gl.BLEND);
+
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ for (const i of range(NUM_OUTPUTS)) {
+ gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 0], `COLOR_ATTACHMENT${i} initially black`);
+ }
+
+ for (const validOutput of range(NUM_OUTPUTS)) {
+ const invalidOutput = validOutput ^ 0b11;
+ debug(`validOutput: ${validOutput}, invalidOutput: ${invalidOutput}`);
+ const prog = wtu.setupProgram(gl, [
+ `\
+#version 300 es
+void main() {
+ gl_Position = vec4(0,0,0,1);
+ gl_PointSize = 1.0f;
+}
+`,
+ `\
+#version 300 es
+precision mediump float;
+layout(location=${validOutput}) out vec4 o_color;
+void main() {
+ o_color = vec4(1,1,1,1);
+}
+`
+ ]);
+ gl.useProgram(prog);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ 'After init.');
+
+ gl.colorMask(1,1,1,1);
+ gl.drawBuffers(DRAW_BUFFERS);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ 'Drawing with unmasked undefined color outputs.');
+
+ gl.colorMask(0,0,0,0);
+ gl.drawBuffers(DRAW_BUFFERS);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ 'Drawing with colorMask-masked-out undefined color outputs.');
+
+ gl.colorMask(1,1,1,1);
+ gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == invalidOutput) ? x : 0));
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ 'Drawing with wrong-id drawBuffer-masked-out undefined color outputs.');
+
+ gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0));
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ 'Drawing with drawBuffer-masked-out undefined color outputs.');
+
+ gl.colorMask(0,0,0,0);
+ gl.drawBuffers([]);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ 'Drawing with colorMask+drawBuffer-masked-out undefined color outputs.');
+
+ const testMask = (r,g,b,a) => {
+ debug(`testMask(${[r,g,b,a]})`);
+ gl.drawBuffers(DRAW_BUFFERS);
+
+ gl.colorMask(1,1,1,1);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.colorMask(0,0,0,0);
+ ext.colorMaskiOES(validOutput, r,g,b,a);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ `Drawing with sole defined color${validOutput} output writemask: ${[r,g,b,a]}.`);
+
+ for (const i of range(NUM_OUTPUTS)) {
+ gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
+ let expect = [0,0,0,0];
+ if (i == validOutput) {
+ expect = [r,g,b,a].map(x => 0xff*x);
+ }
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`);
+ }
+
+ gl.colorMask(1,1,1,1);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.colorMask(r,g,b,a);
+ for (const i of range(NUM_OUTPUTS)) {
+ if (i == validOutput) continue;
+ ext.colorMaskiOES(i, 0,0,0,0);
+ }
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ `Drawing with sole remaining defined color${validOutput} output writemask: ${[r,g,b,a]}.`);
+
+ for (const i of range(NUM_OUTPUTS)) {
+ gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
+ let expect = [0,0,0,0];
+ if (i == validOutput) {
+ expect = [r,g,b,a].map(x => 0xff*x);
+ }
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`);
+ }
+
+ if (r || g || b || a) {
+ gl.colorMask(0,0,0,0);
+ ext.colorMaskiOES(invalidOutput, r,g,b,a);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ `Drawing with wrong-id undefined color output color masked: ${[r,g,b,a]}.`);
+
+ gl.drawBuffers([]);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ 'Drawing with wrong-id colorMask, but all-off drawBuffers.');
+
+ gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0));
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ 'Drawing with wrong-id colorMask, but right-id drawBuffers masked.');
+ }
+ };
+
+ testMask(0,0,0,0);
+ testMask(1,0,0,0);
+ testMask(0,1,0,0);
+ testMask(0,0,1,0);
+ testMask(0,0,0,1);
+ testMask(1,1,1,1);
+ }
+}
+
+function testColorMaskAfterComposite() {
+ debug('');
+ debug('testColorMaskAfterComposite')
+
+ const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+ shouldBeTrue(`${NUM_OUTPUTS} > 2`);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.colorMask(0, 0, 1, 0);
+ ext.colorMaskiOES(0, 1, 0, 0, 0);
+ ext.colorMaskiOES(1, 0, 1, 0, 0);
+
+ function check() {
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, false, false]');
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[false, true, false, false]');
+ shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 2)', '[false, false, true, false]');
+ finishTest();
+ }
+
+ wtu.waitForComposite(check);
+}
+
+function runTest() {
+ if (!gl) {
+ testFailed("context does not exist");
+ } else {
+ testPassed("context exists");
+
+ runInvalidEnumsTest();
+
+ ext = gl.getExtension("OES_draw_buffers_indexed");
+
+ wtu.runExtensionSupportedTest(gl, "OES_draw_buffers_indexed", ext !== null);
+
+ if (ext !== null) {
+ runTestExtension();
+ } else {
+ testPassed("No OES_draw_buffers_indexed support -- this is legal");
+ }
+ }
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2.html
new file mode 100644
index 0000000000..ba74d1398b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2.html
@@ -0,0 +1,524 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+<script id="requireDefine_GL_OVR_multiview2" type="x-shader/x-fragment">#version 300 es
+#ifndef GL_OVR_multiview2
+ #error no GL_OVR_multiview2
+#endif
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="forbidDefine_GL_OVR_multiview" type="x-shader/x-fragment">#version 300 es
+#ifdef GL_OVR_multiview
+ #error legacy GL_OVR_multiview support must be forbidden
+#endif
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="legacyMultiview1Shader" type="x-shader/x-fragment">#version 300 es
+#extension GL_OVR_multiview: require
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runExtensionDisabledTest()
+{
+ debug("");
+ debug("Testing queries with extension disabled");
+
+ let maxViews = gl.getParameter(0x9631);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query MAX_VIEWS_OVR without enabling OVR_multiview2");
+
+ let baseViewIndex = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, 0x9630);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR without enabling OVR_multiview2");
+ let numViews = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, 0x9632);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR without enabling OVR_multiview2");
+}
+
+function runQueryTest()
+{
+ debug("");
+ debug("Testing querying MAX_VIEWS_OVR");
+
+ let maxViews = gl.getParameter(ext.MAX_VIEWS_OVR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from querying MAX_VIEWS_OVR");
+ if (typeof maxViews != 'number') {
+ testFailed("Type of the value of MAX_VIEWS_OVR should be number, was " + (typeof maxViews));
+ }
+ if (maxViews < 2) {
+ testFailed("Value of MAX_VIEWS_OVR should be at least two, was: " + maxViews);
+ }
+}
+
+function runDefaultFramebufferQueryTest()
+{
+ debug("");
+ debug("Testing querying base view index and num views on the default framebuffer");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ // Same behavior as FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR is INVALID_ENUM for default framebuffer");
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR is INVALID_ENUM for default framebuffer");
+}
+
+function runInvalidTextureTypeTest()
+{
+ debug("");
+ debug("Testing invalid texture types");
+ let tex2D = createTextureWithNearestFiltering(gl.TEXTURE_2D);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 128, 128);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be possible to create a multiview framebuffer against a 2D texture");
+
+ let texCube = createTextureWithNearestFiltering(gl.TEXTURE_CUBE_MAP);
+ gl.texStorage2D(gl.TEXTURE_CUBE_MAP, 1, gl.RGBA8, 128, 128);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texCube, 0, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be possible to create a multiview framebuffer against a cube map texture");
+
+ let tex3D = createTextureWithNearestFiltering(gl.TEXTURE_3D);
+ gl.texStorage3D(gl.TEXTURE_3D, 1, gl.RGBA8, 128, 128, 2);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, 0, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be possible to create a multiview framebuffer against a 3D texture");
+}
+
+/**
+ * If allocateStorage is true, the test will allocate texture storage. If it is false, attachments are done without allocations.
+ */
+function runFramebufferQueryTest(allocateStorage)
+{
+ debug("");
+ debug("Testing querying attachment object type, baseViewIndex, numViews and framebuffer status. Texture storage is " + (allocateStorage ? "allocated" : "not allocated") + ".");
+
+ let checkQueryResult = function(actual, expected, name) {
+ if (actual != expected) {
+ testFailed('Unexpected ' + name + ': ' + actual + ' when it was set to ' + expected);
+ } else {
+ testPassed(name + ' was ' + actual + ' when queried from the framebuffer');
+ }
+ }
+
+ let setupAndQuery = function(colorTex, levelSet, baseViewIndexSet, numViewsSet) {
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, levelSet, baseViewIndexSet, numViewsSet);
+ let objectType = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ if (objectType != gl.TEXTURE) {
+ testFailed('Unexpected FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE ' + wtu.glEnumToString(gl, objectType) + ', should be TEXTURE');
+ } else {
+ testPassed('FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was TEXTURE');
+ }
+
+ let level = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL);
+ checkQueryResult(level, levelSet, "level");
+
+ let textureName = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
+ checkQueryResult(textureName, colorTex, "texture object");
+
+ let baseViewIndex = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR);
+ checkQueryResult(baseViewIndex, baseViewIndexSet, "baseViewIndex");
+
+ let numViews = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR);
+ checkQueryResult(numViews, numViewsSet, "numViews");
+
+ let layer = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
+ checkQueryResult(layer, baseViewIndexSet, "texture layer (should match baseViewIndex)");
+ }
+
+ let setupSecondAttachmentAndQueryStatus = function(colorTex2, baseViewIndex, numViews, expectedStatus, msg) {
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, colorTex2, 0, baseViewIndex, numViews);
+ let status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (status != expectedStatus) {
+ testFailed('Framebuffer status: ' + wtu.glEnumToString(gl, status) + ' did not match with the expected value: ' + wtu.glEnumToString(gl, expectedStatus) + ' - ' + msg);
+ } else {
+ testPassed('Framebuffer status: ' + wtu.glEnumToString(gl, status) + ' matched with the expected value - ' + msg);
+ }
+ }
+
+ let maxViews = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let baseViewIndex = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Querying baseViewIndex from a nonexistent attachment");
+ if (baseViewIndex != null) {
+ testFailed('Unexpected baseViewIndex ' + baseViewIndex + ' on a framebuffer without attachments');
+ } else {
+ testPassed('Querying baseViewIndex returned null on a framebuffer without attachments');
+ }
+ let numViews = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Querying numViews from a nonexistent attachment");
+ if (numViews != null) {
+ testFailed('Unexpected numViews ' + numViews + ' on a framebuffer without attachments');
+ } else {
+ testPassed('Querying numViews returned null on a framebuffer without attachments');
+ }
+
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ if (allocateStorage) {
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 2, gl.RGBA8, 128, 128, maxViews);
+ }
+ setupAndQuery(colorTex, 0, 0, maxViews);
+ setupAndQuery(colorTex, 1, 0, 2);
+ setupAndQuery(colorTex, 0, 1, maxViews - 1);
+
+ // Test matching and mismatching attachments for framebuffer status.
+ let colorTex2 = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ if (allocateStorage) {
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, 128, 128, maxViews);
+ }
+ setupSecondAttachmentAndQueryStatus(colorTex2, 1, maxViews - 1, allocateStorage ? gl.FRAMEBUFFER_COMPLETE : gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT, 'matching baseViewIndex and numViews on different attachments');
+ if (allocateStorage) {
+ setupSecondAttachmentAndQueryStatus(colorTex2, 0, maxViews - 1, ext.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, 'baseViewIndex mismatch');
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
+ setupSecondAttachmentAndQueryStatus(colorTex2, 0, maxViews - 1, ext.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, 'numViews mismatch');
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from framebuffer queries");
+}
+
+function runInvalidViewsTest()
+{
+ debug("");
+ debug("Testing invalid out-of-range values for baseViewIndex and numViews");
+
+ let maxViews = gl.getParameter(ext.MAX_VIEWS_OVR);
+ let maxLayers = gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ // Don't allocate storage since it's not needed for the validation.
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified too many views");
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified zero views");
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, -1, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified negative baseViewIndex");
+
+ let colorTex2 = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex2, 0, maxLayers - maxViews + 1, maxViews);
+ // baseViewIndex + numViews = (maxLayers - maxViews + 1) + maxViews = maxLayers + 1
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified so many views that baseViewIndex + numViews is greater than MAX_ARRAY_TEXTURE_LAYERS");
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex2, 0, maxLayers - maxViews, maxViews);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "baseViewIndex + numViews is exactly MAX_ARRAY_TEXTURE_LAYERS");
+}
+
+function runDetachTest()
+{
+ debug("");
+ debug("Testing detaching multiview attachments");
+
+ let maxViews = gl.getParameter(ext.MAX_VIEWS_OVR);
+ let maxLayers = gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, null, 0, maxLayers + 1, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "baseViewIndex and numViews are not validated when detaching");
+ let objectType = gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ if (objectType != gl.NONE) {
+ testFailed('Unexpected FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE ' + wtu.glEnumToString(gl, objectType) + ' after detach, should be NONE');
+ } else {
+ testPassed('FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was NONE after detach');
+ }
+
+ ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Can detach with framebufferTexture2D as well.");
+ objectType = gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ if (objectType != gl.NONE) {
+ testFailed('Unexpected FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE ' + wtu.glEnumToString(gl, objectType) + ' after detach, should be NONE');
+ } else {
+ testPassed('FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was NONE after detach');
+ }
+}
+
+function runShaderCompileTest(extensionEnabled)
+{
+ debug("");
+ debug("Testing shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));
+
+ let prog = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, "requireDefine_GL_OVR_multiview2"], undefined, undefined, true);
+ expectTrue(!extensionEnabled == !prog,
+ "GL_OVR_multiview2 must be defined by the preprocessor iff OVR_multiview2 is enabled by getExtension.");
+ if (extensionEnabled) {
+ prog = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, "forbidDefine_GL_OVR_multiview"], undefined, undefined, true);
+ expectTrue(prog, "GL_OVR_multiview must never be defined by the preprocessor.");
+
+ prog = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, "legacyMultiview1Shader"], undefined, undefined, true);
+ expectTrue(!prog, "#extension GL_OVR_multiview must be forbidden.");
+ }
+
+ if (!extensionEnabled) {
+ let multiviewShaders = [
+ getMultiviewPassthroughVertexShader(2),
+ getMultiviewColorFragmentShader()
+ ];
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (testProgram) {
+ testFailed("Compilation of shaders using extension functionality succeeded when the extension is disabled, should fail.");
+ } else {
+ testPassed("Compilation of shaders using extension functionality should fail when the extension is disabled.");
+ }
+ }
+}
+
+function runClearTest()
+{
+ debug("");
+ debug("Testing that calling clear() clears all views");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+
+ gl.clearColor(0, 1, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = [0, 255, 255, 255];
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be cyan');
+ }
+}
+
+function runFragmentShaderRenderTest()
+{
+ debug("");
+ debug("Testing rendering with different colors in fragment shader");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewPassthroughVertexShader(views),
+ getMultiviewColorFragmentShader()
+ ];
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
+ }
+}
+
+function runVertexShaderRenderTest()
+{
+ debug("");
+ debug("Testing rendering with different colors in fragment shader, different offsets in vertex shader");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewOffsetVertexShader(views),
+ getMultiviewColorFragmentShader()
+ ];
+
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+
+ checkVerticalStrip(width, height, views, viewIndex, expectedColor, 'view ' + viewIndex);
+ }
+}
+
+function runRealisticUseCaseRenderTest()
+{
+ debug("");
+ debug("Testing rendering with a different transformation matrix chosen from a uniform array according to ViewID");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewRealisticUseCaseVertexShader(views),
+ getMultiviewColorFragmentShader()
+ ];
+
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+
+ let transformLocation = gl.getUniformLocation(testProgram, 'transform');
+ let transformData = new Float32Array (views * 16);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ let scaleX = 1.0 / views;
+ // offsetX is the position of the left edge of the quad we want to get in normalized device coordinates
+ let offsetX = viewIndex / views * 2.0 - 1.0;
+
+ setupTranslateAndScaleXMatrix(transformData, viewIndex * 16, scaleX, offsetX);
+ }
+ gl.uniformMatrix4fv(transformLocation, false, transformData);
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+
+ checkVerticalStrip(width, height, views, viewIndex, expectedColor, 'view ' + viewIndex);
+ }
+}
+
+function runUniqueObjectTest()
+{
+ debug("");
+ debug("Testing that getExtension() returns the same object each time");
+ gl.getExtension("OVR_multiview2").myProperty = 2;
+ webglHarnessCollectGarbage();
+ shouldBe('gl.getExtension("OVR_multiview2").myProperty', '2');
+}
+
+description("This test verifies the functionality of the OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runExtensionDisabledTest();
+
+ runShaderCompileTest(false);
+
+ debug("");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ runShaderCompileTest(true);
+
+ runQueryTest();
+
+ runDefaultFramebufferQueryTest();
+
+ runInvalidTextureTypeTest();
+
+ runFramebufferQueryTest(true);
+ runFramebufferQueryTest(false);
+
+ runInvalidViewsTest();
+
+ runDetachTest();
+
+ runClearTest();
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runFragmentShaderRenderTest();
+ runVertexShaderRenderTest();
+ runRealisticUseCaseRenderTest();
+ runUniqueObjectTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_depth.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_depth.html
new file mode 100644
index 0000000000..9ea071f25c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_depth.html
@@ -0,0 +1,138 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+<script id="macroFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+#ifdef GL_OVR_multiview2
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+#else
+ // Error expected
+ #error no GL_OVR_multiview2;
+#endif
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runDepthRenderTest()
+{
+ debug("");
+ debug("Testing rendering with a depth texture array and depth test on");
+
+ let width = 64;
+ let height = 64;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewPassthroughVertexShader(views),
+ getMultiviewColorFragmentShader()
+ ];
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ let depthTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.DEPTH32F_STENCIL8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, depthTex, 0, 0, views);
+
+ let expectedStatus = gl.FRAMEBUFFER_COMPLETE;
+ let status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (status != expectedStatus) {
+ testFailed('Framebuffer status: ' + wtu.glEnumToString(gl, status) + ' did not match with the expected value: ' + wtu.glEnumToString(gl, expectedStatus));
+ } else {
+ testPassed('Framebuffer status: ' + wtu.glEnumToString(gl, status) + ' matched with the expected value');
+ }
+
+ // Draw so that the depth test succeeds for all pixels.
+ gl.viewport(0, 0, width, height);
+ gl.enable(gl.DEPTH_TEST);
+ gl.clearDepth(1.0);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw when depth test succeeds");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
+ }
+
+ // Draw so that the depth test fails for all pixels.
+ gl.clearDepth(0.0);
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw when depth test fails");
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = [0, 0, 0, 0];
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
+ }
+}
+
+description("This test verifies drawing to depth buffers with the OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runDepthRenderTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_draw_buffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_draw_buffers.html
new file mode 100644
index 0000000000..5da29d80b4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_draw_buffers.html
@@ -0,0 +1,158 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runDrawBuffersClearTest()
+{
+ debug("");
+ debug("Testing that calling clear() clears all views in all draw buffers");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = [null, null, null];
+ let drawBuffers = [0, 0, 0];
+ for (let texIndex = 0; texIndex < colorTex.length; ++texIndex) {
+ colorTex[texIndex] = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + texIndex, colorTex[texIndex], 0, 0, views);
+ drawBuffers[texIndex] = gl.COLOR_ATTACHMENT0 + texIndex;
+ }
+
+ gl.viewport(0, 0, width, height);
+ gl.drawBuffers(drawBuffers);
+
+ gl.clearColor(0, 1, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let texIndex = 0; texIndex < colorTex.length; ++texIndex) {
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex[texIndex], 0, viewIndex);
+ let expectedColor = [0, 255, 255, 255];
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' of color attachment ' + texIndex + ' should be cyan');
+ }
+ debug("");
+ }
+}
+
+function runDrawBuffersRenderTest()
+{
+ debug("");
+ debug("Testing rendering into multiple draw buffers with a different transformation matrix chosen from a uniform array according to ViewID");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = [null, null, null];
+ let drawBuffers = [0, 0, 0];
+ for (let texIndex = 0; texIndex < colorTex.length; ++texIndex) {
+ colorTex[texIndex] = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + texIndex, colorTex[texIndex], 0, 0, views);
+ drawBuffers[texIndex] = gl.COLOR_ATTACHMENT0 + texIndex;
+ }
+
+ let multiviewShaders = [
+ getMultiviewRealisticUseCaseVertexShader(views),
+ getMultiviewColorFragmentShaderForDrawBuffers(colorTex.length)
+ ];
+
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ gl.viewport(0, 0, width, height);
+ gl.drawBuffers(drawBuffers);
+
+ let transformLocation = gl.getUniformLocation(testProgram, 'transform');
+ let transformData = new Float32Array (views * 16);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ let scaleX = 1.0 / views;
+ // offsetX is the position of the left edge of the quad we want to get in normalized device coordinates
+ let offsetX = viewIndex / views * 2.0 - 1.0;
+
+ setupTranslateAndScaleXMatrix(transformData, viewIndex * 16, scaleX, offsetX);
+ }
+ gl.uniformMatrix4fv(transformLocation, false, transformData);
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let texIndex = 0; texIndex < colorTex.length; ++texIndex) {
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex[texIndex], 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex + texIndex);
+
+ checkVerticalStrip(width, height, views, viewIndex, expectedColor, 'view ' + viewIndex + ' of color attachment ' + texIndex);
+ }
+ debug("");
+ }
+}
+
+description("This test verifies the functionality of the OVR_multiview2 extension when used with multiple draw buffers, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ runDrawBuffersClearTest();
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runDrawBuffersRenderTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_flat_varying.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_flat_varying.html
new file mode 100644
index 0000000000..9a99de7e84
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_flat_varying.html
@@ -0,0 +1,93 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runFlatVaryingTest()
+{
+ debug("");
+ debug("Testing rendering with different colors in fragment shader");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewFlatVaryingVertexShader(views),
+ getMultiviewFlatVaryingFragmentShader()
+ ];
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
+ }
+}
+
+description("This test verifies that flat varyings work in multiview shaders using OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runFlatVaryingTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_instanced_draw.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_instanced_draw.html
new file mode 100644
index 0000000000..b55d0cfc03
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_instanced_draw.html
@@ -0,0 +1,105 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runInstancedDrawTest()
+{
+ debug("");
+ debug("Testing instanced rendering");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewInstancedVertexShader(views),
+ getInstanceColorFragmentShader()
+ ];
+
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let colorRegionLeftEdge = (width / (views * 2)) * viewIndex;
+ let colorRegionRightEdge = (width / (views * 2)) * (viewIndex + 2);
+ let stripWidth = (colorRegionRightEdge - colorRegionLeftEdge) / 2;
+ if (colorRegionLeftEdge > 0) {
+ wtu.checkCanvasRect(gl, 0, 0, Math.floor(colorRegionLeftEdge) - 1, height, [0, 0, 0, 0], 'the left edge of view ' + viewIndex + ' should be untouched');
+ }
+ if (colorRegionRightEdge < width) {
+ wtu.checkCanvasRect(gl, colorRegionRightEdge + 1, 0, width - colorRegionRightEdge - 1, height, [0, 0, 0, 0], 'the right edge of view ' + viewIndex + ' should be untouched');
+ }
+ let expectedColor = getExpectedColor(0);
+ wtu.checkCanvasRect(gl, colorRegionLeftEdge + 1, 0, stripWidth - 2, height, expectedColor, 'a thin strip in view ' + viewIndex + ' drawn by instance 0 should be colored ' + expectedColor);
+ expectedColor = getExpectedColor(1);
+ wtu.checkCanvasRect(gl, colorRegionLeftEdge + stripWidth + 1, 0, stripWidth - 2, height, expectedColor, 'a thin strip in view ' + viewIndex + ' drawn by instance 1 should be colored ' + expectedColor);
+ }
+}
+
+description("This test verifies instanced draws together with the OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runInstancedDrawTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_non_multiview_shaders.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_non_multiview_shaders.html
new file mode 100644
index 0000000000..44e2ea02ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_non_multiview_shaders.html
@@ -0,0 +1,93 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runNonMultiviewShaderTest()
+{
+ debug("");
+ debug("Testing rendering with shaders that don't declare num_views");
+
+ let width = 256;
+ let height = 256;
+ let depth = 2; // always supported so no need to query MAX_VIEWS_OVR.
+
+ let testProgram = wtu.setupSimpleColorProgram(gl);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let colorUniformLocation = gl.getUniformLocation(testProgram, 'u_color');
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
+
+ gl.viewport(0, 0, width, height);
+
+ gl.uniform4f(colorUniformLocation, 0.0, 1.0, 0.0, 1.0);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw when using a non-multiview shader as long as the number of views is 1");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 0, 255], 'view 0 should be green');
+
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "draw should generate an INVALID_OPERATION error when using a non-multiview shader and the number of views is > 1");
+}
+
+description("This test verifies that non-multiview shaders work correctly with OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runNonMultiviewShaderTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_single_view_operations.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_single_view_operations.html
new file mode 100644
index 0000000000..0e01a3e3b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_single_view_operations.html
@@ -0,0 +1,253 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+
+function runSingleViewReadTest()
+{
+ debug("");
+ debug("Testing reading from a multiview framebuffer with num_views = 1");
+
+ let width = 256;
+ let height = 256;
+ let depth = 2; // always supported so no need to query MAX_VIEWS_OVR.
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
+
+ gl.viewport(0, 0, width, height);
+ gl.clearColor(0.0, 1.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ let buf = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from readPixels");
+
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 255, 255], 'view 0 should be cyan');
+ gl.getError();
+
+ // Also test for the error case with two views
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to read from a framebuffer with two views");
+}
+
+function runSingleViewBlitTest()
+{
+ debug("");
+ debug("Testing blitting from a multiview framebuffer with num_views = 1");
+
+ let width = 256;
+ let height = 256;
+ let depth = 2; // always supported so no need to query MAX_VIEWS_OVR.
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
+
+ gl.viewport(0, 0, width, height);
+ gl.clearColor(0.0, 1.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ gl.canvas.width = width;
+ gl.canvas.height = height;
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.clearColor(0.0, 0.0, 0.0, 0.0)
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from blitFramebuffer");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 255, 255], 'view 0 blitted to the default framebuffer should be cyan');
+
+ // Also test for the error case with multiview blit target
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to blit to a multiview framebuffer even if it has just one view");
+
+ // Also test for the error case with two views
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to blit from a framebuffer with two views");
+}
+
+function runSingleViewCopyTexImage2DTest()
+{
+ debug("");
+ debug("Testing copyTexImage2D from a multiview framebuffer with num_views = 1");
+
+ let width = 256;
+ let height = 256;
+ let depth = 2; // always supported so no need to query MAX_VIEWS_OVR.
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
+
+ gl.viewport(0, 0, width, height);
+ gl.clearColor(0.0, 1.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ let copyTargetTex = createTextureWithNearestFiltering(gl.TEXTURE_2D);
+ gl.bindTexture(gl.TEXTURE_2D, copyTargetTex);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, width, height, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from copyTexImage2D");
+
+ let copyFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, copyFb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, copyTargetTex, 0);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 255, 255], 'copy of view 0 in the 2D texture should be cyan');
+
+ // Also test for the error case with two views
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
+ gl.bindTexture(gl.TEXTURE_2D, copyTargetTex);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, width, height, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to copy from a framebuffer with two views");
+}
+
+function runSingleViewCopyTexSubImage2DTest()
+{
+ debug("");
+ debug("Testing copyTexSubImage2D from a multiview framebuffer with num_views = 1");
+
+ let width = 256;
+ let height = 256;
+ let depth = 2; // always supported so no need to query MAX_VIEWS_OVR.
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
+
+ gl.viewport(0, 0, width, height);
+ gl.clearColor(0.0, 1.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ let copyTargetTex = createTextureWithNearestFiltering(gl.TEXTURE_2D);
+ gl.bindTexture(gl.TEXTURE_2D, copyTargetTex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from copyTexImage2D");
+
+ let copyFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, copyFb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, copyTargetTex, 0);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 255, 255], 'copy of view 0 in the 2D texture should be cyan');
+
+ // Also test for the error case with two views
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
+ gl.bindTexture(gl.TEXTURE_2D, copyTargetTex);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to copy from a framebuffer with two views");
+}
+
+function runSingleViewCopyTexSubImage3DTest()
+{
+ debug("");
+ debug("Testing copyTexSubImage3D from a multiview framebuffer with num_views = 1");
+
+ let width = 256;
+ let height = 256;
+ let depth = 2; // always supported so no need to query MAX_VIEWS_OVR.
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
+
+ gl.viewport(0, 0, width, height);
+ gl.clearColor(0.0, 1.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear");
+
+ let copyTargetTex = createTextureWithNearestFiltering(gl.TEXTURE_3D);
+ gl.bindTexture(gl.TEXTURE_3D, copyTargetTex);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from copyTexSubImage3D");
+
+ let copyFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, copyFb);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, copyTargetTex, 0, 0);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 255, 255], 'copy of view 0 in the 3D texture should be cyan');
+
+ // Also test for the error case with two views
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
+ gl.bindTexture(gl.TEXTURE_3D, copyTargetTex);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to copy from a framebuffer with two views");
+}
+
+description("This test verifies that framebuffers with only one view can be read from with OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ runSingleViewReadTest();
+
+ runSingleViewBlitTest();
+
+ runSingleViewCopyTexImage2DTest();
+
+ runSingleViewCopyTexSubImage2DTest();
+
+ runSingleViewCopyTexSubImage3DTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_timer_query.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_timer_query.html
new file mode 100644
index 0000000000..9f76fadf98
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_timer_query.html
@@ -0,0 +1,142 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+let queryExt = null;
+
+function runClearTest()
+{
+ debug("");
+ debug("Testing clear");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+
+ gl.clearColor(1, 0, 0, 1);
+
+ let query = gl.createQuery();
+ gl.beginQuery(queryExt.TIME_ELAPSED_EXT, query);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from setup");
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "multiview clear should generate invalid operation when a timer query is active");
+
+ gl.endQuery(queryExt.TIME_ELAPSED_EXT);
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = [0, 0, 0, 0];
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be untouched');
+ }
+}
+
+function runFragmentShaderRenderTest()
+{
+ debug("");
+ debug("Testing rendering with different colors in fragment shader");
+
+ let width = 256;
+ let height = 256;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewPassthroughVertexShader(views),
+ getMultiviewColorFragmentShader()
+ ];
+ let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ gl.viewport(0, 0, width, height);
+
+ let query = gl.createQuery();
+ gl.beginQuery(queryExt.TIME_ELAPSED_EXT, query);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from setup");
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "multiview draw should generate invalid operation when a timer query is active");
+
+ gl.endQuery(queryExt.TIME_ELAPSED_EXT);
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = [0, 0, 0, 0];
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be untouched');
+ }
+}
+
+description("This test verifies the functionality of the OVR_multiview2 extension and its interaction with EXT_disjoint_timer_query_webgl2, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2") || !gl.getExtension("EXT_disjoint_timer_query_webgl2")) {
+ testPassed("No OVR_multiview2 support or no EXT_disjoint_timer_query_webgl2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 and EXT_disjoint_timer_query_webgl2 extensions");
+ ext = gl.getExtension('OVR_multiview2');
+ queryExt = gl.getExtension('EXT_disjoint_timer_query_webgl2');
+
+ runClearTest();
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runFragmentShaderRenderTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_transform_feedback.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_transform_feedback.html
new file mode 100644
index 0000000000..297dd43f1f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_transform_feedback.html
@@ -0,0 +1,125 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL OVR_multiview2 Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/ovr_multiview2_util.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+let wtu = WebGLTestUtils;
+let gl = wtu.create3DContext(null, null, 2);
+let ext = null;
+let queryExt = null;
+
+function runTransformFeedbackTest()
+{
+ debug("");
+ debug("Testing transform feedback combined with multiview rendering");
+
+ let width = 64;
+ let height = 64;
+
+ let views = gl.getParameter(ext.MAX_VIEWS_OVR);
+
+ let multiviewShaders = [
+ getMultiviewVaryingVertexShader(views),
+ getMultiviewVaryingFragmentShader()
+ ];
+ let testProgram = wtu.setupTransformFeedbackProgram(gl, multiviewShaders, ['testVarying'], gl.SEPARATE_ATTRIBS, ['a_position'], [0], true);
+ if (!testProgram) {
+ testFailed("Compilation with extension enabled failed.");
+ return;
+ }
+
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
+ ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
+
+ let xfb = gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, xfb);
+
+ let xfbBuffer = gl.createBuffer();
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 128, gl.DYNAMIC_DRAW);
+
+ gl.viewport(0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from setup");
+
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "rendering to a multiview framebuffer with more than one view when there's an active transform feedback should result in invalid operation");
+
+ gl.pauseTransformFeedback();
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw when rendering to a multiview framebuffer with more than one view when there's an active paused transform feedback");
+
+ let readFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
+ }
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw when transform feedback is unbound");
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
+ for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
+ let expectedColor = getExpectedColor(viewIndex);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
+ }
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, xfb);
+ gl.endTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from ending transform feedback");
+}
+
+description("This test verifies interaction between transform feedback and the OVR_multiview2 extension, if it is available.");
+
+debug("");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (!gl.getExtension("OVR_multiview2")) {
+ testPassed("No OVR_multiview2 support -- this is legal");
+ } else {
+ testPassed("Successfully enabled OVR_multiview2 extension");
+ ext = gl.getExtension('OVR_multiview2');
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ runTransformFeedbackTest();
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html
new file mode 100644
index 0000000000..b2b4d1257f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html
@@ -0,0 +1,115 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Extensions promoted to core should not be possible to use in shaders</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fragShaderRequire" type="x-shader/x-fragment">
+#extension $(ext) : require
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="fragShaderIfdef" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+#ifdef $(ext)
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+#else
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+#endif
+}
+</script>
+<script id="fragShader300Require" type="x-shader/x-fragment">#version 300 es
+#extension $(ext) : require
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="fragShader300Ifdef" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+#ifdef $(ext)
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+#else
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+#endif
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+var wtu = WebGLTestUtils;
+
+var shaderTemplateRequire = wtu.getScript('fragShaderRequire');
+var shaderTemplate300Require = wtu.getScript('fragShader300Require');
+var shaderTemplateIfdef = wtu.getScript('fragShaderIfdef');
+var shaderTemplate300Ifdef = wtu.getScript('fragShader300Ifdef');
+
+var extensions = [
+ 'GL_EXT_draw_buffers',
+ 'GL_EXT_frag_depth',
+ 'GL_EXT_shader_texture_lod',
+ 'GL_OES_standard_derivatives'
+];
+
+var tests = [];
+
+for (var i = 0; i < extensions.length; ++i) {
+ var shaderSrcRequire = wtu.replaceParams(shaderTemplateRequire, {'ext': extensions[i]});
+ tests.push({
+ fShaderSource: shaderSrcRequire,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "ESSL 1.00 Fragment shader that requires " + extensions[i] + " should not compile."
+ });
+ var shaderSrc300Require = wtu.replaceParams(shaderTemplate300Require, {'ext': extensions[i]});
+ tests.push({
+ fShaderSource: shaderSrc300Require,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "ESSL 3.00 Fragment shader that requires " + extensions[i] + " should not compile."
+ });
+
+ var shaderSrcIfdef = wtu.replaceParams(shaderTemplateIfdef, {'ext': extensions[i]});
+ tests.push({
+ fShaderSource: shaderSrcIfdef,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: extensions[i] + " should not be defined in ESSL 1.00 fragment shader."
+ });
+ var shaderSrc300Ifdef = wtu.replaceParams(shaderTemplate300Ifdef, {'ext': extensions[i]});
+ tests.push({
+ fShaderSource: shaderSrc300Ifdef,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: extensions[i] + " should not be defined in ESSL 3.00 fragment shader."
+ });
+}
+
+GLSLConformanceTester.runTests(tests, 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html
new file mode 100644
index 0000000000..7e22942c4d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html
@@ -0,0 +1,64 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+
+function checkExtensionNotAvailable(extension, extensions) {
+ if (extensions.indexOf(extension) >= 0) {
+ testFailed(extension + " was exposed in the WebGL 2.0 context but should not have been");
+ } else {
+ testPassed(extension + " was not exposed in the WebGL 2.0 context");
+ }
+}
+
+description("Promoted extensions from WebGL 1.0 should not be exposed in WebGL 2.0");
+
+shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)");
+
+var exts = gl.getSupportedExtensions();
+
+var promotedExtensions = [
+ "ANGLE_instanced_arrays",
+ "EXT_blend_minmax",
+ "EXT_frag_depth",
+ "EXT_shader_texture_lod",
+ "EXT_sRGB",
+ "OES_element_index_uint",
+ "OES_standard_derivatives",
+ "OES_texture_float",
+ "OES_texture_half_float",
+ "OES_texture_half_float_linear",
+ "OES_vertex_array_object",
+ "WEBGL_depth_texture",
+ "WEBGL_draw_buffers",
+]
+
+for (var i = 0; i < promotedExtensions.length; ++i) {
+ checkExtensionNotAvailable(promotedExtensions[i], exts);
+}
+
+debug("")
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/required-extensions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/required-extensions.html
new file mode 100644
index 0000000000..c3de2a5677
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/required-extensions.html
@@ -0,0 +1,58 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+const wtu = WebGLTestUtils;
+let gl;
+
+description("Ensure that required extensions are supported");
+
+shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)");
+
+const supportedExts = gl.getSupportedExtensions();
+
+function hasExt(name) {
+ return supportedExts.indexOf(name) >= 0;
+}
+
+const has_s3tc = hasExt('WEBGL_compressed_texture_s3tc');
+const has_s3tc_srgb = hasExt('WEBGL_compressed_texture_s3tc_srgb');
+const has_rgtc = hasExt('EXT_texture_compression_rgtc');
+const has_etc = hasExt('WEBGL_compressed_texture_etc');
+
+debug(`has_s3tc: ${has_s3tc}`);
+debug(`has_s3tc_srgb: ${has_s3tc_srgb}`);
+debug(`has_rgtc: ${has_rgtc}`);
+debug(`has_etc: ${has_etc}`);
+
+shouldBeTrue("((has_s3tc && has_s3tc_srgb && has_rgtc) || has_etc)");
+
+// ETC1 extension must not be exposed on WebGL 2.0 contexts without ETC2.
+debug("");
+const has_etc1 = hasExt('WEBGL_compressed_texture_etc1');
+debug(`has_etc1: ${has_etc1}`);
+shouldBeTrue("has_etc1 == has_etc");
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html
new file mode 100644
index 0000000000..37f3e23762
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html
@@ -0,0 +1,1021 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL ANGLE_base_vertex_base_instance Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/compositing-test.js"></script>
+<script src="../../js/tests/invalid-vertex-attrib-test.js"></script>
+</head>
+<body>
+<script id="vshaderBaseInstanceWithoutExt" type="x-shader/x-vertex">#version 300 es
+layout(location = 0) in vec2 vPosition;
+out vec4 color;
+void main()
+{
+ color = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_Position = vec4(vPosition * 2.0 - 1.0, gl_BaseInstance, 1);
+}
+</script>
+<!-- Check gl_InstanceID starts at 0 regardless of gl_BaseInstance -->
+<script id="vshaderInstanceIDCheck" type="x-shader/x-vertex">#version 300 es
+layout(location = 0) in vec2 vPosition;
+out vec4 color;
+void main()
+{
+ if (gl_InstanceID == 0) {
+ color = vec4(0, 1, 0, 1);
+ } else {
+ color = vec4(1, 0, 0, 1);
+ }
+ gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1);
+}
+</script>
+<script id="vshaderBaseVertexWithoutExt" type="x-shader/x-vertex">#version 300 es
+layout(location = 0) in vec2 vPosition;
+out vec4 color;
+void main()
+{
+ color = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_Position = vec4(vPosition * 2.0 - 1.0, gl_BaseVertex, 1);
+}
+</script>
+<script id="vshaderWithExt" type="x-shader/x-vertex">#version 300 es
+#extension GL_ANGLE_base_vertex_base_instance : require
+layout(location = 0) in vec2 vPosition;
+out vec4 color;
+void main()
+{
+ color = vec4(0, 1, 0, 1);
+ gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1);
+}
+</script>
+<!-- Check gl_VertexID starts at gl_BaseVertex -->
+<script id="vshaderVertexIDCheck" type="x-shader/x-vertex">#version 300 es
+layout(location = 0) in vec2 vPosition;
+out vec4 color;
+void main()
+{
+ if (gl_VertexID >= 3) {
+ color = vec4(0, 1, 0, 1);
+ } else {
+ color = vec4(1, 0, 0, 1);
+ }
+ gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1);
+}
+</script>
+<script id="vshaderSimple" type="x-shader/x-vertex">#version 300 es
+ layout(location = 0) in vec2 vPosition;
+ layout(location = 1) in float vInstance;
+ out vec4 color;
+ void main()
+ {
+ if (vInstance <= 0.0) {
+ color = vec4(1.0, 0.0, 0.0, 1.0);
+ } else if (vInstance <= 1.0) {
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+ } else if (vInstance <= 2.0) {
+ color = vec4(0.0, 0.0, 1.0, 1.0);
+ } else {
+ color = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+
+ gl_Position = vec4(vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
+ }
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+ precision mediump float;
+ in vec4 color;
+ out vec4 oColor;
+ void main() {
+ oColor = color;
+ }
+</script>
+<div id="description"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("This test verifies the functionality of the WEBGL_[multi]_draw_basevertex_base_instance extension, if it is available.");
+
+const wtu = WebGLTestUtils;
+const canvas = document.getElementById("canvas");
+canvas.style.backgroundColor = '#000';
+canvas.style.imageRendering = 'pixelated'; // Because Chrome doesn't support crisp-edges.
+canvas.style.imageRendering = 'crisp-edges';
+const attribs = {
+ antialias: false,
+};
+const gl = wtu.create3DContext(canvas, attribs, 2);
+
+const width = gl.canvas.width;
+const height = gl.canvas.height;
+const x_count = 8;
+const y_count = 8;
+const quad_count = x_count * y_count;
+const tri_count = quad_count * 2;
+const tileSize = [ 1/x_count, 1/y_count ];
+const tilePixelSize = [ Math.floor(width / x_count), Math.floor(height / y_count) ];
+const quadRadius = [ 0.25 * tileSize[0], 0.25 * tileSize[1] ];
+const pixelCheckSize = [ Math.floor(quadRadius[0] * width), Math.floor(quadRadius[1] * height) ];
+const bufferUsageSet = [ gl.STATIC_DRAW, gl.DYNAMIC_DRAW ];
+
+function getTileCenter(x, y) {
+ return [ tileSize[0] * (0.5 + x), tileSize[1] * (0.5 + y) ];
+}
+
+function getQuadVertices(x, y) {
+ const center = getTileCenter(x, y);
+ return [
+ [center[0] - quadRadius[0], center[1] - quadRadius[1], 0],
+ [center[0] + quadRadius[0], center[1] - quadRadius[1], 0],
+ [center[0] + quadRadius[0], center[1] + quadRadius[1], 0],
+ [center[0] - quadRadius[0], center[1] + quadRadius[1], 0],
+ ];
+}
+
+const indicesData = [];
+let verticesData = [];
+let nonIndexedVerticesData = [];
+const instanceIDsData = Array.from(Array(x_count).keys());
+const is = new Uint16Array([0, 1, 2, 0, 2, 3]);
+// Rects in the same column are within a vertex array, testing gl_VertexID, gl_BaseVertex
+// Rects in the same row are drawn by instancing, testing gl_InstanceID, gl_BaseInstance
+for (let y = 0; y < y_count; ++y) {
+ // v3 ---- v2
+ // | |
+ // | |
+ // v0 ---- v1
+
+ // Get only one column of quad vertices as our geometry
+ // Rely on BaseInstance to duplicate on x axis
+ const vs = getQuadVertices(0, y);
+
+ for (let i = 0; i < vs.length; ++i) {
+ verticesData = verticesData.concat(vs[i]);
+ }
+
+ for (let i = 0; i < is.length; ++i) {
+ nonIndexedVerticesData = nonIndexedVerticesData.concat(vs[is[i]]);
+ }
+}
+
+// Build the indicesData used by drawElements*
+for (let i = 0; i < y_count; ++i) {
+ let oi = 6 * i;
+ let ov = 4 * i;
+ for (let j = 0; j < is.length; ++j) {
+ indicesData[oi + j] = is[j] + ov;
+ }
+}
+
+const indices = new Uint16Array(indicesData);
+const vertices = new Float32Array(verticesData);
+const nonIndexedVertices = new Float32Array(nonIndexedVerticesData);
+const instanceIDs = new Float32Array(instanceIDsData);
+
+const indexBuffer = gl.createBuffer();
+const vertexBuffer = gl.createBuffer();
+const nonIndexedVertexBuffer = gl.createBuffer();
+const instanceIDBuffer = gl.createBuffer();
+
+const drawArraysDrawCount = x_count / 2;
+let drawArraysParams = {
+ drawCount: drawArraysDrawCount,
+ firsts: new Uint32Array(drawArraysDrawCount).fill(0),
+ counts: new Uint32Array(drawArraysDrawCount).fill(y_count * 6),
+ instances: new Uint32Array(drawArraysDrawCount).fill(2),
+ baseInstances: new Uint32Array(drawArraysDrawCount)
+};
+
+for (let i = 0; i < x_count / 2; ++i) {
+ drawArraysParams.baseInstances[i] = i * 2;
+}
+
+const drawElementsDrawCount = x_count * y_count / 2;
+let drawElementsParams = {
+ drawCount: drawElementsDrawCount,
+ offsets: new Uint32Array(drawElementsDrawCount).fill(0),
+ counts: new Uint32Array(drawElementsDrawCount).fill(6),
+ instances: new Uint32Array(drawElementsDrawCount).fill(2),
+ baseVertices: new Uint32Array(drawElementsDrawCount),
+ baseInstances: new Uint32Array(drawElementsDrawCount)
+};
+
+let b = 0;
+for (let v = 0; v < y_count; ++v) {
+ for (let i = 0; i < x_count; i+=2) {
+ drawElementsParams.baseVertices[b] = v * 4;
+ drawElementsParams.baseInstances[b] = i;
+ ++b;
+ }
+}
+
+function setupGeneralBuffers(bufferUsage) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, bufferUsage);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, bufferUsage);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, nonIndexedVertices, bufferUsage);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, instanceIDBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, instanceIDs, bufferUsage);
+}
+
+// Check if the extension is either both enabled and supported or
+// not enabled and not supported.
+function runSupportedTest(extensionName, extensionEnabled) {
+ const supported = gl.getSupportedExtensions();
+ if (supported.indexOf(extensionName) >= 0) {
+ if (extensionEnabled) {
+ testPassed(extensionName + ' listed as supported and getExtension succeeded');
+ return true;
+ } else {
+ testFailed(extensionName + ' listed as supported but getExtension failed');
+ }
+ } else {
+ if (extensionEnabled) {
+ testFailed(extensionName + ' not listed as supported but getExtension succeeded');
+ } else {
+ testPassed(extensionName + ' not listed as supported and getExtension failed -- this is legal');
+ }
+ }
+ return false;
+}
+
+function runTest() {
+ if (!gl) {
+ return function() {
+ testFailed('WebGL context does not exist');
+ }
+ }
+
+ doTest('WEBGL_draw_instanced_base_vertex_base_instance', false);
+ doTest('WEBGL_multi_draw_instanced_base_vertex_base_instance', true);
+
+ testGlslBuiltins();
+}
+
+// -
+
+function* range(n) {
+ for (let i = 0; i < n; i++) {
+ yield i;
+ }
+}
+
+function crossCombine(...args) {
+ function crossCombine2(listA, listB) {
+ const listC = [];
+ for (const a of listA) {
+ for (const b of listB) {
+ const c = Object.assign({}, a, b);
+ listC.push(c);
+ }
+ }
+ return listC;
+ }
+
+ let res = [{}];
+ while (args.length) {
+ const next = args.shift();
+ next[0].defined;
+ res = crossCombine2(res, next);
+ }
+ return res;
+}
+
+// -
+
+const PASSTHROUGH_FRAG_SRC = `\
+#version 300 es
+precision mediump float;
+in vec4 v_color;
+out vec4 o_color;
+
+void main() {
+ o_color = v_color;
+}
+`;
+
+function testGlslBuiltins() {
+ const EXT = gl.getExtension('WEBGL_draw_instanced_base_vertex_base_instance');
+
+ const vertid_prog = (() => {
+ const vert_src = `\
+#version 300 es
+#line 405
+layout(location = 0) in int a_vertex_id; // Same as gl_VertexID
+out vec4 v_color;
+
+void main() {
+ gl_Position = vec4(0,0,0,1);
+ gl_PointSize = 1.0;
+ v_color = vec4(float(gl_VertexID), float(a_vertex_id),0,0);
+ v_color /= 255.0;
+}
+`;
+ const prog = wtu.setupProgram(gl, [vert_src, PASSTHROUGH_FRAG_SRC],
+ undefined, undefined, /*logShaders*/ true);
+ expectTrue(!!prog, `make_vertid_prog failed`);
+ return prog;
+ })();
+
+ const instid_prog = (() => {
+ const vert_src = `\
+#version 300 es
+#line 425
+layout(location = 0) in int a_vertex_id; // Same as gl_VertexID
+layout(location = 1) in int a_instance_div1; // Same as base_instance+gl_InstanceID
+layout(location = 2) in int a_instance_div2; // Same as base_instance+floor(gl_InstanceID/2)
+layout(location = 3) in int a_instance_div3; // Same as base_instance+floor(gl_InstanceID/3)
+out vec4 v_color;
+
+void main() {
+ gl_Position = vec4(0,0,0,1);
+ gl_PointSize = 1.0;
+ v_color = vec4(float(gl_InstanceID), float(a_instance_div1),
+ float(a_instance_div2), float(a_instance_div3));
+ v_color /= 255.0;
+}
+`;
+ const prog = wtu.setupProgram(gl, [vert_src, PASSTHROUGH_FRAG_SRC],
+ undefined, undefined, /*logShaders*/ true);
+ expectTrue(!!prog, `make_instid_prog failed`);
+ return prog;
+ })();
+
+ const COUNT_UP_DATA = new Int32Array(1000);
+ for (const i in COUNT_UP_DATA) {
+ COUNT_UP_DATA[i] = i;
+ }
+
+ const vertex_id_buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertex_id_buf);
+ gl.bufferData(gl.ARRAY_BUFFER, COUNT_UP_DATA, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribIPointer(0, 1, gl.INT, 0, 0);
+
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribIPointer(1, 1, gl.INT, 0, 0);
+ gl.vertexAttribDivisor(1, 1);
+
+ gl.enableVertexAttribArray(2);
+ gl.vertexAttribIPointer(2, 1, gl.INT, 0, 0);
+ gl.vertexAttribDivisor(2, 2);
+
+ gl.enableVertexAttribArray(3);
+ gl.vertexAttribIPointer(3, 1, gl.INT, 0, 0);
+ gl.vertexAttribDivisor(3, 3);
+
+ const index_buf = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buf);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, COUNT_UP_DATA, gl.STATIC_DRAW);
+
+ gl.canvas.width = gl.canvas.height = 1;
+ gl.canvas.style.width = gl.canvas.style.height = '1em';
+ gl.viewport(0, 0, 1, 1);
+
+ const expect_pixel = (() => {
+ const was = new Uint8Array(4);
+ return (desc, subtest, expected) => {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, was);
+ if (!areArraysEqual(was, expected)) {
+ testFailed(`${subtest}: Expected [${expected}], was [${was}]. desc: ${JSON.stringify(desc)}`);
+ } else {
+ debug(`${subtest}: Was [${was}] as expected.`);
+ }
+ };
+ })();
+
+ // Common setup complete
+ // -
+ // Create testcases
+
+ const DRAW_FUNC_COMBINER = [{
+ name: 'drawArraysInstanced',
+ draw: desc => {
+ if (desc.base_vert) return false;
+ if (desc.base_inst) return false;
+ gl.drawArraysInstanced(gl[desc.mode], desc.first_vert,
+ desc.vert_count, desc.inst_count);
+ return true;
+ },
+ }, {
+ name: 'drawElementsInstanced',
+ draw: desc => {
+ if (desc.base_vert) return false;
+ if (desc.base_inst) return false;
+ gl.drawElementsInstanced(gl[desc.mode], desc.vert_count,
+ gl.UNSIGNED_INT, 4*desc.first_vert, desc.inst_count);
+ return true;
+ },
+ }, {
+ name: 'drawArraysInstancedBaseInstanceWEBGL',
+ draw: desc => {
+ if (desc.base_vert) return false;
+ if (!EXT) return false;
+ EXT.drawArraysInstancedBaseInstanceWEBGL(gl[desc.mode],
+ desc.first_vert, desc.vert_count, desc.inst_count,
+ desc.base_inst);
+ return true;
+ },
+ }, {
+ name: 'drawElementsInstancedBaseVertexBaseInstanceWEBGL',
+ draw: desc => {
+ if (!EXT) return false;
+ EXT.drawElementsInstancedBaseVertexBaseInstanceWEBGL(
+ gl[desc.mode], desc.vert_count, gl.UNSIGNED_INT, 4*desc.first_vert,
+ desc.inst_count, desc.base_vert, desc.base_inst);
+ return true;
+ },
+ }];
+
+ // -
+
+ function make_key_combiner(key, vals) {
+ const ret = [];
+ for (const v of vals) {
+ const cur = {};
+ cur[key] = v;
+ ret.push(cur);
+ }
+ return ret;
+ }
+
+ const TEST_DESCS = crossCombine(
+ DRAW_FUNC_COMBINER,
+ make_key_combiner('base_vert', [0,1,2]),
+ make_key_combiner('vert_count', [0,1,2]),
+ make_key_combiner('base_inst', [0,1,2]),
+ make_key_combiner('inst_count', range(10)),
+ make_key_combiner('first_vert', [0,1,2]),
+ );
+ console.log('TEST_DESCS', TEST_DESCS);
+
+ // -
+ // Run testcases
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.STENCIL_TEST);
+ gl.disable(gl.BLEND);
+
+ for (const desc of TEST_DESCS) {
+ gl.disable(gl.SCISSOR_TEST);
+ gl.clearBufferfv(gl.COLOR, 0, [1,0,0,1]);
+
+ // From OpenGL ES 3.2 spec section 10.5
+ // https://www.khronos.org/registry/OpenGL/specs/es/3.2/es_spec_3.2.pdf
+ // The index of any element transferred to the GL by DrawArraysOneInstance
+ // is referred to as its vertex ID, and may be read by a vertex shader as gl_VertexID.
+ // The vertex ID of the ith element transferred is first + i.
+ const last_gl_vert_id = desc.base_vert + desc.first_vert + desc.vert_count - 1;
+ const last_vert_id = last_gl_vert_id;
+ const last_inst_id = desc.inst_count - 1;
+ const last_inst_div1 = desc.base_inst + last_inst_id;
+ const last_inst_div2 = desc.base_inst + Math.floor(last_inst_id / 2);
+ const last_inst_div3 = desc.base_inst + Math.floor(last_inst_id / 3);
+
+ gl.useProgram(vertid_prog);
+ if (!desc.draw(desc)) continue;
+ debug('\ndesc: ' + JSON.stringify(desc));
+
+ wtu.glErrorAssert(gl, 0);
+ if (!desc.vert_count || !desc.inst_count) {
+ expect_pixel(desc, 'vertid_prog', [255, 0, 0, 255]);
+ continue;
+ }
+
+ expect_pixel(desc, 'vertid_prog', [last_gl_vert_id, last_vert_id, 0, 0]);
+
+ gl.useProgram(instid_prog);
+ desc.draw(desc);
+ expect_pixel(desc, 'instid_prog', [last_inst_id, last_inst_div1, last_inst_div2, last_inst_div3]);
+ }
+}
+
+// -
+
+function doTest(extensionName, multiDraw) {
+ const ext = gl.getExtension(extensionName);
+ if (!runSupportedTest(extensionName, ext)) {
+ return;
+ }
+
+ function getShaderSource(countX, countY, config) {
+ const vs = [
+ '#version 300 es',
+ config.isMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '',
+ '#define kCountX ' + countX.toString(),
+ '#define kCountY ' + countY.toString(),
+ 'layout(location = 0) in vec2 vPosition;',
+ 'layout(location = 1) in float vInstanceID;',
+ 'out vec4 color;',
+ 'void main()',
+ '{',
+ ' const float xStep = 1.0 / float(kCountX);',
+ ' const float yStep = 1.0 / float(kCountY);',
+ ' float xID = vInstanceID;',
+ ' float xColor = 1.0 - xStep * xID;',
+ ' float yID = floor(float(gl_VertexID) / ' + (config.isDrawArrays ? '6.0' : '4.0') + ' + 0.01);',
+ ' color = vec4(xColor, 1.0 - yStep * yID, 1.0',
+ ' , 1.0);',
+ ' mat3 transform = mat3(1.0);',
+ ' transform[2][0] = xID * xStep;',
+ ' gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1.0);',
+ '}'
+ ].join('\n');
+
+ const fs = document.getElementById('fshader').text.trim();
+
+ return [vs, fs];
+ }
+
+ function runValidationTests(bufferUsage) {
+ const vertexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0.2,0.2, 0.8,0.2, 0.5,0.8 ]), bufferUsage);
+
+ const indexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2 ]), bufferUsage);
+
+ const instanceBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 1, 2 ]), bufferUsage);
+
+ const program = wtu.setupProgram(gl, ['vshaderSimple', 'fshader'], ['vPosition, vInstanceID'], [0, 1], true);
+ expectTrue(program != null, "can compile simple program");
+
+ function setupInstanced() {
+ gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(1, 1);
+ }
+
+ setupInstanced();
+
+ function setupDrawArrays() {
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+ }
+
+ function setupDrawElements() {
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+ }
+
+ function makeDrawValidationCheck(drawFunc, setup) {
+ if (!drawFunc) {
+ return function() {};
+ }
+ return function(f_args, expect, msg) {
+ setup();
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ drawFunc.apply(ext, f_args);
+ wtu.glErrorShouldBe(gl, expect, drawFunc.name + " " + msg);
+ gl.disableVertexAttribArray(0);
+ }
+ }
+
+ if (!multiDraw) {
+ const checkDrawArraysInstancedBaseInstance = makeDrawValidationCheck(
+ ext.drawArraysInstancedBaseInstanceWEBGL, setupDrawArrays);
+ const checkDrawElementsInstancedBaseVertexBaseInstance = makeDrawValidationCheck(
+ ext.drawElementsInstancedBaseVertexBaseInstanceWEBGL, setupDrawElements);
+ checkDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, 0, 3, 1, 1],
+ gl.NO_ERROR, "with gl.TRIANGLES"
+ );
+ checkDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0, 1, 0, 0],
+ gl.NO_ERROR, "with gl.TRIANGLES"
+ );
+
+ checkDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, 0, 3, 1, 3],
+ [gl.NO_ERROR, gl.INVALID_OPERATION],
+ "with baseInstance leading to out of bounds"
+ );
+ checkDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0, 1, 2, 0],
+ [gl.NO_ERROR, gl.INVALID_OPERATION],
+ "with baseVertex leading to out of bounds"
+ );
+ checkDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0, 1, 0, 3],
+ [gl.NO_ERROR, gl.INVALID_OPERATION],
+ "with baseInstance leading to out of bounds"
+ );
+ checkDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, 3, gl.UNSIGNED_BYTE, 0, 1, 2, 3],
+ [gl.NO_ERROR, gl.INVALID_OPERATION],
+ "with both baseVertex and baseInstance leading to out of bounds"
+ );
+ } else {
+ const checkMultiDrawArraysInstancedBaseInstance = makeDrawValidationCheck(
+ ext.multiDrawArraysInstancedBaseInstanceWEBGL, setupDrawArrays);
+ const checkMultiDrawElementsInstancedBaseVertexBaseInstance = makeDrawValidationCheck(
+ ext.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL, setupDrawElements);
+
+ // Check that drawing a single triangle works
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 0, [1], 0, [0], 0, 1],
+ gl.NO_ERROR, "with gl.TRIANGLES"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 0, [0], 0, 1],
+ gl.NO_ERROR, "with gl.TRIANGLES"
+ );
+
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 0, [1], 0, [3], 0, 1],
+ [gl.NO_ERROR, gl.INVALID_OPERATION], "with baseInstance leads to out of bounds"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [2], 0, [0], 0, 1],
+ [gl.NO_ERROR, gl.INVALID_OPERATION], "with baseVertex leads to out of bounds"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 0, [3], 0, 1],
+ [gl.NO_ERROR, gl.INVALID_OPERATION], "with baseInstance leads to out of bounds"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [2], 0, [3], 0, 1],
+ [gl.NO_ERROR, gl.INVALID_OPERATION],
+ "with both baseVertex and baseInstance lead to out of bounds"
+ );
+
+ // Zero drawcount permitted
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 0, [1], 0, [0], 0, 0],
+ gl.NO_ERROR, "with drawcount == 0"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 0, [0], 0, 0],
+ gl.NO_ERROR, "with drawcount == 0"
+ );
+
+ // Check negative drawcount
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 0, [1], 0, [0], 0, -1],
+ gl.INVALID_VALUE, "with drawcount < 0"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 0, [0], 0, -1],
+ gl.INVALID_VALUE, "with drawcount < 0"
+ );
+
+ // Check offsets greater than array length
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 1, [3], 0, [1], 0, [0], 0, 1],
+ gl.INVALID_OPERATION, "with firstsStart >= firstsList.length"
+ );
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 1, [1], 0, [0], 0, 1],
+ gl.INVALID_OPERATION, "with countsStart >= countsList.length"
+ );
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 0, [1], 1, [0], 0, 1],
+ gl.INVALID_OPERATION, "with instanceCountsStart >= instanceCountsList.length"
+ );
+ checkMultiDrawArraysInstancedBaseInstance(
+ [gl.TRIANGLES, [0], 0, [3], 0, [1], 0, [0], 1, 1],
+ gl.INVALID_OPERATION, "with baseInstancesStart >= baseInstancesList.length"
+ );
+
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 1, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 0, [0], 0, 1],
+ gl.INVALID_OPERATION, "with countsStart >= countsList.length"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 1, [1], 0, [0], 0, [0], 0, 1],
+ gl.INVALID_OPERATION, "with offsetsStart >= offsetsList.length"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 1, [0], 0, [0], 0, 1],
+ gl.INVALID_OPERATION, "with instanceCountsStart >= instanceCountsList.length"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 1, [0], 0, 1],
+ gl.INVALID_OPERATION, "with baseVerticesStart >= baseVerticesList.length"
+ );
+ checkMultiDrawElementsInstancedBaseVertexBaseInstance(
+ [gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [0], 0, [0], 1, 1],
+ gl.INVALID_OPERATION, "with baseInstancesStart >= baseInstancesList.length"
+ );
+ }
+ }
+
+ function runShaderTests(bufferUsage) {
+ let badProgram;
+
+ badProgram = wtu.setupProgram(gl, ["vshaderBaseInstanceWithoutExt", "fshader"]);
+ expectTrue(!badProgram, "cannot compile program with gl_BaseInstance but no extension directive");
+ badProgram = wtu.setupProgram(gl, ["vshaderBaseVertexWithoutExt", "fshader"]);
+ expectTrue(!badProgram, "cannot compile program with gl_BaseVertex but no extension directive");
+
+ badProgram = wtu.setupProgram(gl, ["vshaderWithExt", "fshader"]);
+ expectTrue(!badProgram, "cannot compile program with #extension GL_ANGLE_base_vertex_base_instance");
+
+ const x = Math.floor(width * 0.4);
+ const y = Math.floor(height * 0.4);
+ const xSize = Math.floor(width * 0.2);
+ const ySize = Math.floor(height * 0.2);
+
+ // gl_InstanceID
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0.5,1, 0,1, 0.5,0, 1,1 ]), bufferUsage);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+ const instanceIDProgram = wtu.setupProgram(gl, ["vshaderInstanceIDCheck", "fshader"], ["vPosition"], [0]);
+ expectTrue(instanceIDProgram !== null, "can compile program with gl_InstanceID");
+ gl.useProgram(instanceIDProgram);
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ if (!multiDraw) {
+ ext.drawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, 0, 6, 1, 5);
+ } else {
+ ext.multiDrawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, [0], 0, [6], 0, [1], 0, [5], 0, 1);
+ }
+
+ wtu.checkCanvasRect(gl, x, y, xSize, ySize, [0, 255, 0, 255], "gl_InstanceID should always starts from 0");
+
+ // gl_VertexID
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0.5,1, 0,1, 0.5,0, 1,1, 0,0, 1,0, 0.5,1, 0,1 ]), bufferUsage);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3, 4, 5]), bufferUsage);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+ const vertexIDProgram = wtu.setupProgram(gl, ["vshaderVertexIDCheck", "fshader"], ["vPosition"], [0]);
+ expectTrue(vertexIDProgram !== null, "can compile program with gl_VertexID");
+ gl.useProgram(vertexIDProgram);
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ if (!multiDraw) {
+ ext.drawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 1, 3, 0);
+ } else {
+ ext.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, [6], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [3], 0, [0], 0, 1);
+ }
+
+ wtu.checkCanvasRect(gl, x, y, xSize, ySize, [0, 255, 0, 255], "gl_VertexID should always starts from 0");
+ }
+
+ function runPixelTests() {
+
+ function checkResult(config) {
+ const rects = [];
+ const expected = [
+ [255, 0, 0, 255],
+ [0, 255, 0, 255],
+ [0, 0, 255, 255],
+ ];
+ const msg = config.drawFunc.name + (
+ config.useBaseVertexBuiltin ? ' gl_BaseVertex' : ''
+ ) + (
+ config.useBaseInstanceBuiltin ? ' gl_BaseInstance' : ' InstanceIDArray'
+ );
+ for (let y = 0; y < y_count; ++y) {
+ for (let x = 0; x < x_count; ++x) {
+ const center_x = x * tilePixelSize[0] + Math.floor(tilePixelSize[0] / 2);
+ const center_y = y * tilePixelSize[1] + Math.floor(tilePixelSize[1] / 2);
+
+ rects.push(wtu.makeCheckRect(
+ center_x - Math.floor(pixelCheckSize[0] / 2),
+ center_y - Math.floor(pixelCheckSize[1] / 2),
+ pixelCheckSize[0],
+ pixelCheckSize[1],
+ [
+ 256.0 * (1.0 - x / x_count),
+ 256.0 * (1.0 - y / y_count),
+ (!config.isDrawArrays && config.useBaseVertexBuiltin) ? 256.0 * (1.0 - y / y_count) : 255.0,
+ 255.0
+ ],
+ msg + ' (' + x + ',' + y + ')', 1.0
+ ));
+ }
+ }
+ wtu.checkCanvasRects(gl, rects);
+ }
+
+ // Draw functions variations
+
+ function drawArraysInstancedBaseInstance() {
+ const countPerDraw = y_count * 6;
+ for (let x = 0; x < x_count; x += 2) {
+ ext.drawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, 0, countPerDraw, 2, x);
+ }
+ }
+
+ function multiDrawArraysInstancedBaseInstance() {
+ ext.multiDrawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, drawArraysParams.firsts, 0, drawArraysParams.counts, 0, drawArraysParams.instances, 0, drawArraysParams.baseInstances, 0, drawArraysParams.drawCount);
+ }
+
+ function drawElementsInstancedBaseVertexBaseInstance() {
+ const countPerDraw = 6;
+ for (let v = 0; v < y_count; ++v) {
+ for (let x = 0; x < x_count; x += 2) {
+ ext.drawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, countPerDraw, gl.UNSIGNED_SHORT, 0, 2, v * 4, x);
+ }
+ }
+ }
+
+ function multiDrawElementsInstancedBaseVertexBaseInstance() {
+ ext.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, drawElementsParams.counts, 0, gl.UNSIGNED_SHORT, drawElementsParams.offsets, 0, drawElementsParams.instances, 0, drawElementsParams.baseVertices, 0, drawElementsParams.baseInstances, 0, drawElementsParams.drawCount);
+ }
+
+ function checkDraw(config) {
+ const program = wtu.setupProgram(
+ gl,
+ getShaderSource(x_count, y_count, config),
+ !config.useBaseInstanceBuiltin ? ['vPosition'] : ['vPosition', 'vInstanceID']
+ );
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ if (config.isDrawArrays) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ } else {
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ }
+
+ if (!config.useBaseInstanceBuiltin) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, instanceIDBuffer);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(1, 1);
+ }
+
+ config.drawFunc();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+
+ checkResult(config);
+ }
+
+ checkDraw({
+ drawFunc: multiDraw ? multiDrawArraysInstancedBaseInstance : drawArraysInstancedBaseInstance,
+ isDrawArrays: true,
+ isMultiDraw: multiDraw,
+ useBaseVertexBuiltin: false,
+ useBaseInstanceBuiltin: false
+ });
+
+ checkDraw({
+ drawFunc: multiDraw ? multiDrawElementsInstancedBaseVertexBaseInstance : drawElementsInstancedBaseVertexBaseInstance,
+ isDrawArrays: false,
+ isMultiDraw: multiDraw,
+ useBaseVertexBuiltin: false,
+ useBaseInstanceBuiltin: false
+ });
+ }
+
+ for (let i = 0; i < bufferUsageSet.length; i++) {
+ let bufferUsage = bufferUsageSet[i];
+ debug("Testing with BufferUsage = " + bufferUsage);
+ setupGeneralBuffers(bufferUsage);
+ runValidationTests(bufferUsage);
+ runShaderTests(bufferUsage);
+ runPixelTests();
+ }
+}
+
+
+async function runDrawTests(testFn) {
+ function drawArrays(gl) {
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ function drawElements(gl) {
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ }
+
+ function drawArraysInstanced(gl) {
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, 1);
+ }
+
+ function drawElementsInstanced(gl) {
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 1);
+ }
+
+ function drawArraysInstancedBaseInstanceWEBGL(gl) {
+ const ext = gl.getExtension('WEBGL_draw_instanced_base_vertex_base_instance');
+ if (!ext) {
+ throw 'Should not have run this test without WEBGL_draw_instanced_base_vertex_base_instance';
+ }
+
+ ext.drawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, 0, 6, 1, 0);
+ }
+
+ function drawElementsInstancedBaseVertexBaseInstanceWEBGL(gl) {
+ const ext = gl.getExtension('WEBGL_draw_instanced_base_vertex_base_instance');
+ if (!ext) {
+ throw 'Should not have run this test without WEBGL_draw_instanced_base_vertex_base_instance';
+ }
+
+ ext.drawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 1, 0, 0);
+ }
+
+ function multiDrawArraysInstancedBaseInstanceWEBGL(gl) {
+ const ext = gl.getExtension('WEBGL_multi_draw_instanced_base_vertex_base_instance');
+ if (!ext) {
+ throw 'Should not have run this test without WEBGL_multi_draw_instanced_base_vertex_base_instance';
+ }
+ ext.multiDrawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, [0], 0, [6], 0, [1], 0, [0], 0, 1);
+ }
+
+ function multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(gl) {
+ const ext = gl.getExtension('WEBGL_multi_draw_instanced_base_vertex_base_instance');
+ if (!ext) {
+ throw 'Should not have run this test without WEBGL_multi_draw_instanced_base_vertex_base_instance';
+ }
+ ext.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(
+ gl.TRIANGLES,
+ [6], 0, // counts
+ gl.UNSIGNED_BYTE,
+ [0], 0, // offsets
+ [1], 0, // instances
+ [0], 0, // baseVerts
+ [0], 0, // baseInstances
+ 1, // drawCount
+ );
+ }
+
+ await testFn(drawArrays); // sanity check
+ await testFn(drawElements); // sanity check
+ await testFn(drawArraysInstanced); // sanity check
+ await testFn(drawElementsInstanced); // sanity check
+
+ // It's only legal to call testFn if the extension is supported,
+ // since the invalid vertex attrib tests, in particular, expect the
+ // draw function to have an effect.
+ if (gl.getExtension('WEBGL_draw_instanced_base_vertex_base_instance')) {
+ await testFn(drawArraysInstancedBaseInstanceWEBGL);
+ await testFn(drawElementsInstancedBaseVertexBaseInstanceWEBGL);
+ }
+ if (gl.getExtension('WEBGL_multi_draw_instanced_base_vertex_base_instance')) {
+ await testFn(multiDrawArraysInstancedBaseInstanceWEBGL);
+ await testFn(multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL);
+ }
+}
+
+async function runCompositingTests() {
+ const compositingTestFn = createCompositingTestFn({
+ webglVersion: 2,
+ shadersFn(gl) {
+ const vs = `\
+ #version 300 es
+ layout(location = 0) in vec4 position;
+ void main() {
+ gl_Position = position;
+ }
+ `;
+ const fs = `\
+ #version 300 es
+ precision highp float;
+ out vec4 fragColor;
+ void main() {
+ fragColor = vec4(1, 0, 0, 1);
+ }
+ `;
+ return [vs, fs];
+ },
+ });
+ await runDrawTests(compositingTestFn);
+}
+
+async function runInvalidAttribTests(gl) {
+ const invalidAttribTestFn = createInvalidAttribTestFn(gl);
+ await runDrawTests(invalidAttribTestFn);
+}
+
+async function main() {
+ runTest();
+ await runInvalidAttribTests(gl);
+ await runCompositingTests();
+ finishTest();
+}
+main();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt
new file mode 100644
index 0000000000..5a47d470f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt
@@ -0,0 +1,59 @@
+array-as-return-value.html
+array-assign.html
+array-assign-constructor.html
+array-complex-indexing.html
+array-element-increment.html
+array-equality.html
+array-in-complex-expression.html
+--min-version 2.0.1 array-initialize-with-same-name-array.html
+--min-version 2.0.1 array-length-side-effects.html
+attrib-location-length-limits.html
+bool-type-cast-bug-uint-ivec-uvec.html
+compare-structs-containing-arrays.html
+compound-assignment-type-combination.html
+const-array-init.html
+--min-version 2.0.1 const-struct-from-array-as-function-parameter.html
+--min-version 2.0.1 float-parsing.html
+forbidden-operators.html
+--min-version 2.0.1 forward-declaration.html
+frag-depth.html
+--min-version 2.0.1 fragment-shader-loop-crash.html
+--min-version 2.0.1 gradient-in-discontinuous-loop.html
+--min-version 2.0.1 input-with-interpotaion-as-lvalue.html
+invalid-default-precision.html
+invalid-invariant.html
+loops-with-side-effects.html
+--min-version 2.0.1 matrix-row-major.html
+--min-version 2.0.1 matrix-row-major-dynamic-indexing.html
+misplaced-version-directive.html
+--min-version 2.0.1 no-attribute-vertex-shader.html
+--min-version 2.0.1 precision-side-effects-bug.html
+--min-version 2.0.1 reciprocal-sqrt-of-sum-of-squares-crash.html
+sampler-no-precision.html
+--min-version 2.0.1 sampler-array-indexing.html
+sequence-operator-returns-non-constant.html
+shader-linking.html
+shader-with-1024-character-define.html
+shader-with-1024-character-identifier.frag.html
+shader-with-1025-character-define.html
+shader-with-1025-character-identifier.frag.html
+shader-with-invalid-characters.html
+shader-with-mis-matching-uniform-block.html
+short-circuiting-in-loop-condition.html
+--min-version 2.0.1 switch-case.html
+--min-version 2.0.1 texture-offset-non-constant-offset.html
+texture-offset-out-of-range.html
+--min-version 2.0.1 texture-offset-uniform-texture-coordinate.html
+--min-version 2.0.1 tricky-loop-conditions.html
+--min-version 2.0.1 uint-int-shift-bug.html
+--min-version 2.0.1 unary-minus-operator-in-dynamic-loop.html
+uniform-block-layouts.html
+uniform-block-layout-match.html
+uniform-location-length-limits.html
+--min-version 2.0.1 uniform-struct-with-non-square-matrix.html
+--min-version 2.0.1 uninitialized-local-global-variables.html
+valid-invariant.html
+--min-version 2.0.1 varying-struct-inline-definition.html
+vector-dynamic-indexing.html
+--min-version 2.0.1 vector-dynamic-indexing-nv-driver-bug.html
+--min-version 2.0.1 vector-dynamic-indexing-swizzled-lvalue.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html
new file mode 100644
index 0000000000..45d7353111
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html
@@ -0,0 +1,150 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array as return value 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderReturnedArrayNotUsed" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+void main() {
+ // The function call should be evaluated even if the returned array is not used.
+ plus();
+ my_FragColor = vec4(0.0, ((g == 1) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderCompareReturnedArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] createArray() {
+ ++g;
+ return int[2](g, g);
+}
+
+void main() {
+ // Comparing a returned array should work.
+ if (createArray() == int[2](1, 1)) {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ } else {
+ my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+}
+</script>
+<script id="fshaderReturnReturnedArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] foo() {
+ ++g;
+ return int[2](g, g);
+}
+
+int[2] bar(int addition) {
+ g += addition;
+ // Returning a returned array should work.
+ return foo();
+}
+
+void main() {
+ int a[2] = bar(1);
+ bool arrayCorrect = true;
+ for (int i = 0; i < 2; ++i) {
+ if (a[i] != 2) {
+ arrayCorrect = false;
+ }
+ }
+ my_FragColor = vec4(0.0, ((g == 2 && arrayCorrect) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderReturnedArrayAsParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] createArray() {
+ ++g;
+ return int[2](g, g);
+}
+
+bool isSuccess(int[2] a) {
+ bool arrayCorrect = true;
+ for (int i = 0; i < 2; ++i) {
+ if (a[i] != 1) {
+ arrayCorrect = false;
+ }
+ }
+ return arrayCorrect;
+}
+
+void main() {
+ bool success = isSuccess(createArray());
+ my_FragColor = vec4(0.0, (success ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Arrays as return values should work");
+debug("");
+debug("This test is targeted to stress syntax tree transformations that might need to be done in shader translation when the platform doesn't natively support arrays as return values.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderReturnedArrayNotUsed',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is not used'
+},
+{
+ fShaderId: 'fshaderCompareReturnedArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is compared'
+},
+{
+ fShaderId: 'fshaderReturnReturnedArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is returned again'
+},
+{
+ fShaderId: 'fshaderReturnedArrayAsParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where a returned array is passed as a parameter'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html
new file mode 100644
index 0000000000..c47f3d7123
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html
@@ -0,0 +1,91 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array constructor assignment 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderNonConstantConstructorParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform int u;
+
+out vec4 my_FragColor;
+
+void main() {
+ // Test assigning a constructor result as opposed to initializing with a
+ // constructor result.
+ int a[3];
+ a = int[3](0, 1, u);
+ bool fail = false;
+ for (int i = 0; i < 2; ++i) {
+ if (a[i] != i) {
+ fail = true;
+ }
+ }
+ if (a[2] != u) {
+ fail = true;
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderArrayOfStructs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+struct S {
+ int foo;
+};
+
+void main() {
+ // Test assigning a constructor result as opposed to initializing with a
+ // constructor result.
+ S a[3];
+ a = S[3](S(0), S(1), S(2));
+ bool fail = false;
+ for (int i = 0; i < 3; ++i) {
+ if (a[i].foo != i) {
+ fail = true;
+ }
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Assigning return values of array constructors should work.");
+debug("");
+
+// This test only covers cases which are not covered by the dEQP tests.
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderNonConstantConstructorParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Assigning a constructor result',
+ uniforms: [{name: "u", functionName: "uniform1i", value: 5}]
+},
+{
+ fShaderId: 'fshaderArrayOfStructs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Assigning an array of structs'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html
new file mode 100644
index 0000000000..94c1507b29
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html
@@ -0,0 +1,93 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array assignment 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderSimple" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array assignment independently of array constructors.
+ int a[3];
+ int b[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i] = 0;
+ b[i] = i;
+ }
+ a = b;
+ bool fail = false;
+ for (int i = 0; i < 3; ++i) {
+ if (a[i] != i) {
+ fail = true;
+ }
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderArrayOfStructs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+struct S {
+ int foo;
+};
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array assignment independently of array constructors.
+ S a[3];
+ S b[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i].foo = 0;
+ b[i].foo = i;
+ }
+ a = b;
+ bool fail = false;
+ for (int i = 0; i < 3; ++i) {
+ if (a[i].foo != i) {
+ fail = true;
+ }
+ }
+ my_FragColor = vec4(0.0, (fail ? 0.0 : 1.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Assigning arrays should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSimple',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of integers'
+},
+{
+ fShaderId: 'fshaderArrayOfStructs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of structs'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html
new file mode 100644
index 0000000000..2ff9fa1c5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html
@@ -0,0 +1,87 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL Indexing complex array expressions</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!--
+Array indexing is detailed in the ESSL 3.00 spec section 5.9
+ESSL 3.00 revisions after 3.00.4 changed the definition from 'subscripted array names' to 'subscripted arrays'
+-->
+<script id="fshader-assignment" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+void main() {
+ float a[2] = float[2](0.0, 0.0);
+ float b[2] = float[2](2.0, 1.0);
+ float c = (a = b)[0];
+ color = (c == 2.0) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script id="fshader-function" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+bool hasRan = false;
+
+float[2] functionReturnArray() {
+ hasRan = true;
+ return float[2](2.0, 1.0);
+}
+
+void main() {
+ float c = (functionReturnArray())[0];
+ color = ((c == 2.0) && hasRan) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script id="fshader-array-initialization" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+void main() {
+ float a = (float[3](2.0, 1.0, 0.0))[0];
+ color = (a == 2.0) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Indexing complex array expressions");
+debug("");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader-assignment',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test indexing a variable assignment: (a = b)[0]'
+},
+{
+ fShaderId: 'fshader-function',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test indexing a function return with a side-effect: (functionReturnArray())[0]'
+},
+{
+ fShaderId: 'fshader-array-initialization',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test indexing an array initialization: (float[3](2.0, 1.0, 0.0))[0]'
+},
+], 2);
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html
new file mode 100644
index 0000000000..2a3e555472
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html
@@ -0,0 +1,131 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL initialized array element increment/decrement 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderFloatArrayIncrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ float A[2] = float[2](0.0, 1.0);
+ A[0]++;
+ my_FragColor = vec4(1.0 - A[0], A[0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorArrayIncrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 V[2] = vec4[2](vec4(0.0, 2.0, 3.0, 4.0), vec4(5.0, 6.0, 7.0, 8.0));
+ V[0][0]++;
+ my_FragColor = vec4(1.0 - V[0][0], V[0][0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorElementIncrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 v = vec4(0.0, 2.0, 3.0, 4.0);
+ v[0]++;
+ my_FragColor = vec4(1.0 - v[0], v[0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderFloatArrayDecrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ float A[2] = float[2](2.0, 1.0);
+ A[0]--;
+ my_FragColor = vec4(1.0 - A[0], A[0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorArrayDecrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 V[2] = vec4[2](vec4(2.0, 2.0, 3.0, 4.0), vec4(5.0, 6.0, 7.0, 8.0));
+ V[0][0]--;
+ my_FragColor = vec4(1.0 - V[0][0], V[0][0], 0.0, 1.0);
+}
+</script>
+<script id="fshaderVectorElementDecrement" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 v = vec4(2.0, 2.0, 3.0, 4.0);
+ v[0]--;
+ my_FragColor = vec4(1.0 - v[0], v[0], 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Incrementing or decrementing elements of arrays with initializers should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderFloatArrayIncrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Increment an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorArrayIncrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Increment an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorElementIncrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Increment an element of a vector'
+},
+{
+ fShaderId: 'fshaderFloatArrayDecrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Decrement an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorArrayDecrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Decrement an element of a vector array'
+},
+{
+ fShaderId: 'fshaderVectorElementDecrement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Decrement an element of a vector'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html
new file mode 100644
index 0000000000..dcffa2c0a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html
@@ -0,0 +1,240 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array equality 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderSimple" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array equality independently of array constructors.
+ int a[3];
+ int b[3];
+ int c[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i] = i;
+ b[i] = i;
+ c[i] = i + 1;
+ }
+ bool success = (a == b) && (a != c);
+ my_FragColor = vec4(0.0, (success ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderArrayOfStructs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+struct S {
+ int foo;
+};
+
+void main() {
+ // This simple test uses the ESSL1 style array initialization in order
+ // to be able to test array equality independently of array constructors.
+ S a[3];
+ S b[3];
+ S c[3];
+ for (int i = 0; i < 3; ++i) {
+ a[i].foo = i;
+ b[i].foo = i;
+ c[i].foo = i + 1;
+ }
+ bool success = (a == b) && (a != c);
+ my_FragColor = vec4(0.0, (success ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="simple-float-array-fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform float a[3];
+uniform float b[3];
+
+out vec4 fragColor;
+
+void main(void) {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (a == b) {
+ fragColor.g = 1.0;
+ }
+}
+</script>
+<script id="simple-vec-array-fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform vec3 a[3];
+uniform vec3 b[3];
+
+out vec4 fragColor;
+
+void main(void) {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (a == b) {
+ fragColor.g = 1.0;
+ }
+}
+</script>
+<script id="simple-mat-array-fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform mat3 a[3];
+uniform mat3 b[3];
+
+out vec4 fragColor;
+
+void main(void) {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+
+ if (a == b) {
+ fragColor.g = 1.0;
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Comparing arrays should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSimple',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of integers'
+},
+{
+ fShaderId: 'fshaderArrayOfStructs',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Arrays of structs'
+},
+{
+ fShaderId: "simple-float-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: "Simple float array with default values",
+},
+{
+ fShaderId: "simple-float-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ renderColor: [0, 0, 0, 255],
+ uniforms: [
+ { name: 'a', functionName: 'uniform1fv', value: [1, 2, 3]},
+ { name: 'b', functionName: 'uniform1fv', value: [1, 2, 4]},
+ ],
+ passMsg: "Simple float array with different values",
+},
+{
+ fShaderId: "simple-float-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ uniforms: [
+ { name: 'a', functionName: 'uniform1fv', value: [1, 2, 3]},
+ { name: 'b', functionName: 'uniform1fv', value: [1, 2, 3]},
+ ],
+ passMsg: "Simple float array with same values",
+},
+{
+ fShaderId: "simple-vec-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: "Simple vec array with default values",
+},
+{
+ fShaderId: "simple-vec-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ renderColor: [0, 0, 0, 255],
+ uniforms: [
+ { name: 'a', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 9]},
+ { name: 'b', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 10]},
+ ],
+ passMsg: "Simple vec array with different values",
+},
+{
+ fShaderId: "simple-vec-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ uniforms: [
+ { name: 'a', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 9]},
+ { name: 'b', functionName: 'uniform3fv', value: [1, 2, 3, 4, 5, 6, 7, 8, 9]},
+ ],
+ passMsg: "Simple vec array with same values",
+},
+{
+// "simple-mat-array-fs"
+ fShaderId: "simple-mat-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ passMsg: "Simple mat array with default values",
+},
+{
+ fShaderId: "simple-mat-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ renderColor: [0, 0, 0, 255],
+ uniforms: [
+ { name: 'a', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ ]},
+ { name: 'b', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 30, 39,
+ ]},
+ ],
+ passMsg: "Simple vec array with different values",
+},
+{
+ fShaderId: "simple-mat-array-fs",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ render: true,
+ uniforms: [
+ { name: 'a', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ ]},
+ { name: 'b', functionName: 'uniformMatrix3fv', value: [
+ 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ ]},
+ ],
+ passMsg: "Simple vec array with same values",
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html
new file mode 100644
index 0000000000..9e55a0a016
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html
@@ -0,0 +1,144 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array in complex expression 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderAndShortCircuits" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+bool minus() {
+ --g;
+ return false;
+}
+
+void main() {
+ int a[2] = int[2](0, 0);
+ // The function call must not be evaluated, since && short-circuits
+ minus() && (a == plus());
+ my_FragColor = vec4(0.0, ((g == -1) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderOrShortCircuits" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+bool minus() {
+ --g;
+ return true;
+}
+
+void main() {
+ int a[2] = int[2](0, 0);
+ // The function call must not be evaluated, since || short-circuits.
+ minus() || (a == plus());
+ my_FragColor = vec4(0.0, ((g == -1) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderTernaryOnlyEvaluatesOneOperand" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int g = 0;
+
+int[2] plus() {
+ ++g;
+ return int[2](g, g);
+}
+
+void main() {
+ int a[2] = int[2](0, 0);
+ // The function call must not be evaluated, since the condition is true.
+ (g == 0) ? true : (a == plus());
+ my_FragColor = vec4(0.0, ((g == 0) ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script id="fshaderSequenceSideEffectsAffectingComparedArrayContent" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int[2] func(int param) {
+ return int[2](param, param);
+}
+
+void main() {
+ int a[2];
+ for (int i = 0; i < 2; ++i) {
+ a[i] = 1;
+ }
+ int j = 0;
+ // Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9).
+ // The function call that returns the array needs to be evaluated after ++j
+ // for the expression to return the correct value (true).
+ bool result = ((++j), (a == func(j)));
+ my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Arrays in complex expressions should work");
+debug("");
+debug("This test is targeted to stress syntax tree transformations that might need to be done in shader translation when the platform doesn't natively support arrays as return values.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderAndShortCircuits',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Expression where an array is returned from a function call inside an operand to && that doesn't get evaluated as result of short-circuiting"
+},
+{
+ fShaderId: 'fshaderOrShortCircuits',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Expression where an array is returned from a function call inside an operand to || that doesn't get evaluated as result of short-circuiting"
+},
+{
+ fShaderId: 'fshaderTernaryOnlyEvaluatesOneOperand',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Expression where an array is returned from a function call in an operand of a ternary operator that doesn't get evaluated"
+},
+{
+ fShaderId: 'fshaderSequenceSideEffectsAffectingComparedArrayContent',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Expression where first operand of a sequence operator has side effects which affect the second operand that returns an array'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html
new file mode 100644
index 0000000000..cf81f84dd0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html
@@ -0,0 +1,48 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array initializer that references an array with the same name</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderInitArray" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ float foo[2] = float[2](1.0, 1.0);
+ {
+ float foo[2] = foo;
+ my_FragColor = vec4(0.0, foo[0], 0.0, foo[1]);
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Initializing an array with another array with the same name should work. See GLSL ES 3.00.6 section 4.2.2.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderInitArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Array that is initialized with an array of the same name from an outer scope'
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html
new file mode 100644
index 0000000000..fb32153c66
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html
@@ -0,0 +1,100 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL: test that length() method called on a complex expression works</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderLengthOfAssignment" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ int a[3] = int[3](1, 2, 3);
+ int b[3] = int[3](4, 5, 6);
+ int c = (a = b).length();
+ if (c == 3 && a[0] == 4 && a[1] == 5 && a[2] == 6) {
+ my_FragColor = vec4(0, 1, 0, 1);
+ } else {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script id="fshaderLengthOfFunctionCall" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+int sideEffectCounter = 0;
+
+int[2] func() {
+ ++sideEffectCounter;
+ int a[2];
+ return a;
+}
+
+void main() {
+ int b = (func()).length();
+ if (sideEffectCounter == 1 && b == 2) {
+ my_FragColor = vec4(0, 1, 0, 1);
+ } else {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script id="fshaderLengthOfConstructor" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+void main() {
+ int a = (int[1](0)).length();
+ if (a == 1) {
+ my_FragColor = vec4(0, 1, 0, 1);
+ } else {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+debug('length() method is allowed to be called on arbitrary expressions returning arrays. ESSL 3.00 section 5.9 says that length is allowed on "array names", but ESSL 3.20 has newer, clarified wording that says that it is allowed for "arrays". This was always the intent of the spec.');
+GLSLConformanceTester.runRenderTests([
+ {
+ fShaderId: "fshaderLengthOfAssignment",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Fragment shader which tries to evaluate the length of an assignment operation should succeed."
+ },
+ {
+ fShaderId: "fshaderLengthOfFunctionCall",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Fragment shader which tries to evaluate the length of a return value should succeed."
+ },
+ {
+ fShaderId: "fshaderLengthOfConstructor",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Fragment shader which tries to evaluate the length of a newly constructed array should succeed."
+ }
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html
new file mode 100644
index 0000000000..88af6137c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html
@@ -0,0 +1,368 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Verify uint(bool), ivec(bvec), and uvec(bvec) work correctly (Mac AMD driver bug)</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader-uint-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uint uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uint(bvalue);
+}
+</script>
+<script id="fshader-uint-1" type="x-shader/x-fragment">#version 300 es
+flat in uint uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == 0u)
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-uint-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uint uvalue = uint(bvalue);
+
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == 0u)
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-ivec2-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out ivec2 ivalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ ivalue = ivec2(bvec2(bvalue, bvalue));
+}
+</script>
+<script id="fshader-ivec2-1" type="x-shader/x-fragment">#version 300 es
+flat in ivec2 ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (ivalue == ivec2(1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec2(0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-ivec2-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ ivec2 ivalue = ivec2(bvec2(bvalue, bvalue));
+
+ if (ivalue == ivec2(1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec2(0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-uvec2-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uvec2 uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uvec2(bvec2(bvalue, bvalue));
+}
+</script>
+<script id="fshader-uvec2-1" type="x-shader/x-fragment">#version 300 es
+flat in uvec2 uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == uvec2(1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec2(0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-uvec2-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uvec2 uvalue = uvec2(bvec2(bvalue, bvalue));
+
+ if (uvalue == uvec2(1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec2(0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-ivec3-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out ivec3 ivalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ ivalue = ivec3(bvec3(bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-ivec3-1" type="x-shader/x-fragment">#version 300 es
+flat in ivec3 ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (ivalue == ivec3(1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec3(0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-ivec3-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ ivec3 ivalue = ivec3(bvec3(bvalue, bvalue, bvalue));
+
+ if (ivalue == ivec3(1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec3(0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-uvec3-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uvec3 uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uvec3(bvec3(bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-uvec3-1" type="x-shader/x-fragment">#version 300 es
+flat in uvec3 uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == uvec3(1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec3(0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-uvec3-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uvec3 uvalue = uvec3(bvec3(bvalue, bvalue, bvalue));
+
+ if (uvalue == uvec3(1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec3(0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-ivec4-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out ivec4 ivalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ ivalue = ivec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-ivec4-1" type="x-shader/x-fragment">#version 300 es
+flat in ivec4 ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (ivalue == ivec4(1, 1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec4(0, 0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-ivec4-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ ivec4 ivalue = ivec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+
+ if (ivalue == ivec4(1, 1, 1, 1))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (ivalue == ivec4(0, 0, 0, 0))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-uvec4-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out uvec4 uvalue;
+uniform bool bvalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uvec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+}
+</script>
+<script id="fshader-uvec4-1" type="x-shader/x-fragment">#version 300 es
+flat in uvec4 uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == uvec4(1u, 1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec4(0u, 0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="fshader-uvec4-2" type="x-shader/x-fragment">#version 300 es
+uniform bool bvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uvec4 uvalue = uvec4(bvec4(bvalue, bvalue, bvalue, bvalue));
+
+ if (uvalue == uvec4(1u, 1u, 1u, 1u))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (uvalue == uvec4(0u, 0u, 0u, 0u))
+ myFragColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("Verify uint(bool), ivec(bvec), and uvec(bvec) work correctly");
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-uint-1", fshader: "fshader-uint-1", desc: "vertex shader uint" },
+ { vshader: "vshader-simple", fshader: "fshader-uint-2", desc: "fragment shader uint" },
+ { vshader: "vshader-ivec2-1", fshader: "fshader-ivec2-1", desc: "vertex shader ivec2" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec2-2", desc: "fragment shader ivec2" },
+ { vshader: "vshader-uvec2-1", fshader: "fshader-uvec2-1", desc: "vertex shader uvec2" },
+ { vshader: "vshader-simple", fshader: "fshader-uvec2-2", desc: "fragment shader uvec2" },
+ { vshader: "vshader-ivec3-1", fshader: "fshader-ivec3-1", desc: "vertex shader ivec3" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec3-2", desc: "fragment shader ivec3" },
+ { vshader: "vshader-uvec3-1", fshader: "fshader-uvec3-1", desc: "vertex shader uvec3" },
+ { vshader: "vshader-simple", fshader: "fshader-uvec3-2", desc: "fragment shader uvec3" },
+ { vshader: "vshader-ivec4-1", fshader: "fshader-ivec4-1", desc: "vertex shader ivec4" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec4-2", desc: "fragment shader ivec4" },
+ { vshader: "vshader-uvec4-1", fshader: "fshader-uvec4-1", desc: "vertex shader uvec4" },
+ { vshader: "vshader-simple", fshader: "fshader-uvec4-2", desc: "fragment shader uvec4" },
+ ];
+
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+
+ debug("");
+ var program = wtu.setupProgram(gl, [test.vshader, test.fshader], ["aPosition"]);
+ if (!program) {
+ testFailed("Fail to set up program");
+ } else {
+ var uniformLoc = gl.getUniformLocation(program, 'bvalue');
+ debug("Testing " + test.desc + " with false");
+ gl.uniform1i(uniformLoc, 0);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255]);
+ debug("Testing " + test.desc + " with true");
+ gl.uniform1i(uniformLoc, 1);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+ gl.deleteProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from testing");
+ }
+ }
+};
+
+test();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html
new file mode 100644
index 0000000000..4748ae5153
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html
@@ -0,0 +1,86 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL array equality test with structs containing arrays</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!--
+Structure array comparisons are detailed in the ESSL 3.00 spec section 5.7
+-->
+<script id="fshader-same-struct" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+struct MyStruct {
+ bool a[2];
+};
+
+void main() {
+ MyStruct b;
+ b.a[0] = true;
+ b.a[1] = false;
+
+ MyStruct c;
+ c.a[0] = true;
+ c.a[1] = false;
+
+ color = b == c ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script id="fshader-different-struct" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+
+struct MyStruct {
+ bool a[2];
+};
+
+void main() {
+ MyStruct b;
+ b.a[0] = true;
+ b.a[1] = true;
+
+ MyStruct c;
+ c.a[0] = true;
+ c.a[1] = false;
+
+ color = b != c ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Comparing structs containing arrays should work.");
+debug("");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshader-same-struct',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Comparing two structs containing arrays with the same values should equal to each other'
+},
+{
+ fShaderId: 'fshader-different-struct',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Comparing two structs containing arrays with different values should not equal to each other'
+},
+], 2);
+
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html
new file mode 100644
index 0000000000..76d70efd7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Result type should match the l-value type in compound assignment</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+<script src="../../js/tests/compound-assignment-type-combination.js"></script>
+</head>
+<body onload="runTest(2)">
+<div id="description"></div>
+<div id="console"></div>
+<script type="application/javascript">
+description();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html
new file mode 100644
index 0000000000..c992c03b63
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html
@@ -0,0 +1,98 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Constant array initialization 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderGlobalConstArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+const vec4 constants[2] = vec4[] (
+ vec4(0.6, 0.3, 0.0, 3.0),
+ vec4(-0.6, 0.7, 0.0, -2.0)
+);
+
+void main()
+{
+ my_FragColor = constants[0] + constants[1];
+ return;
+}
+</script>
+<script id="fshaderGlobalConstArrayWithReferenceToConstArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+const vec4 constants[2] = vec4[] (
+ vec4(0.6, 0.3, 0.0, 3.0),
+ vec4(-0.6, 0.7, 0.0, -2.0)
+);
+
+const vec4 constants2[2] = vec4[] (
+ constants[1],
+ constants[0]
+);
+
+void main()
+{
+ my_FragColor = constants2[0] + constants2[1];
+ return;
+}
+</script>
+<script id="fshaderGlobalConstArrayInitializedToConstArray" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+
+const vec4 constants[2] = vec4[] (
+ vec4(0.6, 0.3, 0.0, 3.0),
+ vec4(-0.6, 0.7, 0.0, -2.0)
+);
+
+const vec4 constants2[2] = constants;
+
+void main()
+{
+ my_FragColor = constants2[0] + constants2[1];
+ return;
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test initializing a constant global array");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderGlobalConstArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Global constant array with vec4 constructors and literals in the initializer"
+},
+{
+ fShaderId: 'fshaderGlobalConstArrayWithReferenceToConstArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Global constant array which indexes another global constant array in the initializer"
+},
+{
+ fShaderId: 'fshaderGlobalConstArrayInitializedToConstArray',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Global constant array initialized to another global constant array"
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html
new file mode 100644
index 0000000000..e67e0e0dd5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html
@@ -0,0 +1,59 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL passing struct from a const array into a function parameter bug</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fShaderTest" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+struct S { float member; };
+
+const S s[2] = S[]( S(1.), S(2.));
+
+bool useStruct( S s) { return s.member > 0.0; }
+
+out vec4 outColor;
+
+void main( void )
+{
+ outColor = vec4(0.0, 0.0, 0.0, 1.0);
+ for (int i = 0; i < 2; ++i) {
+ if (useStruct(s[i])) {
+ outColor.g++;
+ }
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+// Covers bug:
+// http://crbug.com/871434
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fShaderTest',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Passing a struct from a dynamically indexed const array into a non-const function parameter should work.',
+ render: true
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html
new file mode 100644
index 0000000000..fcd4d8a731
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html
@@ -0,0 +1,167 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Float parsing corner cases</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderParsedFloatOverflowToInfinity" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float correct = isinf(1.0e40) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatUnderflowToZero" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero."
+ // 1.0e-50 is small enough that it can't even be stored as subnormal.
+ float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatSmallMantissa" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "There is no limit on the number of digits in any digit-sequence."
+ // The below float string has 100 zeros after the decimal point, but represents 1.0.
+ float x = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e101;
+ my_FragColor = vec4(0.0, x, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatLargeMantissa" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "There is no limit on the number of digits in any digit-sequence."
+ // The below float string has 100 zeros, but represents 1.0.
+ float x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0e-100;
+ my_FragColor = vec4(0.0, x, 0.0, 1.0);
+}
+</script>
+<script id="fshaderParsedFloatExponentAboveMaxInt" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float correct = isinf(1.0e2147483649) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderNonConstFloatIsInfinity" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+uniform float u; // Assumed to have the default value 0.0
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float f = 1.0e2048 - u;
+ float correct = (isinf(f) && f > 0.0) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script id="fshaderNonConstFloatIsNegativeInfinity" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+
+uniform float u; // Assumed to have the default value 0.0
+
+void main()
+{
+ // Out-of-range floats should overflow to infinity
+ // GLSL ES 3.00.6 section 4.1.4 Floats:
+ // "If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity"
+ float f = -1.0e2048 + u;
+ float correct = (isinf(f) && f < 0.0) ? 1.0 : 0.0;
+ my_FragColor = vec4(0.0, correct, 0.0, 1.0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderParsedFloatOverflowToInfinity',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Floats of too large magnitude should be converted infinity."
+},
+{
+ fShaderId: 'fshaderParsedFloatUnderflowToZero',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Floats of too small magnitude should be converted to zero."
+},
+{
+ fShaderId: 'fshaderParsedFloatSmallMantissa',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Number of digits in any digit-sequence is not limited - test with a small mantissa and large exponent."
+},
+{
+ fShaderId: 'fshaderParsedFloatLargeMantissa',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Number of digits in any digit-sequence is not limited - test with a large mantissa and negative exponent."
+},
+{
+ fShaderId: 'fshaderParsedFloatExponentAboveMaxInt',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Test that an exponent that slightly overflows signed 32-bit int range works."
+},
+{
+ fShaderId: 'fshaderNonConstFloatIsInfinity',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Test that a non-constant float that has infinity as a value is processed correctly by isinf()."
+},
+{
+ fShaderId: 'fshaderNonConstFloatIsNegativeInfinity',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "Test that a non-constant float that has negative infinity as a value is processed correctly by isinf()."
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html
new file mode 100644
index 0000000000..ec5c7c9bfb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html
@@ -0,0 +1,124 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests - Unsupported variants of operators</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshader-array-ternary-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void main()
+{
+ float a[3];
+ float b[3];
+ float c[3] = true ? a : b;
+}
+</script>
+<script id="fshader-struct-array-ternary-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+struct MyStruct {
+ bool a[3];
+};
+
+void main()
+{
+ MyStruct b;
+ MyStruct c;
+ MyStruct d = true ? b : c;
+}
+</script>
+<script id="fshader-void-ternary-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void foo() {}
+
+void main()
+{
+ true ? foo() : foo();
+}
+</script>
+<script id="fshader-array-sequence-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void main()
+{
+ float a[3];
+ float b[3] = (true, a);
+}
+</script>
+<script id="fshader-struct-array-sequence-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+struct MyStruct {
+ bool a[3];
+};
+
+void main()
+{
+ MyStruct b;
+ MyStruct c = (true, b);
+}
+</script>
+<script id="fshader-void-sequence-operator" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+void foo() {}
+
+void main()
+{
+ (foo(), foo());
+}
+</script>
+<script>
+"use strict";
+description("Check unsupported variants of operators.");
+
+// WebGL 2.0 spec section "Unsupported variants of GLSL ES 3.00 operators"
+
+GLSLConformanceTester.runTests([
+{ fShaderId: 'fshader-array-ternary-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using ternary operators with arrays is not allowed",
+},
+{ fShaderId: 'fshader-struct-array-ternary-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using ternary operators with structs containing arrays is not allowed",
+},
+{ fShaderId: 'fshader-void-ternary-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using ternary operators with void is not allowed",
+},
+{ fShaderId: 'fshader-array-sequence-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using sequence operators with arrays is not allowed",
+},
+{ fShaderId: 'fshader-struct-array-sequence-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using sequence operators with structs containing arrays is not allowed",
+},
+{ fShaderId: 'fshader-void-sequence-operator',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Using sequence operators with void is not allowed",
+}
+], 2);
+
+debug("");
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html
new file mode 100644
index 0000000000..b3afcb846d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html
@@ -0,0 +1,90 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL 3.00 forward declaration 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShaderForwardDecl" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+
+// Forward declaration. Breaks on Pixel C due to flattening of
+// precision qualifiers. It seems the GLSL compiler can't handle the
+// precision qualifier on the return value.
+float identity(float val);
+
+float identity(float val) {
+ return val;
+}
+
+void main(void) {
+ gl_Position = vec4(identity(1.0), 0.0, 0.0, 1.0);
+}
+</script>
+<script id="vertexShader" type="x-shader/x-vertex">#version 300 es
+void main(void) {
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+void main(void) {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="fragmentShaderForwardDecl" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+// Forward declaration. Breaks on Pixel C due to flattening of
+// precision qualifiers. It seems the GLSL compiler can't handle the
+// precision qualifier on the return value.
+float identity(float val);
+
+float identity(float val) {
+ return val;
+}
+
+out vec4 my_FragColor;
+void main(void) {
+ my_FragColor = vec4(0.0, identity(1.0), 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Forward declarations of functions should succeed.");
+
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vertexShaderForwardDecl",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with forward declaration must pass",
+ },
+ {
+ vShaderId: "vertexShader",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderForwardDecl",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "fragment shader with forward declaration must pass",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html
new file mode 100644
index 0000000000..afbbfad741
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html
@@ -0,0 +1,157 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing fragment depth writing -->
+
+<!-- Shader omitting the required #version -->
+<script id="fragmentShaderESSL1" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 1.0;
+}
+</script>
+<!-- Shader with required #version -->
+<script id="fragmentShaderESSL3" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = 1.0;
+}
+</script>
+<!-- Shader using the EXT suffix -->
+<script id="fragmentShaderESSL3EXT" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepthEXT = 1.0;
+}
+</script>
+<!-- Shaders to link with test fragment shaders -->
+<script id="vertexShaderESSL1" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+<script id="vertexShaderESSL3" type="x-shader/x-vertex">#version 300 es
+in vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+
+<!-- Shader to test output -->
+<script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform float uDepth;
+
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragDepth = uDepth;
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies the functionality of setting fragment depth in a shader.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runShaderTests();
+ debug("");
+ runOutputTests();
+}
+
+function runShaderTests() {
+ debug("");
+ debug("Testing various shader compiles");
+
+ // Always expect ESSL1 shaders to fail
+ var fragmentProgramESSL1 = wtu.loadProgramFromScriptExpectError(gl, "vertexShaderESSL1", "fragmentShaderESSL1");
+ if (fragmentProgramESSL1) {
+ testFailed("gl_FragDepth allowed in ESSL1 shader - should be disallowed");
+ } else {
+ testPassed("gl_FragDepth disallowed in ESSL1 shader");
+ }
+
+ // Try to compile a shader using the built-ins that should only succeed if enabled
+ var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "vertexShaderESSL3", "fragmentShaderESSL3");
+ if (testFragmentProgram) {
+ testPassed("gl_FragDepth allowed in ESSL3 shader");
+ } else {
+ testFailed("gl_FragDepth disallowed in ESSL3 shader");
+ }
+
+ var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "vertexShaderESSL3", "fragmentShaderESSL3EXT");
+ if (testFragmentProgram) {
+ testFailed("gl_FragDepthEXT allowed in ESSL3 shader - should only allow gl_FragDepth");
+ } else {
+ testPassed("gl_FragDepthEXT disallowed in ESSL3 shader");
+ }
+}
+
+function runOutputTests() {
+ debug("Testing rendering results from writing to gl_FragData");
+
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+
+ // Enable depth testing with a clearDepth of 0.5
+ // This makes it so that fragments are only rendered when
+ // gl_FragDepth is < 0.5
+ gl.clearDepth(0.5);
+ gl.enable(gl.DEPTH_TEST);
+
+ var positionLoc = 0;
+ var texcoordLoc = 1;
+ var program = wtu.setupProgram(gl, ["vertexShaderESSL3", "outputFragmentShader"], ['vPosition'], [0]);
+ var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+ var depthUniform = gl.getUniformLocation(program, "uDepth");
+
+ // Draw 1: Greater than clear depth
+ gl.uniform1f(depthUniform, 1.0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 255, 255, 255]);
+
+ // Draw 2: Less than clear depth
+ gl.uniform1f(depthUniform, 0.0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html
new file mode 100644
index 0000000000..a171b94e26
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html
@@ -0,0 +1,72 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Fragment shader containing loop should not crash</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+precision highp float;
+out vec2 v_tex_coord;
+uniform mat4 matrix;
+
+void main() {
+ v_tex_coord = vec2(0.0, 0.0);
+ gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+
+in vec2 v_tex_coord;
+out vec4 out_color;
+
+uniform sampler2D texture_1;
+uniform vec2 resolution;
+
+vec4 do_loops(vec4 z)
+{
+ vec4 v[16];
+ for (int i = 0; i < 16; i++)
+ {
+ v[i] = z;
+ }
+ return v[1];
+}
+
+void main() {
+ out_color = do_loops(vec4(0.2, 0.4, 0.6, 1.0)) - texture(texture_1, v_tex_coord);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+const wtu = WebGLTestUtils;
+const tests = [
+ {
+ vShaderSource: wtu.getScript('vshader'),
+ fShaderSource: wtu.getScript('fshader'),
+ vShaderSuccess: true,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Fragment shader containing a simple loop should compile and link'
+ }
+];
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html
new file mode 100644
index 0000000000..db13d61f6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html
@@ -0,0 +1,75 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Short circuit in loop condition 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertex-shader" type="x-shader/x-vertex">#version 300 es
+ precision highp float;
+ in vec4 aPosition;
+
+ void main() {
+ gl_Position = aPosition;
+ }
+</script>
+<script id="fragment-shader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+precision highp int;
+
+uniform vec4 iMouse;
+uniform sampler2D iChannel0;
+
+float map(float p)
+{
+ return texture(iChannel0, vec2(p, p), 0.0).y;
+}
+
+out vec4 outColor;
+
+void main(void)
+{
+ float sum = 0.0;
+
+ for(int i=0; i<1000; i++)
+ {
+ if( sum > 0.99 ) break;
+ float p = iMouse.x + gl_FragCoord.x;
+ sum = map(p);
+ }
+
+ outColor = vec4(sum);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test an HLSL compiler freeze on a gradient inside a discontinuous loop.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+wtu.setupUnitQuad(gl);
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ var program = wtu.setupProgram(gl, ["vertex-shader", "fragment-shader"], ['aPosition'], undefined, true);
+ if (!program) {
+ testFailed('Program compilation failed');
+ }
+}
+var successfullyParsed = true;
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html
new file mode 100644
index 0000000000..fa6d87cd12
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html
@@ -0,0 +1,83 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Negative tests for writting to a shader input with interpolation qualifier</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!--
+According to ESSL 3.00.6 section 4.3.4:
+"Variables declared as in or centroid in may not be written to during shader execution.",
+these tests ensure that a compile error is generated when using a shader input with interpolation qualifier as l-value.
+-->
+<script type="application/javascript">
+"use strict";
+description();
+
+var vertexShaderTemplate = [
+ '#version 300 es',
+ '$(InterpolationQualifier) out float v_float_varying;',
+ 'void main()',
+ '{',
+ ' v_float_varying = 1.0;',
+ ' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);',
+ '}'
+].join('\n');
+
+var fragmentShaderTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ '$(InterpolationQualifier) in float v_float_varying;',
+ 'out vec4 my_color;',
+ 'void main()',
+ '{',
+ ' v_float_varying = 1.0;',
+ ' my_color = vec4(1.0, 0.0, 0.0, v_float_varying);',
+ '}'
+].join('\n');
+
+var errorMessageTemplate = "Writting to shader inputs with '$(InterpolationQualifier)' qualifier must fail";
+
+var testDataList = [
+{
+ InterpolationQualifier: 'flat'
+},
+{
+ InterpolationQualifier: 'smooth'
+},
+{
+ InterpolationQualifier: 'centroid'
+}
+];
+
+var wtu = WebGLTestUtils;
+
+var tests = [];
+for (var i = 0; i < testDataList.length; ++i) {
+ tests.push({
+ vShaderSource: wtu.replaceParams(vertexShaderTemplate, testDataList[i]),
+ vShaderSuccess: true,
+ fShaderSource: wtu.replaceParams(fragmentShaderTemplate, testDataList[i]),
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: wtu.replaceParams(errorMessageTemplate, testDataList[i])
+ });
+}
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html
new file mode 100644
index 0000000000..375c95610c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html
@@ -0,0 +1,71 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Default precision qualifiers should only work with int, float and sampler types</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!-- See ESSL 3.00 section 4.5.4 -->
+<script id="precisionVec" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+precision mediump vec2;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="precisionVoid" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+precision mediump void;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="precisionUint" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+precision mediump uint;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ fShaderId: "precisionVec",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "default precision qualifier shouldn't work with vec2"
+ },
+ {
+ fShaderId: "precisionVoid",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "default precision qualifier shouldn't work with void"
+ },
+ {
+ fShaderId: "precisionUint",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "default precision qualifier shouldn't work with uint"
+ }
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html
new file mode 100644
index 0000000000..f0d2b46ad1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html
@@ -0,0 +1,88 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Negative tests for the use of the invariant qualifier and pragma</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShaderInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+invariant out vec4 v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="fragmentShaderVariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+
+in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script id="fragmentShaderInputInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+
+invariant in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script id="fragmentShaderGlobalInvariant" type="text/something-not-javascript">#version 300 es
+#pragma STDGL invariant(all)
+precision mediump float;
+
+in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vertexShaderInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderGlobalInvariant",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "fragment shader with global invariant pragma must fail",
+ },
+ {
+ vShaderId: "vertexShaderInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderInputInvariant",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "fragment shader with an input variable which is invariant must fail",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html
new file mode 100644
index 0000000000..c8a977b8ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html
@@ -0,0 +1,211 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Loops and side-effects 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+
+<!-- Variations on counter functions that used to give incorrect result on OSX 10.9 -->
+<script id="counter0" type="x-shader/x-shader">
+bool s0 = false;
+while(true) {
+ bool bar = s0;
+ if (!bar) {
+ bar = i < 3;
+ i = i + 1;
+ }
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter1" type="x-shader/x-shader">
+while(true) {
+ bool bar = i < 3;
+ i = i + 1;
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ n ++;
+}
+return n;
+</script>
+<script id="counter2" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ bool bar = s0;
+ if (!bar) {
+ bar = i < 3;
+ i = i + 1;
+ }
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter3" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ bool bar = s0;
+ if (!bar) {
+ bar = i++ < 3;
+ }
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter4" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ bool bar = s0 || (i++ < 3);
+ bool foo = !bar;
+ if (foo) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter5" type="x-shader/x-shader">
+bool s0 = true;
+while(true) {
+ if (!(s0 || (i++ < 3))) {
+ break;
+ }
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+<script id="counter6" type="x-shader/x-shader">
+bool s0 = true;
+while(s0 || (i++ < 3)) {
+ s0 = false;
+ n ++;
+}
+return n;
+</script>
+
+<script id="counter7" type="x-shader/x-shader">
+do {
+ n++;
+} while (i++ < 3);
+return n;
+</script>
+<script>
+"use strict";
+description("This test checks for bugs related to loops and side-effects.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ for (var i = 0; i < 8; i++) {
+ tryCounter(document.getElementById("counter" + i).text);
+ debug("");
+ }
+}
+
+function evaluateCounter(source) {
+ var jsSource = "(function(n, i) {" +
+ source.split("bool").join("var") +
+ "})(0, 0)";
+
+ return eval(jsSource);
+}
+
+function makeFSSource(source) {
+ var fsSource =
+ "#version 300 es\n" +
+ "precision highp float;\n" +
+ "in float vertexCounter;\n" +
+ "uniform int uVertZero;\n" +
+ "uniform int uReference;\n" +
+ "out vec4 fragColor;\n" +
+ "int counter(int n, int i) {\n" +
+ source +
+ "}\n" +
+ "void main() {\n" +
+ " fragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" +
+ " fragColor.r = float(counter(uVertZero, uVertZero) == uReference);\n" +
+ " fragColor.g = float(int(vertexCounter) == uReference);\n" +
+ "}\n";
+ return fsSource;
+}
+
+function makeVSSource(source) {
+ var vsSource =
+ "#version 300 es\n" +
+ "out float vertexCounter;\n" +
+ "uniform int uFragZero;\n" +
+ "in vec4 vPosition;\n" +
+ "int counter(int n, int i) {\n" +
+ source +
+ "}\n" +
+ "void main() {\n" +
+ " gl_Position = vPosition;\n" +
+ " vertexCounter = float(counter(uFragZero, uFragZero));\n" +
+ "}\n";
+ return vsSource;
+}
+
+function tryCounter(source) {
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ var program = wtu.setupProgram(gl, [makeVSSource(source), makeFSSource(source)], ['vPosition'], [0], true);
+
+ gl.uniform1i(gl.getUniformLocation(program, "uVertZero"), 0);
+ gl.uniform1i(gl.getUniformLocation(program, "uFragZero"), 0);
+
+ var reference = evaluateCounter(source);
+ gl.uniform1i(gl.getUniformLocation(program, "uReference"), reference);
+
+ gl.useProgram(program);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 0]);
+ wtu.checkCanvas(gl, [255, 255, 0, 255]);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html
new file mode 100644
index 0000000000..ec6a9bbd1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html
@@ -0,0 +1,118 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Dynamically-indexed row-major 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderIndexRowMajorMatrixArrayInUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+layout(row_major) uniform a {
+ mat4 u_mats[1];
+};
+
+void main() {
+ float f = u_mats[u_zero + 0][2][1];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderRowMatrixIndexedByRowMatrixInUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+uniform Stuff {
+ layout(row_major) mat4 u_mat[3];
+ layout(row_major) mat4 u_ndx[3];
+} stuff;
+
+
+out vec4 my_FragColor;
+
+void main() {
+ vec4 row = stuff.u_mat[int(stuff.u_ndx[1][1][3])][2];
+ my_FragColor = row == vec4(9, 10, 11, 12) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Indexing row-major matrices within a uniform block should work");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderIndexRowMajorMatrixArrayInUniformBlock',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: '',
+ uniformBlocks: [{name: "a", value: new Float32Array([
+ 0, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ ])}],
+},
+{
+ fShaderId: 'fshaderRowMatrixIndexedByRowMatrixInUniformBlock',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: '',
+ uniformBlocks: [{name: "Stuff", value: new Float32Array([
+ // mat4 u_mat[3]
+ 1, 2, 3, 4,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12,
+ 13, 14, 15, 16,
+
+ // +-- we should be pulling out this column
+ // |
+ // V
+ 1, 5, 9, 13,
+ 2, 6, 10, 14,
+ 3, 7, 11, 15,
+ 4, 8, 12, 16,
+
+ 2, 10, 18, 22,
+ 4, 12, 20, 28,
+ 6, 14, 22, 30,
+ 8, 16, 24, 32,
+
+ // mat4 u_ndx[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,
+ 0, 1, 0, 0,
+ // ^
+ // |
+ // +-- we should be reading this value as an index into u_mat
+
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ ])}],
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html
new file mode 100644
index 0000000000..3c56bdacf1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html
@@ -0,0 +1,51 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Row-major 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderUniformMatrixRowMajor" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out highp vec4 my_FragColor;
+layout(std140, row_major) uniform b {
+ mat4x3 m;
+};
+void main() {
+ // If the matrix is interpreted as row-major, then the translation components will be 0,1,0, or solid green.
+ my_FragColor = mat4(m) * vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Row-major matrix layouts should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderUniformMatrixRowMajor',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: '',
+ uniformBlocks: [{name: "b", value: new Float32Array([
+ 0, 0, 0, 0, // Red
+ 0, 0, 0, 1, // Green
+ 0, 0, 0, 0, // Blue
+ ])}]
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html
new file mode 100644
index 0000000000..e0168c5830
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html
@@ -0,0 +1,111 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>#version directive should be on the very first line of a OpenGL ES Shading Language 3.00 shader</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!-- Version directive should be on the very first line in ESSL 3, see ESSL 3 section 3.3 -->
+<script id="VertexShaderCommentBeforeVersion" type="x-shader/x-vertex">// This shader is wrong, this is the first line that should have version
+#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="VertexShaderNewlineBeforeVersion" type="x-shader/x-vertex">
+#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="CorrectVertexShader" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="FragmentShaderCommentBeforeVersion" type="x-shader/x-fragment">// This shader is wrong, this is the first line that should have version
+#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="FragmentShaderNewlineBeforeVersion" type="x-shader/x-fragment">
+#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="CorrectFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "VertexShaderNewlineBeforeVersion",
+ vShaderSuccess: false,
+ fShaderId: "CorrectFragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Vertex shader with a newline before the version directive should fail."
+ },
+ {
+ vShaderId: "VertexShaderCommentBeforeVersion",
+ vShaderSuccess: false,
+ fShaderId: "CorrectFragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Vertex shader with a comment before the version directive should fail."
+ },
+ {
+ vShaderId: "CorrectVertexShader",
+ vShaderSuccess: true,
+ fShaderId: "FragmentShaderCommentBeforeVersion",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Fragment shader with a comment before the version directive should fail."
+ },
+ {
+ vShaderId: "CorrectVertexShader",
+ vShaderSuccess: true,
+ fShaderId: "FragmentShaderNewlineBeforeVersion",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "Fragment shader with a newline before the version directive should fail."
+ }
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html
new file mode 100644
index 0000000000..eabbd9779d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html
@@ -0,0 +1,63 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test no attribute vertex shaders</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertex-shader" type="x-shader/x-vertex">#version 300 es
+
+void main() {
+ ivec2 xy = ivec2(
+ gl_VertexID % 2,
+ (gl_VertexID / 2 + gl_VertexID / 3) % 2);
+ gl_Position = vec4(vec2(xy) * 2. - 1., 0, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 result;
+void main() {
+ result = vec4(0, 1, 0, 1);
+}
+</script>
+<script>
+"use strict";
+description("Test no attribute shaders work as expected");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+function test() {
+ debug("");
+ var program = wtu.setupProgram(gl, ["vertex-shader", "fshader"], undefined, undefined, true);
+ if (!program) {
+ testFailed('Program compilation failed');
+ return;
+ }
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 0);
+};
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ test();
+}
+var successfullyParsed = true;
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html
new file mode 100644
index 0000000000..c717c4ee94
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html
@@ -0,0 +1,125 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Verify precision side effects (Adreno driver bug)</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1.0);
+}
+</script>
+<script id="fshader-int" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp int t;
+ t = 0 | (int(t == t) * 0x8000);
+
+ if (t == 0x8000)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshader-ivec2" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp ivec2 t;
+ t = 0 | (ivec2(t == t) * 0x8000);
+
+ if (t == ivec2(0x8000))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshader-ivec3" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp ivec3 t;
+ t = 0 | (ivec3(t == t) * 0x8000);
+
+ if (t == ivec3(0x8000))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script id="fshader-ivec4" type="x-shader/x-fragment">#version 300 es
+out highp vec4 myFragColor;
+void main() {
+ highp ivec4 t;
+ t = 0 | (ivec4(t == t) * 0x8000);
+
+ if (t == ivec4(0x8000))
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Verify precision side effects");
+debug("");
+debug("When this test is run on Adreno (no repros on other vendors so far):");
+debug(" - the result of the expression 0 | (int(e0 == e0) * 0x8000) somehow returns -32768 instead of 32768 despite the variable using highp precision;");
+debug(" - splitting the expression along | fixes the issue (could also be observed with other operators).");
+debug('For additional reference see this <a href="https://github.com/KhronosGroup/WebGL/pull/3192">pull request</a> and <a href="http://crbug.com/1155942">Chromium bug</a>');
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-simple", fshader: "fshader-int", desc: "fragment shader int" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec2", desc: "fragment shader ivec2" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec3", desc: "fragment shader ivec3" },
+ { vshader: "vshader-simple", fshader: "fshader-ivec4", desc: "fragment shader ivec4" },
+ ];
+
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+
+ debug("");
+ var program = wtu.setupProgram(gl, [test.vshader, test.fshader], ["aPosition"]);
+ if (!program) {
+ testFailed("Fail to set up program");
+ } else {
+ debug("Testing " + test.desc);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+ gl.deleteProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from testing");
+ }
+ }
+};
+
+test();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html
new file mode 100644
index 0000000000..691523aea0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html
@@ -0,0 +1,66 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Shader identified as containing reciprocal square root of sum of squares should not crash</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+void main() {
+ gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+
+#define CRASH 1
+
+out vec4 fragmentColor;
+void main()
+{
+ vec2 p = gl_FragCoord.xy;
+ // This expression meets the requirement of being the reciprocal
+ // square root of a sum of squares.
+ float d = 1.0 / length(p);
+#if CRASH
+ if (p.x > 0.0)
+ {
+ d *= 2.0;
+ }
+#endif
+ fragmentColor = vec4(d);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+debug('Regression test for <a href="https://crbug.com/1079309">crbug.com/1079309</a>');
+const wtu = WebGLTestUtils;
+const tests = [
+ {
+ vShaderSource: wtu.getScript('vshader'),
+ fShaderSource: wtu.getScript('fshader'),
+ vShaderSuccess: true,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Shader containing expression that driver recognizes as reciprocal square root of sum of squares should compile and link'
+ }
+];
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html
new file mode 100644
index 0000000000..f2f124873b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html
@@ -0,0 +1,94 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>ESSL300 sampler array indexing rules</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vs" type="text/plain">#version 300 es
+void main() {}
+</script>
+<script id="fs_constant_integer_expression" type="text/plain">#version 300 es
+precision mediump float;
+uniform sampler2D u_tex[2];
+
+void main()
+{
+ texture(u_tex[0], vec2(0));
+ texture(u_tex[1], vec2(0));
+}
+</script>
+<script id="fs_constant_index_expression" type="text/plain">#version 300 es
+precision mediump float;
+uniform sampler2D u_tex[2];
+
+void main()
+{
+ for (int i = 0; i < 2; i++) {
+ texture(u_tex[i], vec2(0));
+ }
+}
+</script>
+<script id="fs_constant_integer_expression_switch" type="text/plain">#version 300 es
+precision mediump float;
+uniform sampler2D u_tex[2];
+
+void main()
+{
+ for (int i = 0; i < 2; i++) {
+ switch (i) {
+ case 0:
+ texture(u_tex[0], vec2(0));
+ break;
+ case 1:
+ texture(u_tex[1], vec2(0));
+ break;
+ }
+ }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vs",
+ vShaderSuccess: true,
+ fShaderId: "fs_constant_integer_expression",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "indexing into an array of samplers with constant-integer-expression is required",
+ },
+ {
+ vShaderId: "vs",
+ vShaderSuccess: true,
+ fShaderId: "fs_constant_index_expression",
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: "indexing into an array of samplers with constant-index-expression is forbidden in essl300",
+ },
+ {
+ vShaderId: "vs",
+ vShaderSuccess: true,
+ fShaderId: "fs_constant_integer_expression_switch",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "constant-index-expression can be converted into fs_constant_integer_expression via a switch",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html
new file mode 100644
index 0000000000..8205fa5c25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html
@@ -0,0 +1,88 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL sampler with no precision qualifier 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshaderSamplerNoPrecision" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+
+uniform $(samplerType) u_sampler;
+
+void main() {
+ gl_Position = vec4(0.0);
+}
+</script>
+<script id="fshaderSamplerNoPrecision" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform $(samplerType) u_sampler;
+
+void main() {
+ my_FragColor = vec4(0.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("ESSL3 sampler with no precision qualifier should not compile.");
+
+var wtu = WebGLTestUtils;
+
+var fragmentShaderTemplate = wtu.getScript('fshaderSamplerNoPrecision');
+var vertexShaderTemplate = wtu.getScript('vshaderSamplerNoPrecision');
+
+// ESSL 3.00.4 section 4.5.4 types with no predefined precision.
+var samplerTypes = [
+ 'sampler3D',
+ 'samplerCubeShadow',
+ 'sampler2DShadow',
+ 'sampler2DArray',
+ 'sampler2DArrayShadow',
+ 'isampler2D',
+ 'isampler3D',
+ 'isamplerCube',
+ 'isampler2DArray',
+ 'usampler2D',
+ 'usampler3D',
+ 'usamplerCube',
+ 'usampler2DArray'
+];
+
+var tests = [];
+
+for (var i = 0; i < samplerTypes.length; ++i) {
+ var type = samplerTypes[i];
+ var vertexShaderSrc = wtu.replaceParams(vertexShaderTemplate, {'samplerType': type});
+ tests.push({
+ vShaderSource: vertexShaderSrc,
+ vShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Vertex shader with a ' + type + ' uniform with no precision qualifier should not compile'
+ });
+ var fragmentShaderSrc = wtu.replaceParams(fragmentShaderTemplate, {'samplerType': type});
+ tests.push({
+ fShaderSource: fragmentShaderSrc,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Fragment shader with a ' + type + ' uniform with no precision qualifier should not compile'
+ });
+}
+
+GLSLConformanceTester.runTests(tests, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html
new file mode 100644
index 0000000000..d5d0e5eb71
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html
@@ -0,0 +1,59 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Sequence operator returns non-constant 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!--
+Sequence operator and non-constant expressions are detailed in the ESSL 3.00 spec section 12.43
+-->
+<script id="fshader-non-const-expression" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+void main() {
+ const float a = (0.0, 1.0);
+}
+</script>
+<script id="fshader-non-const-expression-as-array-size" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+void main() {
+ float a[(2, 3)];
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Checks sequence operators returning non-constants and cannot be used as an array size.");
+debug("");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshader-non-const-expression',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Sequence operator cannot return a constant expression'
+},
+{
+ fShaderId: 'fshader-non-const-expression-as-array-size',
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Sequence operator return value cannot be used as an array size'
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html
new file mode 100644
index 0000000000..6210e0577b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html
@@ -0,0 +1,84 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>OpenGL ES Shading Language 1.00 and OpenGL ES Shading Language 3.00 shaders should not link with each other</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="ES3VertexShader" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+in vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="ES3FragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="ESSL1VertexShader" type="x-shader/x-vertex">
+precision mediump float;
+attribute vec4 aPosition;
+
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+<script id="ESSL1FragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+// See OpenGL ES Shading Language 3.00 spec section 1.5 or 3.3
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "OpenGL ES Shading Language 3.00 vertex shader should link with OpenGL ES Shading Language 3.00 fragment shader."
+ },
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ESSL1FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "OpenGL ES Shading Language 3.00 vertex shader should not link with OpenGL ES Shading Language 1.00 fragment shader."
+ },
+ {
+ vShaderId: "ESSL1VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "OpenGL ES Shading Language 1.00 vertex shader should not link with OpenGL ES Shading Language 3.00 fragment shader."
+ }
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html
new file mode 100644
index 0000000000..5494c46dcd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html
@@ -0,0 +1,37 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL GLSL Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShader" type="text/something-not-javascript">
+// vertex shader that uses backlash character in comments should succeed
+// This is a li\ne wi\th backlash \\ characters \
+in comments
+
+void main()
+{
+ gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+GLSLConformanceTester.runTest();
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html
new file mode 100644
index 0000000000..2bf41a3825
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html
@@ -0,0 +1,59 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL mis-matching uniform block</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader-uniform-block-precision" type="text/something-not-javascript">#version 300 es
+uniform Block {
+ mediump vec4 val;
+};
+
+void main()
+{
+ gl_Position = val;
+}
+</script>
+<script id="fshader-uniform-block-precision" type="text/something-not-javascript">#version 300 es
+uniform Block {
+ highp vec4 val;
+};
+
+out highp vec4 out_FragColor;
+void main()
+{
+ out_FragColor = val;
+}
+</script>
+<script>
+"use strict";
+description("Shaders with precision mis-matching uniform blocks should fail");
+
+GLSLConformanceTester.runTests([
+{
+ vShaderId: 'vshader-uniform-block-precision',
+ vShaderSuccess: true,
+ fShaderId: 'fshader-uniform-block-precision',
+ fShaderSuccess: true,
+ linkSuccess: false,
+ passMsg: "Shaders with precision mis-matching uniform blocks should fail"
+},
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html
new file mode 100644
index 0000000000..802d67aa4a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html
@@ -0,0 +1,180 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Short circuit in loop condition 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderWhile" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ int iterations = 0;
+
+ while(u && foo()) {
+ ++iterations;
+ if (iterations >= 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderForCondition" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ for(int iterations = 0; u && foo();) {
+ ++iterations;
+ if (iterations >= 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderFor" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ for(int iterations = 0; true; u && foo()) {
+ ++iterations;
+ if (iterations > 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderDoWhile" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ int iterations = 0;
+
+ do {
+ ++iterations;
+ if (iterations > 10) {
+ break;
+ }
+ } while (u && foo());
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script id="fshaderSequence" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform bool u;
+out vec4 result;
+int sideEffectCounter;
+
+bool foo() {
+ ++sideEffectCounter;
+ return true;
+}
+
+void main() {
+ sideEffectCounter = 0;
+ int iterations = 0;
+
+ while(u, u && foo()) {
+ ++iterations;
+ if (iterations >= 10) {
+ break;
+ }
+ }
+
+ bool success = (u && sideEffectCounter == 10) || (!u && sideEffectCounter == 0);
+ result = success ? vec4(0, 1.0, 0, 1.0) : vec4(0, 1.0, 0, 0);
+}
+</script>
+<script type="text/javascript">
+"use strict";
+description("Test behavior of a short-circuiting operator in a loop using a function call with side effects");
+
+var testShaders = [
+ {fShaderId: 'fshaderWhile', description: 'in while loop condition'},
+ {fShaderId: 'fshaderForCondition', description: 'in for loop condition'},
+ {fShaderId: 'fshaderFor', description: 'in for loop expression'},
+ {fShaderId: 'fshaderDoWhile', description: 'in do-while loop condition'},
+ {fShaderId: 'fshaderSequence', description: 'inside a sequence in while loop condition'}
+];
+
+var testList = [];
+
+for (var i = 0; i < testShaders.length; ++i) {
+ testList.push({
+ fShaderId: testShaders[i].fShaderId,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Short-circuiting operator with a true condition ' + testShaders[i].description,
+ uniforms: [{name: "u", functionName: "uniform1i", value: 1}]
+ });
+ testList.push({
+ fShaderId: testShaders[i].fShaderId,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Short-circuiting operator with a false condition ' + testShaders[i].description,
+ uniforms: [{name: "u", functionName: "uniform1i", value: 0}]
+ });
+}
+
+GLSLConformanceTester.runRenderTests(testList, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html
new file mode 100644
index 0000000000..4ab422c958
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html
@@ -0,0 +1,351 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL switch/case corner case 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderDeclarationInsideSwitch" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchDefault" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ default:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchLiteral" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (0)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchLiteralDefault" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (0)
+ {
+ default:
+ ivec2 i;
+ i = ivec2(1, 0);
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderDeclarationInsideSwitchScope" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+// GLSL ES 3.10 clarifies the scoping rules that are relevant here. In section 4.2.2 it says:
+// "The statement following a switch (...) forms a nested scope."
+// There are no other special scoping rules with regards to switch statements.
+
+void main()
+{
+ my_FragColor = vec4(1, 0, 0, 1);
+ switch (u_zero)
+ {
+ case 0:
+ ivec2 i;
+ i = ivec2(1, 0);
+ default:
+ my_FragColor = vec4(0, i[0], 0, 1);
+ }
+}
+</script>
+<script id="fshaderFallThroughAll" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ int i = 0;
+ // switch should fall through both cases.
+ switch(u_zero)
+ {
+ case 0:
+ i += 1;
+ case 1:
+ i += 2;
+ }
+ if (i == 3)
+ {
+ my_FragColor = vec4(0, 1, 0, 1);
+ }
+ else
+ {
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+}
+</script>
+<script id="fshaderEmptySwitchStatement" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ switch(u_zero)
+ {
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasEmptyDeclaration" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty declaration should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ int;
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasEmptyBlock" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty block should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ {}
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasConstantStatement" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty statement should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ 0;
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderLastCaseHasEmptyStatement" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Empty statement should count as a statement.
+ switch(u_zero)
+ {
+ case 0:
+ ;
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script id="fshaderCaseInsideBlock" type="x-shader/x-fragment">#version 300 es
+
+precision highp float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main()
+{
+ // Case statements must not be nested in blocks.
+ // GLSL ES 3.00 spec is a bit vague on this but GLSL ES 3.10 section 6.2 is clearer.
+ switch(u_zero)
+ {
+ case 1:
+ {
+ case 0:
+ my_FragColor = vec4(1, 0, 0, 1);
+ }
+ }
+ my_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+// Covers bugs:
+// http://anglebug.com/2177
+// http://anglebug.com/2178
+// http://anglebug.com/2179
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshaderDeclarationInsideSwitch',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchDefault',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch default case should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchLiteral',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch with literal value should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchLiteralDefault',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch with literal value and default case should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderDeclarationInsideSwitchScope',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Declaration inside switch should be scoped until the end of the switch statement.',
+ render: true
+},
+{
+ fShaderId: 'fshaderFallThroughAll',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Falling through all cases in switch/case should work.',
+ render: true
+},
+{
+ fShaderId: 'fshaderEmptySwitchStatement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty switch statements are valid.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasEmptyDeclaration',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty declaration should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasEmptyBlock',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty block should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasConstantStatement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Constant statement should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderLastCaseHasEmptyStatement',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Empty statement should count as a statement for the purposes of switch statement validation.'
+},
+{
+ fShaderId: 'fshaderCaseInsideBlock',
+ fShaderSuccess: false,
+ passMsg: 'Case statements must not be nested inside blocks.'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html
new file mode 100644
index 0000000000..8fd483140d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html
@@ -0,0 +1,170 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL texture offset with non-constant offset 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderTextureOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureOffset(u_sampler, u_texCoord, offset);
+}
+</script>
+<script id="fshaderTextureProjOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureProjOffset(u_sampler, u_texCoord, offset);
+}
+</script>
+<script id="fshaderTextureLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureLodOffset(u_sampler, u_texCoord, u_lod, offset);
+}
+</script>
+<script id="fshaderTextureProjLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureProjLodOffset(u_sampler, u_texCoord, u_lod, offset);
+}
+</script>
+<script id="fshaderTextureGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, offset);
+}
+</script>
+<script id="fshaderTextureProjGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = textureProjGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, offset);
+}
+</script>
+<script id="fshaderTexelFetchOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_lod;
+
+void main() {
+ ivec2 offset = ivec2(0);
+ my_FragColor = texelFetchOffset(u_sampler, ivec2(u_texCoord), int(u_lod), offset);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("A non-constant offset is not valid in texture offset functions.");
+
+var wtu = WebGLTestUtils;
+
+var shaderTextureOffsetSrc = wtu.getScript('fshaderTextureOffset');
+var shaderTextureLodOffsetSrc = wtu.getScript('fshaderTextureLodOffset');
+var shaderTextureGradOffsetSrc = wtu.getScript('fshaderTextureGradOffset');
+var shaderTextureProjOffsetSrc = wtu.getScript('fshaderTextureProjOffset');
+var shaderTextureProjLodOffsetSrc = wtu.getScript('fshaderTextureProjLodOffset');
+var shaderTextureProjGradOffsetSrc = wtu.getScript('fshaderTextureProjGradOffset');
+var shaderTexelFetchOffsetSrc = wtu.getScript('fshaderTexelFetchOffset');
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("Unable to initialize WebGL 2.0 context.");
+} else {
+ GLSLConformanceTester.runTests([
+ {
+ fShaderSource: shaderTextureOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureLodOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureLodOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureGradOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureGradOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureProjOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureProjOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureProjLodOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureProjLodOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTextureProjGradOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'textureProjGradOffset with non-constant offset is invalid'
+ },
+ {
+ fShaderSource: shaderTexelFetchOffsetSrc,
+ fShaderSuccess: false,
+ passMsg: 'texelFetchOffset with non-constant offset is invalid'
+ }
+ ], 2);
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html
new file mode 100644
index 0000000000..99e698fb6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html
@@ -0,0 +1,106 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL out-of-range texture offset 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshaderInvalidOffset" type="x-shader/x-vertex">#version 300 es
+in vec4 a_position;
+in vec2 a_in0;
+out vec2 v_texCoord;
+
+void main()
+{
+ gl_Position = a_position;
+ v_texCoord = a_in0;
+}
+</script>
+<script id="fshaderInvalidOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+in vec2 v_texCoord;
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform int x;
+
+void main() {
+ my_FragColor = textureOffset(u_sampler, v_texCoord, ivec2(0, $(yoffset)));
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Out-of-range texture offset should not compile.");
+
+var wtu = WebGLTestUtils;
+
+var vshader = wtu.getScript('vshaderInvalidOffset');
+var fshaderTemplate = wtu.getScript('fshaderInvalidOffset');
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("Unable to initialize WebGL 2.0 context.");
+} else {
+ var minOffset = gl.getParameter(gl.MIN_PROGRAM_TEXEL_OFFSET);
+ var maxOffset = gl.getParameter(gl.MAX_PROGRAM_TEXEL_OFFSET);
+
+ var shaderSrcValidMin = wtu.replaceParams(fshaderTemplate, {'yoffset': minOffset});
+ var shaderSrcValidMax = wtu.replaceParams(fshaderTemplate, {'yoffset': maxOffset});
+ var shaderSrcBelowMin = wtu.replaceParams(fshaderTemplate, {'yoffset': (minOffset - 1)});
+ var shaderSrcAboveMax = wtu.replaceParams(fshaderTemplate, {'yoffset': (maxOffset + 1)});
+ var shaderSrcDynamic = wtu.replaceParams(fshaderTemplate, {'yoffset': 'x'});
+
+ GLSLConformanceTester.runTests([
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcValidMin,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Minimum in-range texture offset should compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcValidMax,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Maximum in-range texture offset should compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcBelowMin,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Texture offset below minimum valid value should not compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcAboveMax,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Texture offset above maximum valid value should not compile'
+ },
+ {
+ vShaderSource: vshader,
+ fShaderSource: shaderSrcDynamic,
+ fShaderSuccess: false,
+ linkSuccess: false,
+ passMsg: 'Dynamic texture offset should not compile'
+ }
+ ], 2);
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html
new file mode 100644
index 0000000000..56caf47f46
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html
@@ -0,0 +1,170 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL texture offset with uniform texture coordinates 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderTextureOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+
+void main() {
+ my_FragColor = textureOffset(u_sampler, u_texCoord, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureProjOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+
+void main() {
+ my_FragColor = textureProjOffset(u_sampler, u_texCoord, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ my_FragColor = textureLodOffset(u_sampler, u_texCoord, u_lod, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureProjLodOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform float u_lod;
+
+void main() {
+ my_FragColor = textureProjLodOffset(u_sampler, u_texCoord, u_lod, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ my_FragColor = textureGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTextureProjGradOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec4 u_texCoord;
+uniform vec2 u_dPdx;
+uniform vec2 u_dPdy;
+
+void main() {
+ my_FragColor = textureProjGradOffset(u_sampler, u_texCoord, u_dPdx, u_dPdy, ivec2(0, 1));
+}
+</script>
+<script id="fshaderTexelFetchOffset" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform sampler2D u_sampler;
+uniform vec2 u_texCoord;
+uniform vec2 u_lod;
+
+void main() {
+ my_FragColor = texelFetchOffset(u_sampler, ivec2(u_texCoord), int(u_lod), ivec2(0, 1));
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Texture coordinates expressed as uniform variable should not crash in texture offset functions.");
+
+var wtu = WebGLTestUtils;
+
+var shaderTextureOffsetSrc = wtu.getScript('fshaderTextureOffset');
+var shaderTextureLodOffsetSrc = wtu.getScript('fshaderTextureLodOffset');
+var shaderTextureGradOffsetSrc = wtu.getScript('fshaderTextureGradOffset');
+var shaderTextureProjOffsetSrc = wtu.getScript('fshaderTextureProjOffset');
+var shaderTextureProjLodOffsetSrc = wtu.getScript('fshaderTextureProjLodOffset');
+var shaderTextureProjGradOffsetSrc = wtu.getScript('fshaderTextureProjGradOffset');
+var shaderTexelFetchOffsetSrc = wtu.getScript('fshaderTexelFetchOffset');
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("Unable to initialize WebGL 2.0 context.");
+} else {
+ GLSLConformanceTester.runTests([
+ {
+ fShaderSource: shaderTextureOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureLodOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureLodOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureGradOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureGradOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureProjOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureProjOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureProjLodOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureProjLodOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTextureProjGradOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'textureProjGradOffset with uniform texture coordinates should not crash'
+ },
+ {
+ fShaderSource: shaderTexelFetchOffsetSrc,
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'texelFetchOffset with uniform texture coordinates should not crash'
+ }
+ ], 2);
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html
new file mode 100644
index 0000000000..1bf57d1a02
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html
@@ -0,0 +1,327 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL tricky loop conditions and loop expressions</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!--
+Some tricky shader expressions might be subject to syntax tree transformations that need to create
+new statements. Ensure that these expressions also work inside loop conditions and loop expressions.
+-->
+<script type="application/javascript">
+"use strict";
+description("Indexing complex array expressions");
+debug("");
+
+// All the templates run the given sequence:
+// 1. loopExpression or loopCondition
+// 2. loopContents
+// 3. Break loop if it's done loopIterations iterations, else go back to 1.
+
+var forLoopExpressionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' for (int i = 0; true; $(loopExpression))',
+ ' {',
+ ' ++i;',
+ ' if (i > 1) {',
+ ' $(loopContents)',
+ ' if (i > $(loopIterations)) { break; }',
+ ' }',
+ ' }',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var forLoopConditionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' for (int i = 1; $(loopCondition); ++i)',
+ ' {',
+ ' $(loopContents)',
+ ' if (i >= $(loopIterations)) { break; }',
+ ' }',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var whileLoopConditionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' int i = 0;',
+ ' while ($(loopCondition))',
+ ' {',
+ ' $(loopContents)',
+ ' ++i;',
+ ' if (i >= $(loopIterations)) { break; }',
+ ' }',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var doWhileLoopConditionTemplate = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'out vec4 color;',
+ '$(globalScopePrefix)',
+ 'void main() {',
+ '$(mainPrefix)',
+ ' int i = 0;',
+ // Run the loop condition one extra time to make the different test types behave the same
+ ' $(loopCondition);',
+ ' do {',
+ ' $(loopContents)',
+ ' ++i;',
+ ' if (i >= $(loopIterations)) { break; }',
+ ' }',
+ ' while ($(loopCondition));',
+ ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
+ '}'
+].join('\n');
+
+var testDataList = [
+{
+ description: 'indexing an array assignment',
+ globalScopePrefix: '',
+ mainPrefix: [
+ 'float a[2] = float[2](0.0, 0.0);',
+ 'float b[2] = float[2](2.0, 1.0);',
+ 'float c = 0.0;'
+ ].join('\n'),
+ loopExpression: 'c = (a = b)[0]',
+ loopCondition: 'bool((c = (a = b)[0]) + 1.0)',
+ loopContents: 'b[0] += 1.0;',
+ loopIterations: 3,
+ passCondition: 'abs(c - 4.0) < 0.01'
+},
+{
+ description: 'indexing a function returning an array',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'float[2] functionReturnArray() {',
+ ' ++sideEffectCounter;',
+ ' return float[2](float(sideEffectCounter), 1.0);',
+ '}'
+ ].join('\n'),
+ mainPrefix: 'float c = 0.0;',
+ loopExpression: 'c = functionReturnArray()[0]',
+ loopCondition: 'bool(c = functionReturnArray()[0])',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(c - 3.0) < 0.01 && sideEffectCounter == 3'
+},
+{
+ description: 'indexing an array constructor',
+ globalScopePrefix: '',
+ mainPrefix: 'int c = 0;',
+ loopExpression: 'c = (int[2](c + 1, c + 2))[1]',
+ loopCondition: 'bool(c = (int[2](c + 1, c + 2))[1])',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'c == 6'
+},
+{
+ description: 'indexing an array constructor inside a sequence operator',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'int func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter;',
+ '}'
+ ].join('\n'),
+ mainPrefix: 'int c = 0;',
+ loopExpression: 'c = (func(), (int[2](c + 1, c + 2))[1])',
+ loopCondition: 'bool(c = (func(), (int[2](c + 1, c + 2))[1]))',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'c == 6 && sideEffectCounter == 3'
+},
+{
+ description: 'dynamic indexing of a vector',
+ globalScopePrefix: '',
+ mainPrefix: [
+ 'vec4 v = vec4(1.0, 2.0, 3.0, 4.0);',
+ 'float c = 0.0;',
+ 'int j = 0;'
+ ].join('\n'),
+ loopExpression: 'c = v[j]',
+ loopCondition: 'bool(c = v[j])',
+ loopContents: '++j;',
+ loopIterations: 3,
+ passCondition: 'abs(c - 3.0) < 0.01'
+},
+{
+ description: 'short-circuiting operator',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'bool func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: '',
+ loopExpression: 'func() && func()',
+ loopCondition: 'func() && func()',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'sideEffectCounter == 6'
+},
+{
+ description: 'short-circuiting operator',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'bool func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: '',
+ loopExpression: 'func() || func()',
+ loopCondition: 'func() || func()',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'sideEffectCounter == 3'
+},
+{
+ description: 'short-circuiting operator',
+ globalScopePrefix: [
+ 'int sideEffectCounterA = 0;',
+ 'bool funcA() {',
+ ' sideEffectCounterA++;',
+ ' return sideEffectCounterA > 1;',
+ '}',
+ 'int sideEffectCounterB = 0;',
+ 'bool funcB() {',
+ ' sideEffectCounterB++;',
+ ' return sideEffectCounterB > 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: '',
+ loopExpression: 'funcA() ? true : funcB()',
+ loopCondition: 'funcA() ? true : funcB()',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'sideEffectCounterA == 3 && sideEffectCounterB == 1'
+},
+{
+ description: 'high-precision constant',
+ globalScopePrefix: [
+ 'const highp float f = 2048.5;',
+ 'uniform mediump float u_zero;'
+ ].join('\n'),
+ mainPrefix: 'float c = 0.0;',
+ loopExpression: 'c = fract(u_zero + f)',
+ loopCondition: 'bool(c = fract(u_zero + f))',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(c - 0.5) < 0.01'
+},
+{
+ description: 'l-value indexing side effects combined with static indexing of a vector',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'int func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 1 ? 1 : 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: [
+ 'vec4[2] V;',
+ 'V[0] = vec4(1.0);',
+ 'V[1] = vec4(3.0);'
+ ].join('\n'),
+ loopExpression: 'V[func()][0]++',
+ loopCondition: 'bool(V[func()][0]++)',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(V[0][0] - 2.0) < 0.01 && abs(V[1][0] - 5.0) < 0.01 && sideEffectCounter == 3'
+},
+{
+ description: 'l-value indexing side effects combined with dynamically indexing a vector',
+ globalScopePrefix: [
+ 'int sideEffectCounter = 0;',
+ 'uniform int u_zero;',
+ 'int func() {',
+ ' sideEffectCounter++;',
+ ' return sideEffectCounter > 1 ? 1 : 0;',
+ '}'
+ ].join('\n'),
+ mainPrefix: [
+ 'vec4[2] V;',
+ 'V[0] = vec4(1.0);',
+ 'V[1] = vec4(3.0);'
+ ].join('\n'),
+ loopExpression: 'V[func()][u_zero + 1]++',
+ loopCondition: 'bool(V[func()][u_zero + 1]++)',
+ loopContents: '',
+ loopIterations: 3,
+ passCondition: 'abs(V[0][1] - 2.0) < 0.01 && abs(V[1][1] - 5.0) < 0.01 && sideEffectCounter == 3'
+}
+];
+
+var tests = [];
+
+var wtu = WebGLTestUtils;
+
+for (var i = 0; i < testDataList.length; ++i) {
+ var testData = testDataList[i];
+ if ('loopCondition' in testData) {
+ tests.push({
+ fShaderSource: wtu.replaceParams(forLoopConditionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a for loop condition'
+ });
+ tests.push({
+ fShaderSource: wtu.replaceParams(whileLoopConditionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a while loop condition'
+ });
+ tests.push({
+ fShaderSource: wtu.replaceParams(doWhileLoopConditionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a do-while loop condition'
+ });
+ }
+ if ('loopExpression' in testData) {
+ tests.push({
+ fShaderSource: wtu.replaceParams(forLoopExpressionTemplate, testData),
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Test ' + testData.description + ': ' + testData.loopExpression + ' inside a for loop expression'
+ });
+ }
+}
+
+GLSLConformanceTester.runRenderTests(tests, 2);
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html
new file mode 100644
index 0000000000..499d266e7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html
@@ -0,0 +1,106 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Verify (uint(int) >> 31) works correctly (Adreno driver bug)</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader-uint-1" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+flat out highp uint uvalue;
+uniform highp int ivalue;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+ uvalue = uint(ivalue) >> 31u;
+}
+</script>
+<script id="fshader-uint-1" type="x-shader/x-fragment">#version 300 es
+flat in highp uint uvalue;
+out highp vec4 myFragColor;
+
+void main() {
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
+in vec3 aPosition;
+
+void main() {
+ gl_Position = vec4(aPosition, 1);
+}
+</script>
+<script id="fshader-uint-2" type="x-shader/x-fragment">#version 300 es
+uniform highp int ivalue;
+out highp vec4 myFragColor;
+
+void main() {
+ uint uvalue = uint(ivalue) >> 31u;
+
+ if (uvalue == 1u)
+ myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else
+ myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script type="application/javascript">
+"use strict";
+description("Verify (uint(int) >> 31) works correctly");
+debug("");
+var wtu = WebGLTestUtils;
+function test() {
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ }
+ wtu.setupUnitQuad(gl);
+
+ var testCases = [
+ { vshader: "vshader-uint-1", fshader: "fshader-uint-1", desc: "vertex shader uint" },
+ { vshader: "vshader-simple", fshader: "fshader-uint-2", desc: "fragment shader uint" },
+ ];
+
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ var test = testCases[idx];
+
+ debug("");
+ var program = wtu.setupProgram(gl, [test.vshader, test.fshader], ["aPosition"]);
+ if (!program) {
+ testFailed("Fail to set up program");
+ } else {
+ var uniformLoc = gl.getUniformLocation(program, 'ivalue');
+ gl.uniform1i(uniformLoc, -1);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+ gl.deleteProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from testing");
+ }
+ }
+};
+
+test();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html
new file mode 100644
index 0000000000..200acbe6de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html
@@ -0,0 +1,248 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+
+<head>
+<meta charset="utf-8">
+<title>Unary minus operator on int or uint variables in a dynamic loop in vertex shader should work</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+
+<body>
+<canvas id="canvas" style="border: none;" width="1024" height="128"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="shader-vs-int" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform int u_one;
+uniform int u_two;
+uniform int u_three;
+
+out mediump vec4 v_color;
+void main() {
+ int array[3];
+ array[0] = u_one; // array[0] should be 1
+ array[1] = -u_two; // array[1] should be -2
+ array[2] = u_three; // array[2] should be 3
+ int result = 0;
+ for (int i = 0; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-uint" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform uint u_one;
+uniform uint u_two;
+uniform uint u_three;
+
+out mediump vec4 v_color;
+void main() {
+ uint array[3];
+ array[0] = u_one; // array[0] should be 1u
+ array[1] = -u_two; // array[1] should be -2u
+ array[2] = u_three; // array[2] should be 3u
+ uint result = 0u;
+ for (uint i = 0u; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-int-multiple-brackets" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform int u_one;
+uniform int u_two;
+uniform int u_three;
+
+out mediump vec4 v_color;
+void main() {
+ int array[3];
+ array[0] = u_one; // array[0] should be 1
+ array[1] = -(-(-u_two + 1) + 1); // array[1] should be -2
+ array[2] = u_three; // array[2] should be 3
+ int result = 0;
+ for (int i = 0; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-uint-multiple-brackets" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform uint u_one;
+uniform uint u_two;
+uniform uint u_three;
+
+out mediump vec4 v_color;
+void main() {
+ uint array[3];
+ array[0] = u_one; // array[0] should be 1u
+ array[1] = -(-(-u_two + 1u) + 1u); // array[1] should be -2u
+ array[2] = u_three; // array[2] should be 3u
+ uint result = 0u;
+ for (uint i = 0u; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-int-implicit-unary-minus" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform int u_one;
+uniform int u_two;
+uniform int u_three;
+
+out mediump vec4 v_color;
+void main() {
+ int array[3];
+ array[0] = u_one; // array[0] should be 1
+ array[1] = 1 - u_two;
+ array[2] = u_three; // array[2] should be 3
+ int result = 0;
+ array[1] -= 1; // array[1] should be -u_two == -2
+ for (int i = 0; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-vs-uint-implicit-unary-minus" type="x-shader/x-vertex">#version 300 es
+in highp vec4 pos;
+
+uniform uint u_one;
+uniform uint u_two;
+uniform uint u_three;
+
+out mediump vec4 v_color;
+void main() {
+ uint array[3];
+ array[0] = u_one; // array[0] should be 1u
+ array[1] = 1u - u_two;
+ array[2] = u_three; // array[2] should be 3u
+ uint result = 0u;
+ array[1] -= 1u; // array[1] should be -u_two == -2u
+ for (uint i = 0u; i < u_three; i++) {
+ result += array[i];
+ }
+ v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+ gl_Position = pos;
+}
+</script>
+
+<script id="shader-fs" type="x-shader/x-fragment">#version 300 es
+in mediump vec4 v_color;
+out mediump vec4 o_color;
+
+void main() {
+ o_color = v_color;
+}
+</script>
+
+<script>
+"use strict";
+
+function test() {
+ description();
+ debug("This test exposes an Intel driver bug on Windows.");
+ debug("");
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("canvas", undefined, 2);
+ if (!gl) {
+ testFailed("WebGL 2 context does not exist");
+ return;
+ }
+
+ var testNum = 0;
+ var border = 10; // border between test squares for visibility
+ var squareSize = 128;
+ var expectedColor = [0, 255, 0, 255]; // green
+
+ function subTest_int(message, VertexShader) {
+ debug(message);
+ var startX = (squareSize + border) * testNum;
+ var program = wtu.setupProgram(
+ gl, [VertexShader, "shader-fs"], ["pos"], null, true);
+ gl.viewport(startX, 0, squareSize, squareSize);
+
+ var one = gl.getUniformLocation(program, "u_one");
+ var two = gl.getUniformLocation(program, "u_two");
+ var three = gl.getUniformLocation(program, "u_three");
+ gl.uniform1i(one, 1);
+ gl.uniform1i(two, 2);
+ gl.uniform1i(three, 3);
+
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(
+ gl, startX, 0, squareSize, squareSize,
+ expectedColor, "square should be green", 1);
+ debug("");
+ testNum++;
+ }
+
+ function subTest_uint(message, VertexShader) {
+ debug(message);
+ var startX = (squareSize + border) * testNum;
+ var program = wtu.setupProgram(
+ gl, [VertexShader, "shader-fs"], ["pos"], null, true);
+ gl.viewport(startX, 0, squareSize, squareSize);
+
+ var one = gl.getUniformLocation(program, "u_one");
+ var two = gl.getUniformLocation(program, "u_two");
+ var three = gl.getUniformLocation(program, "u_three");
+ gl.uniform1ui(one, 1);
+ gl.uniform1ui(two, 2);
+ gl.uniform1ui(three, 3);
+
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(
+ gl, startX, 0, squareSize, squareSize,
+ expectedColor, "square should be green", 1);
+ debug("");
+ testNum++;
+ }
+
+ if (!gl) {
+ testFailed("context does not exist");
+ } else {
+ wtu.setupUnitQuad(gl);
+ subTest_int("Test unary minus operator on int.", "shader-vs-int");
+ subTest_uint("Test unary minus operator on unsigned int.", "shader-vs-uint");
+ subTest_int("Test unary minus operator on int with multiple brackets.", "shader-vs-int-multiple-brackets");
+ subTest_uint("Test unary minus operator on unsigned int with multiple brackets.", "shader-vs-uint-multiple-brackets");
+ subTest_int("Test implicit unary minus operator on int.", "shader-vs-int-implicit-unary-minus");
+ subTest_uint("Test implicit unary minus operator on unsigned int.", "shader-vs-uint-implicit-unary-minus");
+ }
+}
+
+test();
+var successfullyParsed = true;
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html
new file mode 100644
index 0000000000..b92cefc882
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Uniform Block Layout Behavior Testing</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="ES3VertexShader" type="x-shader/x-vertex">#version 300 es
+layout(std140) uniform Block
+{
+ highp vec4 val;
+};
+
+void main() {
+ gl_Position = vec4(val);
+}
+</script>
+<script id="ES3FragmentShader" type="x-shader/x-fragment">#version 300 es
+uniform Block
+{
+ highp vec4 val;
+};
+out highp vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(val);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "ES3VertexShader",
+ vShaderSuccess: true,
+ fShaderId: "ES3FragmentShader",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "A uniform block's layout defaults to std140 if not specified."
+ },
+], 2);
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html
new file mode 100644
index 0000000000..2dbfc664ee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html
@@ -0,0 +1,63 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Disallowed uniform block layouts</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderPackedUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+layout(packed) uniform foo {
+ vec4 bar;
+};
+
+void main() {
+ my_FragColor = bar;
+}
+</script>
+<script id="fshaderSharedUniformBlock" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+layout(shared) uniform foo {
+ vec4 bar;
+};
+
+void main() {
+ my_FragColor = bar;
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("WebGL does not allow interface blocks with shared or packed layouts.");
+
+GLSLConformanceTester.runTests([
+{
+ fShaderId: 'fshaderPackedUniformBlock',
+ fShaderSuccess: false,
+ passMsg: 'Packed uniform buffers are disallowed'
+},
+{
+ fShaderId: 'fshaderSharedUniformBlock',
+ fShaderSuccess: false,
+ passMsg: 'Shared uniform buffers are disallowed'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html
new file mode 100644
index 0000000000..9df7b5a88f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html
@@ -0,0 +1,51 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL uniform struct with a non-square 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderUniformStructWithNonSquareMatrixAndBoolean" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out highp vec4 my_color;
+struct S
+{
+ mat2x4 m;
+ bool b;
+};
+uniform S uni;
+void main()
+{
+ my_color = vec4(0, 1, 0, 1);
+ if (!uni.b) { my_color.g = 0.0; }
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderUniformStructWithNonSquareMatrixAndBoolean',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Set a boolean member in a uniform struct that also contains a non-square-matrix',
+ uniforms: [{name: "uni.b", functionName: "uniform1i", value: 1}]
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html
new file mode 100644
index 0000000000..0d5be3da22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html
@@ -0,0 +1,98 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Uninitialized local/global variables should be initialized (ESSL 3.00 cases)</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"> </script>
+
+<!--
+This test covers cases that can't be tested with ESSL 1.00 due to Appendix A limitations.
+The ESSL 1.00 cases are covered in conformance/glsl/misc/uninitialized-local-global-variables.html
+-->
+
+<script id="vs_uninit_in_frag" type="x-shader/x-vertex">#version 300 es
+precision highp float;
+in vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+
+<!-- Uninitialized variables in a for loop initializer in fragment shader -->
+<script id="fs_uninit_variables_in_loop_in_frag" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ int i = 0;
+ for (vec4 uninit, uninit2[2] = vec4[2](uninit, uninit); i < 1; ++i) {
+ my_FragColor = uninit2[0];
+ }
+}
+</script>
+
+<!-- Uninitialized nameless struct in a for loop initializer in fragment shader -->
+<script id="fs_uninit_nameless_struct_in_loop_in_frag" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ int i = 0;
+ for (struct { vec4 v; } uninit; i < 1; ++i) {
+ my_FragColor = uninit.v;
+ }
+}
+</script>
+
+</head>
+<body>
+<canvas id="canvas" width="50" height="50"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Uninitialized local/global variables should be initialized: http://anglebug.com/1966');
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", undefined, 2);
+wtu.setupUnitQuad(gl);
+
+var cases = [
+ {
+ name: "Uninitialized variables in a for loop initializer in fragment shader",
+ prog: ["vs_uninit_in_frag", "fs_uninit_variables_in_loop_in_frag"],
+ },
+ {
+ name: "Uninitialized nameless struct in a for loop initializer in fragment shader",
+ prog: ["vs_uninit_in_frag", "fs_uninit_nameless_struct_in_loop_in_frag"],
+ }
+];
+
+function runTest() {
+ for (var i = 0; i < cases.length; ++i) {
+ debug("");
+ debug(cases[i].name);
+ var program = wtu.setupProgram(gl, cases[i].prog, ["a_position"], undefined, true);
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 0, 0, 0]);
+ }
+
+ debug("");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html
new file mode 100644
index 0000000000..a4fffaf061
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html
@@ -0,0 +1,95 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Positive tests for the use of the invariant qualifier and pragma</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertexShaderInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+invariant out vec4 v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="vertexShaderSeparateInvariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+out vec4 v_varying;
+invariant v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="vertexShaderGlobalInvariant" type="text/something-not-javascript">#version 300 es
+#pragma STDGL invariant(all)
+precision mediump float;
+out vec4 v_varying;
+
+void main()
+{
+ v_varying = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position = v_varying;
+}
+</script>
+<script id="fragmentShaderVariant" type="text/something-not-javascript">#version 300 es
+precision mediump float;
+
+in vec4 v_varying;
+out vec4 my_color;
+
+void main()
+{
+ my_color = v_varying;
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+GLSLConformanceTester.runTests([
+ {
+ vShaderId: "vertexShaderInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderVariant",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with invariant varying and fragment shader with variant varying must succeed",
+ },
+ {
+ vShaderId: "vertexShaderGlobalInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderVariant",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with invariant (global setting) varying and fragment shader with variant varying must succeed",
+ },
+ {
+ vShaderId: "vertexShaderSeparateInvariant",
+ vShaderSuccess: true,
+ fShaderId: "fragmentShaderVariant",
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: "vertex shader with invariant (separately set) varying and fragment shader with variant varying must succeed",
+ },
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html
new file mode 100644
index 0000000000..f3ac2485e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html
@@ -0,0 +1,62 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL varying struct with inline definition 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+
+in vec4 vPosition;
+
+flat out struct S {
+ int field;
+} v_s;
+
+void main() {
+ v_s.field = 1;
+ gl_Position = vPosition;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+
+flat in struct S {
+ int field;
+} v_s;
+
+out vec4 my_FragColor;
+
+void main() {
+ my_FragColor = vec4(1 - v_s.field, v_s.field, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description();
+
+GLSLConformanceTester.runRenderTests([
+{
+ vShaderId: 'vshader',
+ vShaderSuccess: true,
+ fShaderId: 'fshader',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Vertex output struct / fragment input struct with an inline definition should compile and link'
+}
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html
new file mode 100644
index 0000000000..767bfd915d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html
@@ -0,0 +1,67 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL dynamic vector and matrix indexing 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderLValueVectorBeingIndexedHasSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 1;
+}
+
+void main() {
+ vec4 V[2];
+ V[0] = vec4(1.0, 2.0, 3.0, 4.0);
+ V[1] = vec4(5.0, 6.0, 7.0, 8.0);
+ // In case this is broken down to two expressions where one reads V[funcWithSideEffects()]
+ // and another writes it, it needs to be made sure that funcWithSideEffects() only gets called once.
+ V[funcWithSideEffects()][u_zero + 1]++;
+ vec4 expectedV0 = vec4(1.0, 2.0, 3.0, 4.0);
+ vec4 expectedV1 = vec4(5.0, 7.0, 7.0, 8.0);
+ float f = 1.0 - distance(V[0], expectedV0) - distance(V[1], expectedV1);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Dynamic indexing of vectors and matrices should work.");
+
+debug("This test exposes a NVidia driver bug on Linux");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderLValueVectorBeingIndexedHasSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index a vector expression that itself has side effects, in an l-value'
+},
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html
new file mode 100644
index 0000000000..4b82d6ed30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html
@@ -0,0 +1,50 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL swizzled vector l-value dynamic indexing 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!--
+ The shader first assigns v.x to v.z (1.0)
+ Then v.y to v.y (2.0)
+ Then v.z to v.x (1.0)
+-->
+<script id="fshaderSwizzledLValueIndexing" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+void main() {
+ vec3 v = vec3(1.0, 2.0, 3.0);
+ for (int i = 0; i < 3; i++) {
+ v.zyx[i] = v[i];
+ }
+ my_FragColor = distance(v, vec3(1.0, 2.0, 1.0)) < 0.01 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Dynamic indexing of swizzled l-values should work.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderSwizzledLValueIndexing',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an l-value swizzled vector'
+},
+], 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html
new file mode 100644
index 0000000000..5bf60578ad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html
@@ -0,0 +1,369 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>GLSL dynamic vector and matrix indexing 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="../../js/glsl-conformance-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="fshaderIndexMatrixTwice" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ mat2 m = mat2(0.0, 0.0, 0.0, 1.0);
+ float f = m[u_zero + 1][u_zero + 1];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexWithValueFromIndexingExpression" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ ivec2 i = ivec2(0, 2);
+ vec4 v = vec4(0.0, 0.2, 1.0, 0.4);
+ float f = v[i[u_zero + 1]];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexLValue" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[u_zero + 1] = 5.0;
+ vec4 expected = vec4(1.0, 5.0, 3.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexLValueWithValueFromIndexingExpression" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ ivec2 i = ivec2(0, 2);
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[i[u_zero + 1]] = 5.0;
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexBuiltInFunctionCallOutParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ modf(5.5, v[u_zero + 3]);
+ vec4 expected = vec4(1.0, 2.0, 3.0, 5.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUserDefinedFunctionCallOutParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void foo(out float f) {
+ modf(5.5, f);
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ foo(v[u_zero + 3]);
+ vec4 expected = vec4(1.0, 2.0, 3.0, 5.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUserDefinedFunctionCallInOutParameter" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void foo(inout float f) {
+ float g = f + 2.5;
+ modf(g, f);
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ foo(v[u_zero + 2]);
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexWithSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 2;
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[funcWithSideEffects()] = 5.0;
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexInOutWithSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 2;
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[funcWithSideEffects()]++;
+ vec4 expected = vec4(1.0, 2.0, 4.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUserDefinedFunctionCallInOutParameterWithIndexWithSideEffects" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+
+void foo(inout float f) {
+ float g = f + 2.5;
+ modf(g, f);
+}
+
+int funcWithSideEffects() {
+ sideEffectCounter++;
+ return 2;
+}
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ foo(v[funcWithSideEffects()]);
+ vec4 expected = vec4(1.0, 2.0, 5.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ if (sideEffectCounter != 1) {
+ f = 0.0;
+ }
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexLValueWithUint" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform uint u_zero;
+
+void main() {
+ vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
+ v[u_zero] = 5.0;
+ vec4 expected = vec4(5.0, 2.0, 3.0, 4.0);
+ float f = 1.0 - distance(v, expected);
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script id="fshaderIndexUniform" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform vec4 u_zeroVec;
+uniform uint u_zero;
+
+void main() {
+ // This test is just to catch a crash bug that occurred in ANGLE's workaround.
+ // Rendering result is not meaningful.
+ float f = u_zeroVec[u_zero];
+ my_FragColor = vec4(f, 1.0, 0.0, 1.0);
+}
+</script>
+<script id="fshaderSequenceDynamicIndexingVectorLvalue" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+uniform int u_zero;
+
+int sideEffectCounter = 0;
+float func() {
+ ++sideEffectCounter;
+ return -1.0;
+}
+
+void main() {
+ vec4 v = vec4(0.0, 2.0, 4.0, 6.0);
+ float f = (func(), (++v[u_zero + sideEffectCounter]));
+ my_FragColor = (abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCounter == 1) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script id="fshaderIndexMatrixTwiceInLValue" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+
+uniform int u_zero;
+
+void main() {
+ mat2 m = mat2(0.0, 0.0, 0.0, 0.0);
+ m[u_zero + 1][u_zero + 1] = float(u_zero + 1);
+ float f = m[1][1];
+ my_FragColor = vec4(1.0 - f, f, 0.0, 1.0);
+}
+</script>
+<script type="application/javascript">
+"use strict";
+description("Dynamic indexing of vectors and matrices should work.");
+
+debug("Dynamic indexing of vectors and matrices requires complex workarounds on HLSL backends. Try to test possible bugs those workarounds might have.");
+
+GLSLConformanceTester.runRenderTests([
+{
+ fShaderId: 'fshaderIndexMatrixTwice',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index matrix and then index the resulting vector in the same expression'
+},
+{
+ fShaderId: 'fshaderIndexWithValueFromIndexingExpression',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index a vector with an index that is the result of indexing'
+},
+{
+ fShaderId: 'fshaderIndexLValue',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index on the left-hand side of assignment'
+},
+{
+ fShaderId: 'fshaderIndexLValueWithValueFromIndexingExpression',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index on the left-hand side of assignment with an index that is the result of indexing'
+},
+{
+ fShaderId: 'fshaderIndexBuiltInFunctionCallOutParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index the out parameter passed to built-in modf'
+},
+{
+ fShaderId: 'fshaderIndexUserDefinedFunctionCallOutParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an out parameter passed to an user-defined function'
+},
+{
+ fShaderId: 'fshaderIndexUserDefinedFunctionCallInOutParameter',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an inout parameter passed to an user-defined function'
+},
+{
+ fShaderId: 'fshaderIndexWithSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Use expression with side effects as an index of an l-value'
+},
+{
+ fShaderId: 'fshaderIndexInOutWithSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Use expression with side effects as an index of an l-value that is both read and written'
+},
+{
+ fShaderId: 'fshaderIndexUserDefinedFunctionCallInOutParameterWithIndexWithSideEffects',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index an inout parameter passed to an user-defined function with an index with side effects'
+},
+{
+ fShaderId: 'fshaderIndexLValueWithUint',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index on the left-hand side of assignment with an uint'
+},
+{
+ fShaderId: 'fshaderIndexUniform',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index a uniform with a uniform'
+},
+{
+ fShaderId: 'fshaderSequenceDynamicIndexingVectorLvalue',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Sequence operator with dynamic indexing of a vector as an l-value inside'
+},
+{
+ fShaderId: 'fshaderIndexMatrixTwiceInLValue',
+ fShaderSuccess: true,
+ linkSuccess: true,
+ passMsg: 'Index matrix and then index the resulting vector in the same expression inside an l-value'
+}
+], 2);
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt
new file mode 100644
index 0000000000..8f1343f91d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt
@@ -0,0 +1,8 @@
+--min-version 2.0.1 blend-integer.html
+expando-loss-2.html
+getextension-while-pbo-bound-stability.html
+instanceof-test.html
+--min-version 2.0.1 null-object-behaviour-2.html
+object-deletion-behaviour-2.html
+uninitialized-test-2.html
+views-with-offsets.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html
new file mode 100644
index 0000000000..40ccfd0d86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html
@@ -0,0 +1,176 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Blend Integer Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css" />
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="outputVertexShader" type="x-shader/x-vertex">
+#version 300 es
+in vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+<script id="outputFragmentShaderSigned" type="x-shader/x-fragment">
+#version 300 es
+layout(location = 1) out highp vec4 o_drawBuffer1;
+layout(location = 2) out highp ivec4 o_drawBuffer2;
+layout(location = 3) out highp vec4 o_drawBuffer3;
+void main(void)
+{
+ o_drawBuffer1 = vec4(0, 0, 0, 0);
+ o_drawBuffer2 = ivec4(0, 0, 0, 0);
+ o_drawBuffer3 = vec4(0, 0, 0, 0);
+}
+</script>
+<script id="outputFragmentShaderUnsigned" type="x-shader/x-fragment">
+ #version 300 es
+ layout(location = 1) out highp vec4 o_drawBuffer1;
+ layout(location = 2) out highp uvec4 o_drawBuffer2;
+ layout(location = 3) out highp vec4 o_drawBuffer3;
+ void main(void)
+ {
+ o_drawBuffer1 = vec4(0, 0, 0, 0);
+ o_drawBuffer2 = uvec4(0, 0, 0, 0);
+ o_drawBuffer3 = vec4(0, 0, 0, 0);
+ }
+ </script>
+
+<script>
+"use strict";
+description("This test verifies correct behavior of min/max blending operations on integer attachments.");
+
+debug("");
+
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext(null, undefined, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("")
+ debug("GL_MIN");
+ runTest(false, gl.MIN);
+ runTest(true, gl.MIN);
+
+ debug("")
+ debug("GL_MAX");
+ runTest(false, gl.MAX);
+ runTest(true, gl.MAX);
+}
+
+function compareValue(value, attachment, isSigned) {
+ const pixel = isSigned ? new Int32Array(4) : new Uint32Array(4);
+ gl.readBuffer(attachment);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, isSigned ? gl.INT : gl.UNSIGNED_INT, pixel);
+ let pass = true;
+ for (let i = 0; i < 4; i++) {
+ if (value[i] != pixel[i]) {
+ testFailed(`Read value of channel ${i} should be ${pixel[i]}, was ${value[i]}.`);
+ pass = false;
+ }
+ }
+ return pass;
+}
+
+function runTest(isSigned, operation) {
+ gl.viewport(0, 0, 1, 1);
+ gl.disable(gl.BLEND);
+
+ const program = wtu.setupProgram(gl,
+ ["outputVertexShader",
+ isSigned ? "outputFragmentShaderSigned" : "outputFragmentShaderUnsigned"],
+ ['vPosition'], [0]);
+ const quadParameters = wtu.setupUnitQuad(gl, 0, 1);
+
+ // Setup render targets
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ const rb1 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1);
+
+ const rb2 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb2);
+ gl.renderbufferStorage(gl.RENDERBUFFER, isSigned ? gl.RGBA32I : gl.RGBA32UI, 50, 50);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.RENDERBUFFER, rb2);
+
+ const rb3 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb3);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 50, 50);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.RENDERBUFFER, rb3);
+
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Pipeline setup complete.");
+
+ if (isSigned) {
+ const clearValue = new Int32Array([-1, 2, -3, 4]);
+ gl.clearBufferiv(gl.COLOR, 2, clearValue);
+ if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Signed clear passed.");
+ } else {
+ testFailed("Signed clear failed.");
+ }
+ } else {
+ const clearValue = new Uint32Array([1, 2, 3, 4]);
+ gl.clearBufferuiv(gl.COLOR, 2, clearValue);
+ if (compareValue(clearValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Unsigned clear passed.");
+ } else {
+ testFailed("Unsigned clear failed.");
+ }
+ }
+
+ gl.blendEquation(operation);
+ gl.enable(gl.BLEND);
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw complete.");
+
+ if (isSigned) {
+ const drawValue = new Int32Array([0, 0, 0, 0]);
+ if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Signed draw passed.");
+ } else {
+ testFailed("Signed draw failed.");
+ }
+ } else {
+ const drawValue = new Uint32Array([0, 0, 0, 0]);
+ if (compareValue(drawValue, gl.COLOR_ATTACHMENT2, isSigned)) {
+ testPassed("Unsigned draw passed.");
+ } else {
+ testFailed("Unsigned draw failed.");
+ }
+ }
+ gl.deleteRenderbuffer(rb1);
+ gl.deleteRenderbuffer(rb2);
+ gl.deleteRenderbuffer(rb3);
+ gl.deleteFramebuffer(fb);
+ gl.deleteProgram(program);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html
new file mode 100644
index 0000000000..141a5377a8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html
@@ -0,0 +1,285 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<title>WebGL 2 Object Expandos Conformance Test</title>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
+<script>
+"use strict";
+description("This test verifies that WebGL object expandos are preserved across garbage collections.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false}, 2);
+
+// Helpers that set expandos and verify they are set to the correct value.
+var expandoValue = "WebGL is awesome!"
+function setTestExpandos(instance, extra) {
+ instance.expando1 = expandoValue;
+ instance.expando2 = { subvalue : expandoValue };
+ instance.expando_extra = extra;
+}
+function verifyTestExpandos(instance, msg, extra) {
+ assertMsg(instance.expando1 === expandoValue, msg + ": Expect basic expando to survive despite GC.");
+ assertMsg(instance.expando2 && instance.expando2.subvalue === expandoValue, msg + ": Expect subobject expando to survive despite GC.");
+ assertMsg(instance.expando_extra === extra, msg + ": Expect extra expando to survive despite GC.");
+}
+
+// Tests that we don't get expando loss for bound resources where the
+// only remaining reference is internal to WebGL
+function testBasicBindings() {
+ debug('Basic Bindings');
+
+ // Test data that describes how to create, bind, and retrieve an object off of the context
+ var glProt = Object.getPrototypeOf(gl);
+ var simpleData = [
+ {
+ typeName: 'WebGLSampler',
+ creationFn: glProt.createSampler,
+ bindFn: glProt.bindSampler,
+ bindConstant: 0,
+ retrieveConstant: glProt.SAMPLER_BINDING,
+ name: "SAMPLER_BINDING",
+ },
+ {
+ typeName: 'WebGLTransformFeedback',
+ creationFn: glProt.createTransformFeedback,
+ bindFn: glProt.bindTransformFeedback,
+ bindConstant: glProt.TRANSFORM_FEEDBACK,
+ retrieveConstant: glProt.TRANSFORM_FEEDBACK_BINDING,
+ name: "TRANSFORM_FEEDBACK_BINDING",
+ },
+ {
+ typeName: 'WebGLVertexArrayObject',
+ creationFn: glProt.createVertexArray,
+ bindFn: glProt.bindVertexArray,
+ bindConstant: null,
+ retrieveConstant: glProt.VERTEX_ARRAY_BINDING,
+ name: "VERTEX_ARRAY_BINDING",
+ },
+ {
+ typeName: 'WebGLTexture',
+ creationFn: glProt.createTexture,
+ bindFn: glProt.bindTexture,
+ bindConstant: glProt.TEXTURE_3D,
+ retrieveConstant: glProt.TEXTURE_BINDING_3D,
+ name: "TEXTURE_BINDING_3D",
+ },
+ {
+ typeName: 'WebGLTexture',
+ creationFn: glProt.createTexture,
+ bindFn: glProt.bindTexture,
+ bindConstant: glProt.TEXTURE_2D_ARRAY,
+ retrieveConstant: glProt.TEXTURE_BINDING_2D_ARRAY,
+ name: "TEXTURE_BINDING_2D_ARRAY",
+ },
+ {
+ typeName: 'WebGLFramebuffer',
+ creationFn: glProt.createFramebuffer,
+ bindFn: glProt.bindFramebuffer,
+ bindConstant: glProt.READ_FRAMEBUFFER,
+ retrieveConstant: glProt.READ_FRAMEBUFFER_BINDING,
+ name: "READ_FRAMEBUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLFramebuffer',
+ creationFn: glProt.createFramebuffer,
+ bindFn: glProt.bindFramebuffer,
+ bindConstant: glProt.DRAW_FRAMEBUFFER,
+ retrieveConstant: glProt.DRAW_FRAMEBUFFER_BINDING,
+ name: "DRAW_FRAMEBUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.COPY_READ_BUFFER,
+ retrieveConstant: glProt.COPY_READ_BUFFER_BINDING,
+ name: "COPY_READ_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.COPY_WRITE_BUFFER,
+ retrieveConstant: glProt.COPY_WRITE_BUFFER_BINDING,
+ name: "COPY_WRITE_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.PIXEL_PACK_BUFFER,
+ retrieveConstant: glProt.PIXEL_PACK_BUFFER_BINDING,
+ name: "PIXEL_PACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.PIXEL_UNPACK_BUFFER,
+ retrieveConstant: glProt.PIXEL_UNPACK_BUFFER_BINDING,
+ name: "PIXEL_UNPACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.TRANSFORM_FEEDBACK_BUFFER,
+ retrieveConstant: glProt.TRANSFORM_FEEDBACK_BUFFER_BINDING,
+ name: "TRANSFORM_FEEDBACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBuffer,
+ bindConstant: glProt.UNIFORM_BUFFER,
+ retrieveConstant: glProt.UNIFORM_BUFFER_BINDING,
+ name: "UNIFORM_BUFFER_BINDING",
+ },
+ ];
+
+ simpleData.forEach(function(test) {
+ var instance = test.creationFn.call(gl);
+ var msg = "getParameter(" + test.name + ")";
+ setTestExpandos(instance);
+
+ if (test.bindConstant === null) {
+ test.bindFn.call(gl, instance);
+ } else {
+ test.bindFn.call(gl, test.bindConstant, instance);
+ }
+ assertMsg(instance === gl.getParameter(test.retrieveConstant), msg + " returns instance that was bound.");
+
+ // Garbage collect Javascript references. Remaining references should be internal to WebGL.
+ instance = null;
+ webglHarnessCollectGarbage();
+
+ var retrievedObject = gl.getParameter(test.retrieveConstant);
+ verifyTestExpandos(retrievedObject, msg);
+ shouldBeType(retrievedObject, test.typeName);
+ debug('');
+ });
+}
+
+function testIndexedBindings() {
+ debug('Indexed Bindings');
+
+ // Test data that describes how to create, bind, and retrieve an indexed object off of the context
+ var glProt = Object.getPrototypeOf(gl);
+ var simpleData = [
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBufferBase,
+ indexMax: gl.getParameter(glProt.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS) - 1,
+ bindConstant: glProt.TRANSFORM_FEEDBACK_BUFFER,
+ retrieveConstant: glProt.TRANSFORM_FEEDBACK_BUFFER_BINDING,
+ name: "TRANSFORM_FEEDBACK_BUFFER_BINDING",
+ },
+ {
+ typeName: 'WebGLBuffer',
+ creationFn: glProt.createBuffer,
+ bindFn: glProt.bindBufferBase,
+ indexMax: gl.getParameter(glProt.MAX_UNIFORM_BUFFER_BINDINGS) - 1,
+ bindConstant: glProt.UNIFORM_BUFFER,
+ retrieveConstant: glProt.UNIFORM_BUFFER_BINDING,
+ name: "UNIFORM_BUFFER_BINDING",
+ },
+ ];
+
+ simpleData.forEach(function(test) {
+ // This test sets all of the separate indexed bindings first, then
+ // tests them all. It puts a different extra expando on each indexed
+ // parameter so that we can ensure they're all distinct.
+ var instances = [];
+ for (var i = 0; i <= test.indexMax; i++) {
+ var instance = test.creationFn.call(gl);
+ var msg = "getIndexedParameter(" + test.name + ", " + i + ")";
+ setTestExpandos(instance, i);
+ instances[i] = instance;
+ test.bindFn.call(gl, test.bindConstant, i, instance);
+ }
+
+ for (var i = 0; i <= test.indexMax; i++) {
+ var msg = "getIndexedParameter(" + test.name + ", " + i + ")";
+ assertMsg(instances[i] === gl.getIndexedParameter(test.retrieveConstant, i), msg + " returns instance that was bound.");
+ }
+
+ // Garbage collect Javascript references. Remaining references should be internal to WebGL.
+ instances = null;
+ webglHarnessCollectGarbage();
+
+ for (var i = 0; i <= test.indexMax; i++) {
+ var msg = "getIndexedParameter(" + test.name + ", " + i + ")";
+ var retrievedObject = gl.getIndexedParameter(test.retrieveConstant, i);
+ verifyTestExpandos(retrievedObject, msg, i);
+ shouldBeType(retrievedObject, test.typeName);
+ debug('');
+ }
+ });
+}
+
+function testQueries() {
+ debug('Query');
+
+ expandoValue = "First query";
+ var query1 = gl.createQuery();
+ setTestExpandos(query1);
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, query1);
+
+ expandoValue = "Second query";
+ var query2 = gl.createQuery();
+ setTestExpandos(query2);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query2);
+
+
+ assertMsg(query1 === gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY), "CURRENT_QUERY returns instance that was bound.");
+ assertMsg(query2 === gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY), "CURRENT_QUERY returns instance that was bound.");
+
+ // Garbage collect Javascript references. Remaining references should be internal to WebGL.
+ query1 = null;
+ query2 = null;
+ webglHarnessCollectGarbage();
+
+ var retrievedQuery1 = gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY);
+ var retrievedQuery2 = gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY);
+ expandoValue = "First query";
+ verifyTestExpandos(retrievedQuery1, "Query");
+ shouldBeType(retrievedQuery1, 'WebGLQuery');
+
+ expandoValue = "Second query";
+ verifyTestExpandos(retrievedQuery2, "Query");
+ shouldBeType(retrievedQuery2, 'WebGLQuery');
+
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+
+ debug('');
+}
+
+// Run tests
+testBasicBindings();
+testIndexedBindings();
+testQueries();
+
+// FYI: There's no need to test WebGLSync objects because there is no notion of an "active" sync,
+// and thus no way to query them back out of the context.
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html
new file mode 100644
index 0000000000..73e34fdc1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 getExtension while PBO bound stability conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+
+function runTest(extension_name) {
+ debug("");
+ debug("getExtension('" + extension_name + "') while PIXEL_UNPACK_BUFFER bound should be stable");
+
+ var gl = wtu.create3DContext(null, undefined, 2);
+ if (!gl) {
+ testFailed("Fail to get a WebGL context");
+ return;
+ }
+
+ var pbo = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo);
+ var ext = gl.getExtension('EXT_color_buffer_float');
+ var gl_texture_float_linear = gl.getExtension(extension_name);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Late-enable of extension should succeed");
+ if (pbo != gl.getParameter(gl.PIXEL_UNPACK_BUFFER_BINDING)) {
+ testFailed("Fail to maintain PIXEL_UNPACK_BUFFER binding when enabling extension " + extension_name);
+ }
+}
+
+function runTests() {
+ debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=641643'>Chromium Issue 641642</a>");
+ runTest('EXT_color_buffer_float');
+ runTest('OES_texture_float_linear');
+}
+
+runTests();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html
new file mode 100644
index 0000000000..4ecbd6e2d3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html
@@ -0,0 +1,44 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL instanceof 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>
+</head>
+<body>
+<canvas id="canvas" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec4 color;
+void main()
+{
+ gl_FragColor = color;
+}
+</script>
+
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/instanceof-test.js"></script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html
new file mode 100644
index 0000000000..1a65dc57bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html
@@ -0,0 +1,61 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description("Tests calling WebGL 2 APIs without providing the necessary objects");
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+var shouldGenerateGLError = wtu.shouldGenerateGLError;
+
+
+for (let nullOrUndefined of [null, undefined]) {
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteQuery(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isQuery(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteSync(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isSync(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteTransformFeedback(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isTransformFeedback(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteSampler(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isSampler(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteVertexArray(${nullOrUndefined})`);
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isVertexArray(${nullOrUndefined})`);
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindSampler(0, ${nullOrUndefined})`);
+ shouldThrow(`gl.samplerParameteri(${nullOrUndefined}, gl.TEXTURE_MAG_FILTER, gl.NEAREST)`);
+ shouldThrow(`gl.samplerParameterf(${nullOrUndefined}, gl.TEXTURE_MAX_LOD, 1)`);
+ shouldThrow(`gl.getSamplerParameter(${nullOrUndefined}, gl.TEXTURE_MAX_LOD)`);
+
+ shouldThrow(`gl.waitSync(${nullOrUndefined}, 0, 0)`);
+ shouldThrow(`gl.clientWaitSync(${nullOrUndefined}, 0, 0)`);
+ shouldThrow(`gl.getSyncParameter(${nullOrUndefined}, gl.OBJECT_TYPE)`);
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, ${nullOrUndefined})`);
+ shouldThrow(`gl.transformFeedbackVaryings(${nullOrUndefined}, [], gl.SEPARATE_ATTRIBS)`);
+
+ shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindVertexArray(${nullOrUndefined})`);
+}
+
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html
new file mode 100644
index 0000000000..0551a1bd97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html
@@ -0,0 +1,114 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Tests deletion behavior for WebGL2 buffer, sampler, vertexArray and transformFeedback objects.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+var shouldGenerateGLError = wtu.shouldGenerateGLError;
+
+debug("");
+debug("buffer deletion");
+
+var bufferBaseUniform = gl.createBuffer();
+shouldBeNonNull("bufferBaseUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, bufferBaseUniform)");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "bufferBaseUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferBaseUniform)");
+shouldBeFalse("gl.isBuffer(bufferBaseUniform)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, bufferBaseUniform)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+
+var bufferBaseTransformFeedback = gl.createBuffer();
+shouldBeNonNull("bufferBaseTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferBaseTransformFeedback)");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "bufferBaseTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferBaseTransformFeedback)");
+shouldBeFalse("gl.isBuffer(bufferBaseTransformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferBaseTransformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+
+var bufferRangeUniform = gl.createBuffer();
+shouldBeNonNull("bufferRangeUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufferRangeUniform, 0, gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT)");
+shouldBe("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)", "bufferRangeUniform");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferRangeUniform)");
+shouldBeFalse("gl.isBuffer(bufferRangeUniform)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufferRangeUniform, 0, gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT)");
+shouldBeNull("gl.getParameter(gl.UNIFORM_BUFFER_BINDING)");
+
+var bufferRangeTransformFeedback = gl.createBuffer();
+shouldBeNonNull("bufferRangeTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferRangeTransformFeedback, 0, 4)");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)", "bufferRangeTransformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferRangeTransformFeedback)");
+shouldBeFalse("gl.isBuffer(bufferRangeTransformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufferRangeTransformFeedback, 0, 4)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING)");
+
+debug("");
+debug("sampler deletion");
+
+var sampler = gl.createSampler();
+shouldBeNonNull("sampler");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindSampler(0, sampler)");
+shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "sampler");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteSampler(sampler)");
+shouldBeFalse("gl.isSampler(sampler)");
+shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindSampler(0, sampler)");
+shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+
+debug("");
+debug("vertexArray deletion");
+
+var vertexArray = gl.createVertexArray();
+shouldBeNonNull("vertexArray");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindVertexArray(vertexArray)");
+shouldBe("gl.getParameter(gl.VERTEX_ARRAY_BINDING)", "vertexArray");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteVertexArray(vertexArray)");
+shouldBeFalse("gl.isVertexArray(vertexArray)");
+shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindVertexArray(vertexArray)");
+shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+
+debug("");
+debug("transformFeedback deletion");
+
+var transformFeedback = gl.createTransformFeedback();
+shouldBeNonNull("transformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback)");
+shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)", "transformFeedback");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTransformFeedback(transformFeedback)");
+shouldBeFalse("gl.isTransformFeedback(transformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback)");
+shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
new file mode 100644
index 0000000000..4befe35c93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html
@@ -0,0 +1,583 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Uninitialized GL Resources Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("Tests to check user code cannot access uninitialized data from GL resources.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", undefined, 2);
+if (!gl)
+ testFailed("Context created.");
+else
+ testPassed("Context created.");
+
+// This is the maximum size that will end up being allocated with the tests
+// currently written as they are. It could need to be increased later.
+var scratchBuffer = new ArrayBuffer(1024 * 1024 * 8 * 4);
+function zeroArrayBuffer(arr) {
+ for (var i = 0; i < arr.length; ++i) {
+ arr[i] = 0;
+ }
+}
+function getUint32Array(length) {
+ var arr = new Uint32Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getInt32Array(length) {
+ var arr = new Int32Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getUint8Array(length) {
+ var arr = new Uint8Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+function getInt8Array(length) {
+ var arr = new Int8Array(scratchBuffer, 0, length);
+ zeroArrayBuffer(arr);
+ return arr;
+}
+
+function setupTexture(target, texWidth, texHeight, texDepth) {
+ var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
+ var texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ if (is3d) {
+ gl.texImage3D(target, 0, gl.RGBA8, texWidth, texHeight, texDepth, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } else if (target == gl.TEXTURE_2D) {
+ gl.texImage2D(target, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ } else {
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ // this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
+ // into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
+ // with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
+
+ var badData = getUint8Array(texWidth * texHeight * texDepth * 4);
+ for (var i = 0; i < badData.length; ++i)
+ badData[i] = i % 255;
+
+ if (is3d) {
+ gl.texSubImage3D(target, 0, 0, 0, 0, texWidth, texHeight, texDepth, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ } else if (target == gl.TEXTURE_2D) {
+ gl.texSubImage2D(target, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ } else {
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+ }
+ gl.finish(); // make sure it has been uploaded
+
+ gl.deleteTexture(texture);
+ gl.finish(); // make sure it has been deleted
+
+ var texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ return texture;
+}
+
+function checkNonZeroPixels(texture, target, format, type, texWidth, texHeight, level, layer, exceptions) {
+ var tol = 2;
+ var is3d = (target == gl.TEXTURE_3D || target == gl.TEXTURE_2D_ARRAY);
+ switch (target) {
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_X:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case gl.TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case gl.TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ break;
+ default:
+ gl.bindTexture(target, null);
+ break;
+ }
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ if (is3d) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level, layer);
+ } else {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, texture, level);
+ }
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+
+ var data;
+ switch (type) {
+ case gl.UNSIGNED_INT:
+ data = getUint32Array(texWidth * texHeight * 4);
+ break;
+ case gl.INT:
+ data = getInt32Array(texWidth * texHeight * 4);
+ break;
+ case gl.UNSIGNED_BYTE:
+ default:
+ data = getUint8Array(texWidth * texHeight * 4);
+ break;
+ }
+ gl.readPixels(0, 0, texWidth, texHeight, format, type, data);
+
+ var k = 0;
+ var failed_exceptions = 0;
+ for (var y = 0; y < texHeight; ++y) {
+ for (var x = 0; x < texWidth; ++x) {
+ var index = (y * texWidth + x) * 4;
+ var is_exception = false;
+ for (var ii = 0; ii < exceptions.length; ++ii) {
+ if (exceptions[ii].x == x && exceptions[ii].y == y) {
+ is_exception = true;
+ if (Math.abs(data[index] - exceptions[ii].r) > tol ||
+ Math.abs(data[index + 1] - exceptions[ii].g) > tol ||
+ Math.abs(data[index + 2] - exceptions[ii].b) > tol ||
+ Math.abs(data[index + 3] - exceptions[ii].a) > tol) {
+ failed_exceptions++;
+ }
+ }
+ }
+ if (is_exception)
+ continue;
+ for (var i = 0; i < 4; ++i) {
+ if (data[index + i] != 0) {
+ k++;
+ }
+ }
+ }
+ }
+ var info = "Level = " + level;
+ if (is3d)
+ info += ", layer = " + layer;
+ info += " : ";
+ if (k) {
+ testFailed(info + "found " + k + " non-zero elements");
+ } else {
+ testPassed(info + "all data initialized");
+ }
+ if (exceptions.length > 0) {
+ if (failed_exceptions) {
+ testFailed(info + "found " + failed_exceptions + " elements incorrectly overwritten");
+ } else {
+ testPassed(info + "all initialized elements stay untouched");
+ }
+ }
+}
+
+function testTexImage3D() {
+
+ var max_3d_texture_size = Math.min(gl.getParameter(gl.MAX_3D_TEXTURE_SIZE), 1024);
+
+ var test_cases = [
+ // TEXTURE_3D + RGBA8
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 0, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_3D + RGBA8UI
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 0, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 128, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_3D + RGBA8I
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [ { x: 128, y: 255, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 256, // minimum MAX_3D_TEXTURE_SIZE is 256
+ height: 256,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [ { x: 128, y: 128, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_3D",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: max_3d_texture_size,
+ height: max_3d_texture_size,
+ depth: 4,
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 1023, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8",
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_BYTE,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8UI
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 1023, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 0, y: 0, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8UI",
+ format: gl.RGBA_INTEGER,
+ type: gl.UNSIGNED_BYTE,
+ read_type: gl.UNSIGNED_INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // TEXTURE_2D_ARRAY + RGBA8I
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [ { x: 512, y: 1023, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 1024,
+ height: 1024,
+ depth: 8,
+ exceptions: [],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [ { x: 63, y: 32, r: 108, g: 72, b: 36, a: 9 } ],
+ },
+ {
+ target: "TEXTURE_2D_ARRAY",
+ internal_format: "RGBA8I",
+ format: gl.RGBA_INTEGER,
+ type: gl.BYTE,
+ read_type: gl.INT,
+ width: 64,
+ height: 64,
+ depth: 256, // minimum MAX_ARRAY_TEXTURE_LAYERS is 256
+ exceptions: [],
+ },
+
+ // If more tests are added here, make sure to increase the size of
+ // scratchBuffer above, if needed.
+ ];
+
+ for (var ii = 0; ii < test_cases.length; ++ii) {
+ debug("");
+ var test = test_cases[ii];
+ debug("TexImage3D with target = " + test.target + ", internal_format = " + test.internal_format +
+ ", width = " + test.width + ", height = " + test.height + ", depth = " + test.depth);
+ var tex = setupTexture(gl[test.target], test.width, test.height, test.depth);
+ gl.texImage3D(gl[test.target], 0, gl[test.internal_format], test.width, test.height, test.depth, 0, test.format, test.type, null);
+ for (var jj = 0; jj < test.exceptions.length; ++jj) {
+ var exception = test.exceptions[jj];
+ var data;
+ switch (test.type) {
+ case gl.BYTE:
+ data = getInt8Array(4 * test.depth);
+ break;
+ case gl.UNSIGNED_BYTE:
+ data = getUint8Array(4 * test.depth);
+ break;
+ default:
+ assert(false);
+ }
+ for (var pixel = 0; pixel < test.depth; ++pixel) {
+ data[pixel * 4] = exception.r;
+ data[pixel * 4 + 1] = exception.g;
+ data[pixel * 4 + 2] = exception.b;
+ data[pixel * 4 + 3] = exception.a;
+ }
+ gl.texSubImage3D(gl[test.target], 0, exception.x, exception.y, 0, 1, 1, test.depth, test.format, test.type, data);
+ }
+ for (var layer = 0; layer < test.depth; ++layer)
+ checkNonZeroPixels(tex, gl[test.target], test.format, test.read_type, test.width, test.height, 0, layer, test.exceptions);
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+function testTexStorage2D() {
+ var targets = [ "TEXTURE_2D", "TEXTURE_CUBE_MAP" ];
+ var width = 512;
+ var height = 512;
+ var levels = 5;
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ debug("");
+ debug("Reading an uninitialized texture (texStorage2D) should succeed with all bytes set to 0 : target = " + targets[ii]);
+ var tex = setupTexture(gl[targets[ii]], width, height, 1);
+ gl.texStorage2D(gl[targets[ii]], levels, gl.RGBA8, width, height);
+ for (var level = 0; level < levels; ++level) {
+ if (gl[targets[ii]] == gl.TEXTURE_2D) {
+ checkNonZeroPixels(tex, gl[targets[ii]], gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ } else {
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ checkNonZeroPixels(tex, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, gl.RGBA, gl.UNSIGNED_BYTE, width, height, level, 0, []);
+ }
+ }
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+function testTexStorage3D() {
+ var targets = [ "TEXTURE_3D", "TEXTURE_2D_ARRAY" ];
+ var internal_formats = [ "RGBA8", "RGBA8UI", "RGBA8I" ];
+ var formats = [ gl.RGBA, gl.RGBA_INTEGER, gl.RGBA_INTEGER ];
+ var read_types = [ gl.UNSIGNED_BYTE, gl.UNSIGNED_INT, gl.INT ];
+ var width = 256; // minimum MAX_3D_TEXTURE_SIZE is 256
+ var height = 256; // minimum MAX_3D_TEXTURE_SIZE is 256
+ var depth = 8;
+ var levels = 5;
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ debug("");
+ debug("Reading an uninitialized texture (texStorage3D) should succeed with all bytes set to 0 : target = " + targets[ii]);
+ for (var jj = 0; jj < internal_formats.length; ++jj) {
+ debug("");
+ debug("Internal format : " + internal_formats[jj]);
+ var tex = setupTexture(gl[targets[ii]], width, height, depth);
+ gl.texStorage3D(gl[targets[ii]], levels, gl[internal_formats[jj]], width, height, depth);
+ var level_depth = depth;
+ for (var level = 0; level < levels; ++level) {
+ for (var layer = 0; layer < level_depth; ++layer) {
+ checkNonZeroPixels(tex, gl[targets[ii]], formats[jj], read_types[jj], width, height, level, layer, []);
+ }
+ if (gl[targets[ii]] == gl.TEXTURE_3D)
+ level_depth = Math.max(1, level_depth >> 1);
+ }
+ gl.deleteTexture(tex);
+ gl.finish();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+ }
+}
+
+testTexImage3D();
+testTexStorage2D();
+testTexStorage3D();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html
new file mode 100644
index 0000000000..8e89b4b78a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html
@@ -0,0 +1,320 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Tests texture uploads with ArrayBufferView+offsets");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(null, undefined, 2);
+console.log(gl.getParameter(gl.VERSION));
+
+////
+
+function arrToStr(arr) {
+ return "[" + arr.map(x => x.toString()).join(", ") + "]";
+}
+
+function shouldBeWas(shouldBe, was, info) {
+ var text = "Should be " + shouldBe + ", was " + was + ".";
+ if (info) {
+ text = info + ": " + text;
+ }
+
+ if (shouldBe == was) {
+ testPassed(text);
+ return true;
+ } else {
+ testFailed(text);
+ return false;
+ }
+}
+
+function shouldBeWasArr(shouldBe, was, info) {
+ if (shouldBe.length != was.length) {
+ testFailed("Length should be " + shouldBe.length + ", was " + was.length + ".");
+ return false;
+ }
+
+ return shouldBeWas(arrToStr(shouldBe), arrToStr(was), info);
+}
+
+////
+
+// Textures
+
+var fibArr = [
+ 0, 1, 1, 2,
+ 3, 5, 8, 13,
+ 21, 34, 55, 89,
+ 144, 233,
+];
+
+var fb = gl.createFramebuffer();
+
+function probeWithBadOffset(fnTest, info) {
+ fnTest(+(-1|0));
+ if (!gl.getError()) {
+ testFailed("Does not support " + info + " with offsets into views.");
+ return false;
+ }
+ return true;
+}
+
+// fn(view, offset, expectedError, expectedResult)
+
+do {
+ var readPixelView = new Uint8Array(4);
+ var testView = new Uint8Array(fibArr);
+
+ function testTexOrSubImage(funcName, fnTexOrSubImage) {
+ debug("");
+ debug(funcName);
+
+ var fnProbe = function(viewOffset) {
+ fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, viewOffset);
+ };
+
+ if (!probeWithBadOffset(fnProbe, funcName))
+ return;
+
+ for (var i = 0; i <= testView.length+1; i++) {
+ debug("offset=" + i);
+
+ fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, i);
+
+ var effectiveViewLen = testView.length - i;
+
+ if (effectiveViewLen >= 4) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeWasArr(testView.slice(i, i+4), readPixelView);
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ }
+ }
+
+ debug("");
+
+ var yellow565 = (0x1f << 11) | (0x3f << 5);
+ var cyan565 = (0x3f << 5) | 0x1f;
+ var arr565 = [yellow565, cyan565];
+ var view565 = new Uint16Array(arr565);
+
+ function rgb888to565(arr888) {
+ return ((arr888[0] >> 3) << 11) | ((arr888[1] >> 2) << 5) | (arr888[2] >> 3);
+ }
+
+ for (var i = 0; i <= arr565.length+1; i++) {
+ debug("rgb565, offset=" + i);
+
+ fnTexOrSubImage(gl.RGB, gl.UNSIGNED_SHORT_5_6_5, view565, i);
+
+ var effectiveViewLen = arr565.length - i;
+
+ if (effectiveViewLen >= 1) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView);
+ debug(arrToStr(readPixelView));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeWas(arr565[i], rgb888to565(readPixelView));
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ }
+ }
+ }
+
+ var fn2D = function(format, type, view, viewOffset) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, view, viewOffset);
+ }
+
+ var fnSub2D = function(format, type, view, viewOffset) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, format, type, view, viewOffset);
+ }
+
+ var fn3D = function(format, type, view, viewOffset) {
+ gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, view, viewOffset);
+ }
+
+ var fnSub3D = function(format, type, view, viewOffset) {
+ gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, null);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, format, type, view, viewOffset);
+ }
+
+ ////
+
+ var tex2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2d, 0);
+
+ testTexOrSubImage("texImage2D", fn2D);
+ testTexOrSubImage("texSubImage2D", fnSub2D);
+
+ ////
+
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0);
+
+ testTexOrSubImage("texImage3D", fn3D);
+ testTexOrSubImage("texSubImage3D", fnSub3D);
+} while (false);
+
+
+do {
+ var compressedFormat = 0;
+ var compressedByteCount;
+
+ if (gl.getExtension("WEBGL_compressed_texture_s3tc")) {
+ var e = gl.getExtension("WEBGL_compressed_texture_s3tc");
+ compressedFormat = e.COMPRESSED_RGB_S3TC_DXT1_EXT;
+ compressedByteCount = 8;
+ } else if (gl.getExtension("WEBGL_compressed_texture_etc")) {
+ var e = gl.getExtension("WEBGL_compressed_texture_etc");
+ compressedFormat = e.COMPRESSED_RGB8_ETC2;
+ compressedByteCount = 8;
+ } else {
+ debug("No compressed texture format found. Skipping compressedTex(Sub)Image tests.");
+ break;
+ }
+
+ ////
+
+ var view = new Uint8Array(compressedByteCount+1);
+
+ var fn2D = function(viewOffset) {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0,
+ view, viewOffset, compressedByteCount);
+ };
+
+ var fnSub2D = function(viewOffset) {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0,
+ view, 0, compressedByteCount);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, compressedFormat,
+ view, viewOffset, compressedByteCount);
+ };
+
+ var fn3D = function(viewOffset) {
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0,
+ view, viewOffset, compressedByteCount);
+ };
+
+ var fnSub3D = function(viewOffset) {
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0,
+ view, 0, compressedByteCount);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 1, compressedFormat,
+ view, viewOffset, compressedByteCount);
+ };
+
+ ////
+
+ var testFunc = function(funcName, fnToTest) {
+ debug("");
+ debug(funcName);
+
+ if (!probeWithBadOffset(fnToTest, funcName))
+ return;
+
+ var viewLength = view.length;
+ var subViewLength = compressedByteCount;
+
+ for (var i = 0; i <= viewLength+1; i++) {
+ debug("offset=" + i);
+
+ fnToTest(i);
+ var effectiveViewLen = viewLength - i;
+
+ if (effectiveViewLen >= subViewLength) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+ }
+ }
+ };
+
+ var tex2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+ testFunc("compressedTexImage2D" , fn2D );
+ testFunc("compressedTexSubImage2D", fnSub2D);
+
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex3d);
+ testFunc("compressedTexImage3D" , fn3D );
+ testFunc("compressedTexSubImage3D", fnSub3D);
+} while (false);
+
+do {
+ debug("");
+ debug("readPixels");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ var testColor = [10, 20, 30, 40];
+ gl.clearColor(testColor[0]/255.0,
+ testColor[1]/255.0,
+ testColor[2]/255.0,
+ testColor[3]/255.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var readPixelView = new Uint8Array(6);
+
+ function doReadPixels(viewOffset) {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView, viewOffset);
+ return readPixelView;
+ }
+
+ if (!probeWithBadOffset(doReadPixels, "doReadPixels"))
+ break;
+
+ for (var i = 0; i <= readPixelView.length+1; i++) {
+ debug("offset=" + i);
+ var res = doReadPixels(i);
+ var effectiveViewLen = readPixelView.length - i;
+
+ if (effectiveViewLen >= 4) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeWasArr(testColor, res.slice(i,i+4));
+
+ } else if (effectiveViewLen >= 0) {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+ }
+ }
+} while (false);
+
+debug("")
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/00_test_list.txt
new file mode 100644
index 0000000000..2aff6e699d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/00_test_list.txt
@@ -0,0 +1,8 @@
+context-creation.html
+context-creation-worker.html
+methods-2.html
+methods-2-worker.html
+--min-version 2.0.1 offscreencanvas-query.html
+--min-version 2.0.1 offscreencanvas-sync.html
+--min-version 2.0.1 offscreencanvas-timer-query.html
+--min-version 2.0.1 offscreencanvas-transfer-image-bitmap.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.html
new file mode 100644
index 0000000000..9362a0a4ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Context Creation Test for OffscreenCanvas in a worker</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("This test ensures that the WebGL context can be created on an OffscreenCanvas.");
+
+if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+} else {
+ var worker = new Worker('context-creation-worker.js');
+ worker.postMessage("Start worker");
+ worker.onmessage = function(e) {
+ if (e.data == "Test passed") {
+ testPassed("All tests have passed");
+ } else {
+ testFailed("Some tests failed");
+ }
+ finishTest();
+ }
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.js b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.js
new file mode 100644
index 0000000000..67bf406482
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.js
@@ -0,0 +1,13 @@
+/*
+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.
+*/
+
+importScripts("../../js/tests/canvas-tests-utils.js");
+self.onmessage = function(e) {
+ if (contextCreation('webgl2'))
+ self.postMessage("Test passed");
+ else
+ self.postMessage("Test failed");
+};
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation.html
new file mode 100644
index 0000000000..c3f1d2657d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation.html
@@ -0,0 +1,36 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Context Creation 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="../../js/tests/canvas-tests-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("This test ensures that the WebGL2 context can be created on an OffscreenCanvas.");
+
+if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+} else {
+ if (contextCreation('webgl2')) {
+ testPassed("WebGL2 context created correctly.");
+ } else {
+ testFailed("WebGL2 context creation failed");
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.html
new file mode 100644
index 0000000000..582fd556a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Methods Test for OffscreenCanvas in a worker</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("This test ensures that the WebGL context created for an OffscreenCanvas has all the methods in the specification.");
+
+if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+} else {
+ var worker = new Worker('methods-2-worker.js');
+ worker.postMessage("Start worker");
+ worker.onmessage = function(e) {
+ if (e.data == "Test passed") {
+ testPassed("All test have passed");
+ } else {
+ testFailed("Some tests failed");
+ }
+ finishTest();
+ }
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.js b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.js
new file mode 100644
index 0000000000..94c1378f0d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.js
@@ -0,0 +1,13 @@
+/*
+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.
+*/
+
+importScripts("../../js/tests/canvas-tests-utils.js");
+self.onmessage = function(e) {
+ if (testAPIs('webgl2'))
+ self.postMessage("Test passed");
+ else
+ self.postMessage("Test failed");
+}
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2.html
new file mode 100644
index 0000000000..c4250f5724
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2.html
@@ -0,0 +1,36 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Methods Test for OffscreenCanvas in a worker</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/canvas-tests-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("This test ensures that the WebGL context has all the methods in the specification.");
+
+if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+} else {
+ if (testAPIs('webgl2')) {
+ testPassed("All WebGL2 methods found");
+ } else {
+ testFailed("Some WebGL2 methods not found");
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-query.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-query.html
new file mode 100644
index 0000000000..8d9e92e511
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-query.html
@@ -0,0 +1,79 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test for Query objects with OffscreenCanvas</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script id='myWorker' type='text/worker'>
+ function tick(callback) {
+ function tickImpl() {
+ const res = callback();
+ if (res) {
+ if (requestAnimationFrame) {
+ requestAnimationFrame(tickImpl);
+ } else {
+ setTimeout(tickImpl, 10);
+ }
+ }
+ }
+
+ tickImpl();
+ }
+
+ self.onmessage = function(e) {
+ let canvas = new OffscreenCanvas(128, 128);
+ let gl = canvas.getContext("webgl2");
+ let query = gl.createQuery();
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, query);
+ gl.endQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE);
+ gl.clearColor(0.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ tick(function() {
+ const status = gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
+ if (status) {
+ self.postMessage("PASSED - query object completed successfully from worker");
+ return false;
+ } else {
+ const err = gl.getError();
+ if (err != 0) {
+ self.postMessage("FAILED - GL error " + err);
+ return false;
+ }
+ }
+ return true;
+ });
+ };
+ </script>
+ <script>
+ "use strict";
+ description("This test ensures that query objects work with the WebGL 2.0 context created via OffscreenCanvas.");
+ if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+ } else {
+ var blob = new Blob([document.getElementById("myWorker").textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.onmessage = function(msg) {
+ if (msg.data.startsWith("PASSED")) {
+ testPassed(msg.data);
+ } else {
+ testFailed(msg.data);
+ }
+ finishTest();
+ }
+ worker.postMessage("Start Worker");
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-sync.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-sync.html
new file mode 100644
index 0000000000..dc70a60bbd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-sync.html
@@ -0,0 +1,77 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test for Sync objects with OffscreenCanvas</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script id='myWorker' type='text/worker'>
+ function tick(callback) {
+ function tickImpl() {
+ const res = callback();
+ if (res) {
+ if (requestAnimationFrame) {
+ requestAnimationFrame(tickImpl);
+ } else {
+ setTimeout(tickImpl, 10);
+ }
+ }
+ }
+
+ tickImpl();
+ }
+
+ self.onmessage = function(e) {
+ let canvas = new OffscreenCanvas(128, 128);
+ let gl = canvas.getContext("webgl2");
+ let sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ gl.clearColor(0.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ tick(function() {
+ const status = gl.getSyncParameter(sync, gl.SYNC_STATUS);
+ if (status == gl.SIGNALED) {
+ self.postMessage("PASSED - Sync object signaled successfully from worker");
+ return false;
+ } else {
+ const err = gl.getError();
+ if (err != 0) {
+ self.postMessage("FAILED - GL error " + err);
+ return false;
+ }
+ }
+ return true;
+ });
+ };
+ </script>
+ <script>
+ "use strict";
+ description("This test ensures that sync objects work with the WebGL 2.0 context created via OffscreenCanvas.");
+ if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+ } else {
+ var blob = new Blob([document.getElementById("myWorker").textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.onmessage = function(msg) {
+ if (msg.data.startsWith("PASSED")) {
+ testPassed(msg.data);
+ } else {
+ testFailed(msg.data);
+ }
+ finishTest();
+ }
+ worker.postMessage("Start Worker");
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-timer-query.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-timer-query.html
new file mode 100644
index 0000000000..8714956fd1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-timer-query.html
@@ -0,0 +1,84 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test for Timer Query objects with OffscreenCanvas</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script id='myWorker' type='text/worker'>
+ function tick(callback) {
+ function tickImpl() {
+ const res = callback();
+ if (res) {
+ if (requestAnimationFrame) {
+ requestAnimationFrame(tickImpl);
+ } else {
+ setTimeout(tickImpl, 10);
+ }
+ }
+ }
+
+ tickImpl();
+ }
+
+ self.onmessage = function(e) {
+ let canvas = new OffscreenCanvas(128, 128);
+ let gl = canvas.getContext("webgl2");
+ let ext = gl.getExtension("EXT_disjoint_timer_query_webgl2");
+ if (!ext) {
+ self.postMessage("PASSED - no EXT_disjoint_timer_query_webgl2 extension - this is legal");
+ return false;
+ }
+ let query = gl.createQuery();
+ gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
+ gl.endQuery(ext.TIME_ELAPSED_EXT);
+ gl.clearColor(0.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ tick(function() {
+ const status = gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
+ if (status) {
+ self.postMessage("PASSED - timer query object completed successfully on worker");
+ return false;
+ } else {
+ const err = gl.getError();
+ if (err != 0) {
+ self.postMessage("FAILED - GL error " + err);
+ return false;
+ }
+ }
+ return true;
+ });
+ };
+ </script>
+ <script>
+ "use strict";
+ description("This test ensures that timer query objects work with the WebGL 2.0 context created via OffscreenCanvas.");
+ if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+ } else {
+ var blob = new Blob([document.getElementById('myWorker').textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+ worker.onmessage = function(msg) {
+ if (msg.data.startsWith("PASSED")) {
+ testPassed(msg.data);
+ } else {
+ testFailed(msg.data);
+ }
+ finishTest();
+ }
+ worker.postMessage("Start Worker");
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html
new file mode 100644
index 0000000000..cb9232b65a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html
@@ -0,0 +1,50 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test for OffscreenCanvas TransferToImageBitmap</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../js/tests/offscreencanvas-transfer-image-bitmap.js"></script>
+</head>
+<body>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ var canvas = new OffscreenCanvas(128, 128);
+ var gl = canvas.getContext("webgl2");
+ gl.clearColor(1.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var image = canvas.transferToImageBitmap();
+
+ self.postMessage({ bitmap: image },
+ [ image ]);
+ };
+ </script>
+ <script>
+ "use strict";
+ description("This test ensures that the transferToImageBitmap function of OffscreenCanvas webgl2 context is functional.");
+ if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+ } else {
+ var blob = new Blob([document.getElementById('myWorker').textContent]);
+ var worker = new Worker(URL.createObjectURL(blob));
+
+ worker.onmessage = function(msg) {
+ testTransferToImageBitmap("webgl2", msg.data.bitmap);
+ finishTest();
+ }
+ worker.postMessage("Start Worker");
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/programs/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/00_test_list.txt
new file mode 100644
index 0000000000..c88d255dab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/00_test_list.txt
@@ -0,0 +1,4 @@
+active-built-in-attribs.html
+--min-version 2.0.1 get-uniform-indices.html
+gl-get-frag-data-location.html
+--min-version 2.0.1 sampler-uniforms.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/programs/active-built-in-attribs.html b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/active-built-in-attribs.html
new file mode 100644
index 0000000000..68b62cdcf2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/active-built-in-attribs.html
@@ -0,0 +1,86 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Tests: Verify validation for active built-in attribs</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 64px; height: 64px;"> </canvas>
+<div id="console"></div>
+<script id="vs" type="x-shader/x-vertex">#version 300 es
+void main() {
+ gl_Position = vec4(gl_VertexID % 2, (gl_VertexID/2) % 2, 0, 1);
+}
+</script>
+
+<script id="fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 fragColor;
+void main() {
+ fragColor = vec4(0, 1, 0, 1);
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies validation for active built-in attribs.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ runTests();
+}
+
+var activeInfo, attribLoc;
+
+function runTests() {
+ var prog = wtu.setupProgram(gl, ["vs", "fs"]);
+ if (!prog) {
+ testFailed("Set up program failed");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
+
+ var numActive = gl.getProgramParameter(prog, gl.ACTIVE_ATTRIBUTES);
+ if (numActive != 1) {
+ testFailed('ACTIVE_ATTRIBUTES should be 1.');
+ return;
+ }
+ testPassed('ACTIVE_ATTRIBUTES should be 1.');
+
+ activeInfo = gl.getActiveAttrib(prog, 0);
+ if (!activeInfo) {
+ testFailed('getActiveAttrib should return an info object.');
+ return;
+ }
+
+ shouldBe('activeInfo.name', '"gl_VertexID"');
+ attribLoc = gl.getAttribLocation(prog, 'gl_VertexID');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be able to request the location of a built-in.");
+ shouldBe('attribLoc', '-1');
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/programs/get-uniform-indices.html b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/get-uniform-indices.html
new file mode 100644
index 0000000000..d42add065c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/get-uniform-indices.html
@@ -0,0 +1,121 @@
+<!--
+Copyright (c) 2022 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("This test verifies getUniformIndices behaviors.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+
+const e_canvas = document.createElement('canvas');
+const gl = e_canvas.getContext('webgl2');
+
+const VSRC = `\
+ #version 300 es
+ precision mediump float;
+ uniform float u_vert_scalar;
+ uniform float u_vert_arr[3];
+ uniform float u_both_scalar;
+ uniform float u_both_arr[3];
+ void main() {
+ gl_Position = vec4(0, 0, 0, 1);
+ gl_Position.r += u_vert_scalar;
+ gl_Position.r += u_vert_arr[1];
+ gl_Position.r += u_both_scalar;
+ gl_Position.r += u_both_arr[1];
+ }
+`;
+
+const FSRC = `\
+ #version 300 es
+ precision mediump float;
+ uniform float u_frag_scalar;
+ uniform float u_frag_arr[3];
+ uniform float u_both_scalar;
+ uniform float u_both_arr[3];
+ out vec4 o_frag_color;
+ void main() {
+ o_frag_color = vec4(0, 0, 0, 1);
+ o_frag_color.r += u_frag_scalar;
+ o_frag_color.r += u_frag_arr[1];
+ o_frag_color.r += u_both_scalar;
+ o_frag_color.r += u_both_arr[1];
+ }
+`;
+
+(() => {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+
+ window.prog = wtu.setupProgram(gl, [VSRC, FSRC]);
+ if (!prog) {
+ testFailed("Setting up program failed");
+ return;
+ }
+ let err = gl.getError();
+ if (err) throw err;
+
+ const IS_ACTIVE_BY_NAME = {
+ 'u_vert_scalar' : true,
+ 'u_vert_scalar[0]': false,
+ 'u_vert_arr' : true,
+ 'u_vert_arr[0]' : true, // Even if the [0] is unused, the name enumerated
+ // via getActiveUniforms for this array is 'u_vert_arr[0]'.
+ 'u_vert_arr[1]' : false,
+
+ 'u_frag_scalar' : true,
+ 'u_frag_scalar[0]': false,
+ 'u_frag_arr' : true,
+ 'u_frag_arr[0]' : true,
+ 'u_frag_arr[1]' : false,
+
+ 'u_both_scalar' : true,
+ 'u_both_scalar[0]': false,
+ 'u_both_arr' : true,
+ 'u_both_arr[0]' : true,
+ 'u_both_arr[1]' : false,
+ };
+ const NAMES = Object.keys(IS_ACTIVE_BY_NAME);
+ const active_ids = gl.getUniformIndices(prog, NAMES);
+
+ err = gl.getError();
+ if (err) throw err;
+
+ NAMES.forEach((name, i) => {
+ const active_id_was = active_ids[i];
+ const is_active_expected = IS_ACTIVE_BY_NAME[name];
+ const is_active_was = active_id_was != gl.INVALID_INDEX;
+ expectTrue(is_active_was == is_active_expected,
+ `getUniformIndices([, '${name}' ,]) -> [, ${active_id_was} ,], should be [, ${is_active_expected ? '0<=N<INVALID_INDEX' : 'INVALID_INDEX'} ,]`);
+ if (is_active_was) {
+ const info = gl.getActiveUniform(prog, active_id_was);
+ expectTrue(info.name.startsWith(name), `'${info.name}'.startsWith('${name}')`);
+ }
+ });
+})();
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/programs/gl-get-frag-data-location.html b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/gl-get-frag-data-location.html
new file mode 100644
index 0000000000..1e006ebd28
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/gl-get-frag-data-location.html
@@ -0,0 +1,121 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Tests: Verify getFragDataLocation</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 4px; height: 4px;"> </canvas>
+<div id="console"></div>
+<script id="vs" type="x-shader/x-vertex">#version 300 es
+void main() {
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+
+<script id="fs" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+layout(location = 2) out vec4 fragColor0;
+layout(location = 0) out vec4 fragColor1;
+void main() {
+ fragColor0 = vec4(0, 1, 0, 1);
+ fragColor1 = vec4(1, 0, 0, 1);
+}
+</script>
+
+<script id="fs-array" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 fragColor[2];
+void main() {
+ fragColor[0] = vec4(0, 1, 0, 1);
+ fragColor[1] = vec4(1, 0, 0, 1);
+}
+</script>
+
+<script id="vs-es2" type="x-shader/x-vertex">
+void main() {
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+<script id="fs-es2" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(0, 1, 0, 1);
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies getFragDataLocation behaviors.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ runTests();
+}
+
+function runTests() {
+ window.program = wtu.setupProgram(gl, ["vs", "fs"]);
+ window.programArray = wtu.setupProgram(gl, ["vs", "fs-array"]);
+ window.programEs2 = wtu.setupProgram(gl, ["vs-es2", "fs-es2"]);
+ if (!program || !programArray || !programEs2) {
+ testFailed("Set up program failed");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
+
+ shouldBe("gl.getFragDataLocation(program, 'gl_FragColor')", "-1");
+ shouldBe("gl.getFragDataLocation(programArray, 'gl_FragColor')", "-1");
+ shouldBe("gl.getFragDataLocation(programEs2, 'gl_FragColor')", "-1");
+ shouldBe("gl.getFragDataLocation(program, 'gl_FragData')", "-1");
+ shouldBe("gl.getFragDataLocation(programArray, 'gl_FragData')", "-1");
+ shouldBe("gl.getFragDataLocation(programEs2, 'gl_FragData')", "-1");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from gl_* queries");
+
+ var loc0 = gl.getFragDataLocation(program, "fragColor0");
+ var loc1 = gl.getFragDataLocation(program, "fragColor1");
+ if (loc0 != 2 || loc1 != 0) {
+ testFailed("Fail to query scalar output variable locations, " +
+ "expected: fragColor0->2, fragColor1->0, " +
+ "got: fragColor0->" + loc0 + ", fragColor1->" + loc1);
+ } else {
+ testPassed("getFragDataLocation on scalar variables works fine");
+ }
+
+ var loc = gl.getFragDataLocation(programArray, "fragColor");
+ loc0 = gl.getFragDataLocation(programArray, "fragColor[0]");
+ loc1 = gl.getFragDataLocation(programArray, "fragColor[1]");
+ if (loc < 0 || loc0 < 0 || loc1 < 0 || loc != loc0 || loc0 + 1 != loc1) {
+ testFailed("Fail to query scalar output variable locations, " +
+ "expected: fragColor->0, fragColor[0]->0, fragColor[1]->1, " +
+ "got: fragColor->" + loc + ", fragColor[0]->" + loc0 + ", fragColor[1]->" + loc1);
+ } else {
+ testPassed("getFragDataLocation on variable arrays works fine");
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from testing");
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/programs/sampler-uniforms.html b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/sampler-uniforms.html
new file mode 100644
index 0000000000..4df60d3ee3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/programs/sampler-uniforms.html
@@ -0,0 +1,111 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 getActiveUniform conformance 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>
+</head>
+<body>
+<canvas id="example" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+void main()
+{
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform mediump $type uniform0;
+out vec4 myFragColor;
+void main()
+{
+ myFragColor = vec4(0,$access,0,1);
+}
+</script>
+<script>
+"use strict";
+description("Tests getActiveUniform for various types");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var tests = [
+ { glType: gl.SAMPLER_2D, size: 1, type: 'sampler2D', access: 'texture(uniform0, vec2(0,0)).x'},
+ { glType: gl.SAMPLER_CUBE, size: 1, type: 'samplerCube', access: 'texture(uniform0, vec3(0,1,0)).x'},
+ { glType: gl.SAMPLER_3D, size: 1, type: 'sampler3D', access: 'texture(uniform0, vec3(0,1,0)).x'},
+ { glType: gl.SAMPLER_2D_ARRAY, size: 1, type: 'sampler2DArray', access: 'texture(uniform0, vec3(0,1,0)).x'},
+
+ { glType: gl.SAMPLER_2D_SHADOW, size: 1, type: 'sampler2DShadow', access: 'texture(uniform0, vec3(0,1,0))'},
+ { glType: gl.SAMPLER_CUBE_SHADOW, size: 1, type: 'samplerCubeShadow', access: 'texture(uniform0, vec4(0,1,0,0))'},
+ { glType: gl.SAMPLER_2D_ARRAY_SHADOW, size: 1, type: 'sampler2DArrayShadow', access: 'texture(uniform0, vec4(0,1,0,0))'},
+
+ { glType: gl.INT_SAMPLER_2D, size: 1, type: 'isampler2D', access: 'texture(uniform0, vec2(0,0)).x'},
+ { glType: gl.INT_SAMPLER_CUBE, size: 1, type: 'isamplerCube', access: 'texture(uniform0, vec3(0,1,0)).x'},
+ { glType: gl.INT_SAMPLER_3D, size: 1, type: 'isampler3D', access: 'texture(uniform0, vec3(0,1,0)).x'},
+ { glType: gl.INT_SAMPLER_2D_ARRAY, size: 1, type: 'isampler2DArray', access: 'texture(uniform0, vec3(0,1,0)).x'},
+
+ { glType: gl.UNSIGNED_INT_SAMPLER_2D, size: 1, type: 'usampler2D', access: 'texture(uniform0, vec2(0,0)).x'},
+ { glType: gl.UNSIGNED_INT_SAMPLER_CUBE, size: 1, type: 'usamplerCube', access: 'texture(uniform0, vec3(0,1,0)).x'},
+ { glType: gl.UNSIGNED_INT_SAMPLER_3D, size: 1, type: 'usampler3D', access: 'texture(uniform0, vec3(0,1,0)).x'},
+ { glType: gl.UNSIGNED_INT_SAMPLER_2D_ARRAY, size: 1, type: 'usampler2DArray', access: 'texture(uniform0, vec3(0,1,0)).x'},
+];
+
+var vs = wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER);
+var source = document.getElementById('fshader').text;
+
+function createProgram(type, access) {
+ var fs = wtu.loadShader(
+ gl,
+ source.replace('$type', type).replace('$access', access),
+ gl.FRAGMENT_SHADER);
+ var program = wtu.setupProgram(gl, [vs, fs]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from setup");
+ return program;
+}
+
+for (var tt = 0; tt < tests.length; ++tt) {
+ var t = tests[tt];
+ debug("");
+ debug("Testing uniform sampler type : " + t.type);
+ var program = createProgram(t.type, t.access);
+ var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
+ assertMsg(numUniforms >= 1, "at least 1 sampler uniform");
+ var found = false;
+ for (var ii = 0; ii < numUniforms; ++ii) {
+ var info = gl.getActiveUniform(program, ii);
+ if (info.name == 'uniform0') {
+ found = true;
+ assertMsg(info.type == t.glType,
+ "type must be " + wtu.glEnumToString(gl, t.glType) + " was " +
+ wtu.glEnumToString(gl, info.type));
+ assertMsg(info.size == t.size,
+ "size must be " + t.size + ' was ' + info.size);
+ }
+ }
+ assertMsg(found, "uniform 'uniform0' should exist");
+ var loc = gl.getUniformLocation(program, 'uniform0');
+ assertMsg(loc != null, "getUniformLocation must return non null");
+ gl.uniform1i(loc, tt + 1);
+ var val = gl.getUniform(program, loc);
+ assertMsg(val == tt + 1, "getUniform must return set value");
+}
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors running the tests");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/query/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/query/00_test_list.txt
new file mode 100644
index 0000000000..c40921bf88
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/query/00_test_list.txt
@@ -0,0 +1,2 @@
+occlusion-query.html
+query.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/query/occlusion-query.html b/dom/canvas/test/webgl-conf/checkout/conformance2/query/occlusion-query.html
new file mode 100644
index 0000000000..3655ed8783
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/query/occlusion-query.html
@@ -0,0 +1,137 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of occlusion query objects.");
+
+debug("");
+
+var tests = [];
+var currentTest;
+var currentTestIndex = 0;
+var numberOfTestAttempts = 4; // Just to stress implementations a bit more.
+var query;
+var numberOfCompletionAttempts = 0;
+
+function setupTests(gl) {
+ tests = [
+ {
+ target: gl.ANY_SAMPLES_PASSED_CONSERVATIVE,
+ name: "ANY_SAMPLES_PASSED_CONSERVATIVE",
+ result: 1,
+ },
+ {
+ target: gl.ANY_SAMPLES_PASSED,
+ name: "ANY_SAMPLES_PASSED",
+ result: 1,
+ },
+ ];
+}
+
+function runOcclusionQueryTest() {
+ currentTest = tests[currentTestIndex];
+
+ debug("");
+ debug("Testing completion and behavior of " + currentTest.name + " occlusion query");
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ var program = wtu.setupSimpleColorProgram(gl, 0);
+ gl.uniform4f(gl.getUniformLocation(program, "u_color"), 0, 1, 0, 1);
+ wtu.setupUnitQuad(gl, 0);
+ query = gl.createQuery();
+ var target = currentTest.target;
+ gl.beginQuery(target, query);
+ wtu.drawUnitQuad(gl);
+ gl.endQuery(target);
+
+ // Verify as best as possible that the implementation doesn't
+ // allow a query's result to become available the same frame, by
+ // spin-looping for some time and ensuring that none of the
+ // queries' results become available.
+ var numEarlyTests = 20000;
+ while (--numEarlyTests > 0) {
+ gl.finish();
+ if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) {
+ testFailed("Query's result became available too early");
+ finishTest();
+ return;
+ }
+ }
+
+ testPassed("Query's result didn't become available too early");
+ numberOfCompletionAttempts = 0;
+ requestAnimationFrame(completeOcclusionQueryTest);
+}
+
+function completeOcclusionQueryTest() {
+ ++numberOfCompletionAttempts;
+
+ if (numberOfCompletionAttempts > 500) {
+ testFailed("Query didn't become available in a reasonable time");
+ finishTest();
+ return;
+ }
+
+ if (!gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) {
+ requestAnimationFrame(completeOcclusionQueryTest);
+ return;
+ }
+
+ // No matter whether the test was run with ANY_SAMPLES_PASSED or
+ // ANY_SAMPLES_PASSED_CONSERVATIVE, the query object should always
+ // report a non-zero result.
+ var result = gl.getQueryParameter(query, gl.QUERY_RESULT);
+ if (result == currentTest.result) {
+ testPassed("Occlusion query " + currentTest.name + " returned a correct result (" + result + ")");
+ } else {
+ testFailed("Occlusion query " + currentTest.name + " returned an incorrect result " + result + " (expected " + currentTest.result + ")");
+ }
+
+ gl.deleteQuery(query);
+ query = null;
+
+ ++currentTestIndex;
+ if (currentTestIndex >= tests.length) {
+ --numberOfTestAttempts;
+ if (numberOfTestAttempts == 0) {
+ finishTest();
+ } else {
+ currentTestIndex = 0;
+ requestAnimationFrame(runOcclusionQueryTest);
+ }
+ } else {
+ requestAnimationFrame(runOcclusionQueryTest);
+ }
+}
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ setupTests(gl);
+ runOcclusionQueryTest();
+}
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/query/query.html b/dom/canvas/test/webgl-conf/checkout/conformance2/query/query.html
new file mode 100644
index 0000000000..03a1124be7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/query/query.html
@@ -0,0 +1,167 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+attribute vec4 a_color;
+varying vec4 v_color;
+void main(void) {
+ gl_Position = a_position;
+ v_color = a_color;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 v_color;
+void main(void) {
+ gl_FragColor = v_color;
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the functionality of the Query objects.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var q1 = null;
+var q2 = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runCurrentQueryTest();
+ runObjectTest();
+ // TODO: Test buffer binding, drawing, etc.
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runCurrentQueryTest() {
+ debug("");
+ debug("Testing Beginning, Ending, and checking the state of query objects");
+
+ shouldBe("gl.ANY_SAMPLES_PASSED", "0x8C2F");
+ shouldBe("gl.ANY_SAMPLES_PASSED_CONSERVATIVE", "0x8D6A");
+ shouldBe("gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN", "0x8C88");
+
+ gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "ANY_SAMPLES_PASSED query should succeed");
+
+ gl.getQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, gl.CURRENT_QUERY);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "ANY_SAMPLES_PASSED query should succeed");
+
+ gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "ANY_SAMPLES_PASSED query should succeed");
+
+ // Default value is null
+ shouldBeNull("gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY)");
+ shouldBeNull("gl.getQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, gl.CURRENT_QUERY)");
+ shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
+
+ q1 = gl.createQuery();
+ q2 = gl.createQuery();
+ shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
+ shouldBeTrue("gl.isQuery(q1)");
+ shouldBe("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)", "q1");
+
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Can't begin a query while one is already active");
+ shouldBe("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)", "q1");
+
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
+
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Can't end a query if one is not active");
+
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, q1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Can't re-use query objects for incompatible targets");
+ shouldBeNull("gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY)");
+
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, q2);
+ shouldBe("gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY)", "q2");
+
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, q2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Can't call beginQuery on an already active query object");
+ shouldBeNull("gl.getQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, gl.CURRENT_QUERY)");
+
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be able to have multiple unrelated query types active at once");
+ shouldBe("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)", "q1");
+
+ gl.deleteQuery(q1);
+ gl.deleteQuery(q2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "deleting queries should not produce errors");
+
+ shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
+ shouldBeNull("gl.getQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, gl.CURRENT_QUERY)");
+
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "beginning a deleted query object");
+ shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
+
+ debug("");
+ debug("Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1636525");
+
+ q1 = gl.createQuery();
+ gl.deleteQuery(q1);
+ wtu.glErrorShouldBe(gl, 0, "DeleteQuery after CreateQuery");
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Begining a deleted query");
+ shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
+}
+
+function runObjectTest() {
+ debug("");
+ debug("Testing object creation");
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should have no previous errors");
+
+ q1 = gl.createQuery();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createQuery should not set an error");
+ shouldBeNonNull("q1");
+
+ // Expect false if never bound
+ shouldBeFalse("gl.isQuery(q1)");
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
+ shouldBeTrue("gl.isQuery(q1)");
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ shouldBeTrue("gl.isQuery(q1)");
+ gl.deleteQuery(q1);
+ shouldBeFalse("gl.isQuery(q1)");
+
+ shouldBeFalse("gl.isQuery(null)");
+
+ q1 = null;
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/00_test_list.txt
new file mode 100644
index 0000000000..d5fe8b664e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/00_test_list.txt
@@ -0,0 +1,5 @@
+--min-version 2.0.1 format-r11f-g11f-b10f.html
+read-pixels-from-fbo-test.html
+--min-version 2.0.1 read-pixels-from-rgb8-into-pbo-bug.html
+read-pixels-into-pixel-pack-buffer.html
+read-pixels-pack-parameters.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/format-r11f-g11f-b10f.html b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/format-r11f-g11f-b10f.html
new file mode 100644
index 0000000000..5534a6884f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/format-r11f-g11f-b10f.html
@@ -0,0 +1,266 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test Format R11F_G11F_B10F</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec2 pos;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+
+void main() {
+ gl_Position = vec4(pos, 0.0, 1.0);
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform vec3 u_color;
+uniform vec3 u_tol;
+uniform sampler2D u_tex;
+varying vec2 texCoord;
+
+void main() {
+ vec4 sample = texture2D(u_tex, texCoord);
+ vec3 rgb = sample.xyz;
+ if (abs(rgb[0] - u_color[0]) > u_tol[0] ||
+ abs(rgb[1] - u_color[1]) > u_tol[1] ||
+ abs(rgb[2] - u_color[2]) > u_tol[2]) {
+ gl_FragColor = vec4(1, 0, 0, 1);
+ } else {
+ gl_FragColor = vec4(0, 1, 0, 1);
+ }
+}
+</script>
+<script>
+"use strict";
+description("This tests format R11F_G11F_B10F works as expected");
+debug("MacOSX driver bug. See https://github.com/KhronosGroup/WebGL/issues/1832");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+
+var testValues = [100, 1000, 2047, 2500, 4095, 5000,
+ 8191, 8192, 10000, 16383, 16384];
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+ if (gl.getExtension("EXT_color_buffer_float")) {
+ testPassed("Extension EXT_color_buffer_float is available");
+
+ testRenderbufferReadback(4, 4);
+ testTextureReadback(4, 4);
+ testTextureSampling(4, 4);
+ } else {
+ testPassed("Extension EXT_color_buffer_float is unavailable - this is legal");
+ }
+}
+
+function setupColor(testR, testG, testB, value) {
+ var data = new Float32Array(4);
+ data[0] = testR ? value : 0;
+ data[1] = testG ? value : 0;
+ data[2] = testB ? value : 0;
+ data[3] = 1; // Doesn't really matter for RGB formats.
+ return data;
+}
+
+// The definition of <Unsinged 11-Bit Floating-Point Number> in GLES 3.0.4:
+// https://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.4.pdf#nameddest=section-2.1.3
+// The definition of <Unsinged 10-Bit Floating-Point Number> in GLES 3.0.4:
+// https://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.4.pdf#nameddest=section-2.1.4
+function setTolerance (testR, testG, testB, value) {
+ var tol = new Float32Array(3);
+ var exponent;
+ if (value < Math.pow(2, -14)) {
+ exponent = -14;
+ } else {
+ exponent = Math.floor(Math.log(value) / Math.LN2);
+ }
+ var tol11F = Math.pow(2, exponent) / 64;
+ var tol10F = Math.pow(2, exponent) / 32;
+ tol[0] = testR ? tol11F : 0;
+ tol[1] = testG ? tol11F : 0;
+ tol[2] = testB ? tol10F : 0;
+ return tol;
+}
+
+function clearAndVerifyColor(width, height, testR, testG, testB, value) {
+ var data = setupColor(testR, testG, testB, value);
+ var tol = setTolerance(testR, testG, testB, value);
+ gl.clearBufferfv(gl.COLOR, 0, data);
+ var buffer = new Float32Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.FLOAT, buffer);
+ for (var ii = 0; ii < width * height; ++ii) {
+ var pixel = [buffer[ii * 4], buffer[ii * 4 + 1], buffer[ii * 4 + 2], buffer[ii * 4 + 3]];
+ if (isNaN(pixel[0]) || isNaN(pixel[1]) || isNaN(pixel[2]) ||
+ Math.abs(pixel[0] - data[0]) > tol[0] ||
+ Math.abs(pixel[1] - data[1]) > tol[1] ||
+ Math.abs(pixel[2] - data[2]) > tol[2]) {
+ testFailed("ReadPixels " + ii + " : got [" + pixel + "], expected [" + data + "], tol [" + tol + "]");
+ return;
+ }
+ }
+ testPassed("ReadPixels success : [" + data + "]");
+}
+
+function clearDrawAndVerifyColor(fbo, program, testR, testG, testB, value) {
+ var data = setupColor(testR, testG, testB, value);
+ var tol = setTolerance(testR, testG, testB, value);
+ debug("Testing : [" + data + "] with tolerance = [" + tol + "]");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.clearBufferfv(gl.COLOR, 0, data);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.clearColor(0, 0, 0,1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.uniform3fv(program.colorPos, data.slice(0, 3));
+ gl.uniform3fv(program.tolPos, tol);
+
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "Should pass (green color instead of red)");
+}
+
+
+function testReadPixelsFromColorChannelsWithVariousValues(width, height) {
+ debug("Testing R channel");
+ for (var ii = 0; ii < testValues.length; ++ii) {
+ clearAndVerifyColor(width, height, true, false, false, testValues[ii]);
+ }
+ debug("Testing G channel");
+ for (var ii = 0; ii < testValues.length; ++ii) {
+ clearAndVerifyColor(width, height, false, true, false, testValues[ii]);
+ }
+ debug("Testing B channel");
+ for (var ii = 0; ii < testValues.length; ++ii) {
+ clearAndVerifyColor(width, height, false, false, true, testValues[ii]);
+ }
+}
+
+function testSampleTextureFromColorChannelsWithVariousValues(fbo, program) {
+ debug("Testing R channel");
+ for (var ii = 0; ii < testValues.length; ++ii) {
+ clearDrawAndVerifyColor(fbo, program, true, false, false, testValues[ii]);
+ }
+ debug("Testing G channel");
+ for (var ii = 0; ii < testValues.length; ++ii) {
+ clearDrawAndVerifyColor(fbo, program, false, true, false, testValues[ii]);
+ }
+ debug("Testing B channel");
+ for (var ii = 0; ii < testValues.length; ++ii) {
+ clearDrawAndVerifyColor(fbo, program, false, false, true, testValues[ii]);
+ }
+}
+
+function testRenderbufferReadback(width, height) {
+ debug("");
+ debug("Checking clearing and readback of a color image of renderbuffer with R11F_G11F_B10F format.");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.R11F_G11F_B10F, width, height);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer);
+ shouldBe("gl.FRAMEBUFFER_COMPLETE", "gl.checkFramebufferStatus(gl.FRAMEBUFFER)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with renderbuffer should succeed.");
+
+ testReadPixelsFromColorChannelsWithVariousValues(width, height);
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteRenderbuffer(renderbuffer);
+}
+
+function testTextureReadback(width, height) {
+ debug("");
+ debug("Checking clearing and readback of a color image of texture with R11F_G11F_B10F format.");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R11F_G11F_B10F, width, height, 0, gl.RGB, gl.FLOAT, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ shouldBe("gl.FRAMEBUFFER_COMPLETE", "gl.checkFramebufferStatus(gl.FRAMEBUFFER)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with texture should succeed.");
+
+ testReadPixelsFromColorChannelsWithVariousValues(width, height);
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(tex);
+}
+
+function setupProgram() {
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["pos", "texCoord0"]);
+ if (!program)
+ return null;
+ program.colorPos = gl.getUniformLocation(program, "u_color");
+ program.tolPos = gl.getUniformLocation(program, "u_tol");
+ var texPos = gl.getUniformLocation(program, "u_tex");
+ program.buffers = wtu.setupUnitQuad(gl, 0, 1);
+ if (!program.colorPos || !program.tolPos || !texPos || program.buffers.length == 0) {
+ gl.deleteProgram(program);
+ return null;
+ }
+ gl.useProgram(program);
+ gl.uniform1i(texPos, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup program should succeed.");
+ return program;
+}
+
+function testTextureSampling(width, height) {
+ debug("");
+ debug("Checking sampling of a texture with R11_G11F_B10F format");
+
+ var program = setupProgram();
+ if (!program) {
+ testFailed("Failed to setup program");
+ return;
+ }
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R11F_G11F_B10F, width, height, 0, gl.RGB, gl.FLOAT, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ shouldBe("gl.FRAMEBUFFER_COMPLETE", "gl.checkFramebufferStatus(gl.FRAMEBUFFER)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with texture should succeed.");
+
+ testSampleTextureFromColorChannelsWithVariousValues(fbo, program);
+
+ gl.deleteTexture(tex);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteProgram(program);
+}
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from tests.");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-fbo-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-fbo-test.html
new file mode 100644
index 0000000000..c06e9988ed
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-fbo-test.html
@@ -0,0 +1,642 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 ReadPixels 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Checks that ReadPixels from a fbo works as expected.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+gl.pixelStorei(gl.PACK_ALIGNMENT, 1);
+
+function getChannelCount(format) {
+ switch (format) {
+ case gl.RED:
+ case gl.RED_INTEGER:
+ case gl.ALPHA:
+ case gl.LUMINANCE:
+ return 1;
+ case gl.RB:
+ case gl.RB_INTEGER:
+ case gl.LUMINANCE_ALPHA:
+ return 2;
+ case gl.RGB:
+ case gl.RGB_INTEGER:
+ return 3;
+ case gl.RGBA:
+ case gl.RGBA_INTEGER:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+function getUnpackInfo(type) {
+ switch (type) {
+ case gl.UNSIGNED_SHORT_5_6_5:
+ return {bitsCount: [5, 6, 5], isReverse: false};
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ return {bitsCount: [4, 4, 4, 4], isReverse: false};
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ return {bitsCount: [5, 5, 5, 1], isReverse: false};
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ return {bitsCount: [2, 10, 10, 10], isReverse: true};
+ case gl.UNSIGNED_INT_10F_11F_11F_REV:
+ return {bitsCount: [10, 11, 11], isReverse: true};
+ case gl.UNSIGNED_INT_5_9_9_9_REV:
+ return {bitsCount: [5, 9, 9, 9], isReverse: true};
+ default:
+ return null;
+ }
+}
+
+// bitsCount is an array contains bit count for each component.
+function unpack(value, channelCount, bitsCount, isReverse) {
+ var result = new Array(channelCount);
+
+ var accumBitsCount = 0;
+ for (var i = channelCount - 1; i >= 0; --i) {
+ var currentChannel = isReverse ? (channelCount - i - 1) : i;
+ var mask = 0xFFFFFFFF >>> (32 - bitsCount[i]);
+ result[currentChannel] = ((value >> accumBitsCount) & mask);
+ accumBitsCount += bitsCount[i];
+ }
+
+ return result;
+}
+
+function getColor(buf, index, readFormat, readType) {
+ var channelCount = getChannelCount(readFormat);
+ var result = new Array(channelCount);
+
+ var unpackInfo = getUnpackInfo(readType);
+ if (unpackInfo) {
+ result = unpack(buf[index], channelCount, unpackInfo.bitsCount, unpackInfo.isReverse);
+ } else {
+ for (var i = 0; i < channelCount; ++i) {
+ result[i] = buf[index + i];
+ }
+ }
+
+ return result;
+}
+
+function convertToSRGB(val) {
+ if (val <= 0) {
+ return 0;
+ } else if (val < 0.0031308) {
+ return 12.92 * val;
+ } else if (val < 1) {
+ return 1.055 * Math.pow(val, 0.41666) - 0.055;
+ } else {
+ return 1;
+ }
+}
+
+function denormalizeColor(srcInternalFormat, destType, color) {
+ var result = color.slice();
+ var tol = 0;
+
+ var srcIsNormalized = false;
+
+ switch (srcInternalFormat) {
+ case gl.R8:
+ case gl.RG8:
+ case gl.RGB8:
+ case gl.RGBA8:
+ case gl.RGB5_A1:
+ case gl.SRGB8_ALPHA8:
+ case gl.RGB10_A2:
+ srcIsNormalized = true;
+ tol = 6;
+ break;
+ case gl.RGB565:
+ // RGB565 needs slightly extra tolerance, at least on Google Pixel. crbug.com/682753
+ srcIsNormalized = true;
+ tol = 7;
+ break;
+ case gl.RGBA4:
+ srcIsNormalized = true;
+ tol = 10;
+ break;
+ }
+
+ if (!srcIsNormalized) {
+ return { color: result, tol: tol };
+ }
+
+ if (srcInternalFormat == gl.SRGB8_ALPHA8) {
+ for (var i = 0; i < 3; ++i) {
+ result[i] = convertToSRGB(result[i]);
+ }
+ }
+
+ switch (destType) {
+ case gl.UNSIGNED_BYTE:
+ result = result.map(val => { return val * 0xFF});
+ break;
+ case gl.UNSIGNED_SHORT:
+ // On Linux NVIDIA, tol of 33 is necessary to pass the test.
+ tol = 40;
+ result = result.map(val => { return val * 0xFFFF});
+ break;
+ case gl.UNSIGNED_INT:
+ tol = 40;
+ result = result.map(val => { return val * 0xFFFFFFFF});
+ break;
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ result = result.map(val => { return val * 0xF});
+ break;
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ result[0] = result[0] * 0x1F;
+ result[1] = result[1] * 0x1F;
+ result[2] = result[2] * 0x1F;
+ result[3] = result[3] * 0x1;
+ break;
+ case gl.UNSIGNED_SHORT_5_6_5:
+ result[0] = result[0] * 0x1F;
+ result[1] = result[1] * 0x3F;
+ result[2] = result[2] * 0x1F;
+ break;
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ tol = 25;
+ result[0] = result[0] * 0x3FF;
+ result[1] = result[1] * 0x3FF;
+ result[2] = result[2] * 0x3FF;
+ result[3] = result[3] * 0x3;
+ break;
+ case gl.UNSIGNED_INT_5_9_9_9_REV:
+ result[0] = result[0] * 0x1FF;
+ result[1] = result[1] * 0x1FF;
+ result[2] = result[2] * 0x1FF;
+ result[3] = result[3] * 0x1F;
+ break;
+ }
+
+ return { color: result, tol: tol };
+}
+
+function compareColor(buf, index, expectedColor, srcInternalFormat,
+ srcFormat, srcType, readFormat, readType) {
+ var srcChannelCount = getChannelCount(srcFormat);
+ var readChannelCount = getChannelCount(readFormat);
+
+ var color = getColor(buf, index, readFormat, readType);
+ expectedColor = denormalizeColor(srcInternalFormat, readType, expectedColor);
+
+ var minChannel = Math.min(srcChannelCount, readChannelCount);
+ for (var i = 0; i < minChannel; ++i) {
+ if (Math.abs(expectedColor.color[i] - color[i]) > expectedColor.tol) {
+ testFailed("Expected color = " + expectedColor.color + ", was = " + color);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+var textureTestCases = [
+ {
+ texInternalFormat: 'R8', texFormat: 'RED', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.0, 0.0, 0],
+ },
+ {
+ texInternalFormat: 'R8UI', texFormat: 'RED_INTEGER', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [250, 0, 0, 0],
+ },
+ {
+ texInternalFormat: 'R8I', texFormat: 'RED_INTEGER', texType: 'BYTE',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-126, 0, 0, 0],
+ },
+ {
+ texInternalFormat: 'R16UI', texFormat: 'RED_INTEGER', texType: 'UNSIGNED_SHORT',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [30001, 0, 0, 0],
+ },
+ {
+ texInternalFormat: 'R16I', texFormat: 'RED_INTEGER', texType: 'SHORT',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-14189, 0, 0, 0],
+ },
+ {
+ texInternalFormat: 'R32UI', texFormat: 'RED_INTEGER', texType: 'UNSIGNED_INT',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [126726, 0, 0, 0],
+ },
+ {
+ texInternalFormat: 'R32I', texFormat: 'RED_INTEGER', texType: 'INT',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-126726, 0, 0, 0],
+ },
+
+ {
+ texInternalFormat: 'RG8', texFormat: 'RG', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.7, 0.0, 0],
+ },
+ {
+ texInternalFormat: 'RG8UI', texFormat: 'RG_INTEGER', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [250, 124, 0, 0],
+ },
+ {
+ texInternalFormat: 'RG8I', texFormat: 'RG_INTEGER', texType: 'BYTE',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-55, 124, 0, 0],
+ },
+ {
+ texInternalFormat: 'RG16UI', texFormat: 'RG_INTEGER', texType: 'UNSIGNED_SHORT',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [30001, 18, 0, 0],
+ },
+ {
+ texInternalFormat: 'RG16I', texFormat: 'RG_INTEGER', texType: 'SHORT',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-14189, 6735, 0, 0],
+ },
+ {
+ texInternalFormat: 'RG32UI', texFormat: 'RG_INTEGER', texType: 'UNSIGNED_INT',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [126726, 1976, 0, 0],
+ },
+ {
+ texInternalFormat: 'RG32I', texFormat: 'RG_INTEGER', texType: 'INT',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-126726, 126726, 0, 0],
+ },
+
+ {
+ texInternalFormat: 'RGB8', texFormat: 'RGB', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 1, 0, 0],
+ },
+ {
+ texInternalFormat: 'RGB565', texFormat: 'RGB', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.7, 0.2, 0],
+ },
+ {
+ texInternalFormat: 'RGB565', texFormat: 'RGB', texType: 'UNSIGNED_SHORT_5_6_5',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.7, 0.2, 0],
+ },
+
+ {
+ texInternalFormat: 'RGBA8', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0, 1, 0.7],
+ },
+ {
+ texInternalFormat: 'SRGB8_ALPHA8', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0, 1, 0.7],
+ },
+ {
+ texInternalFormat: 'RGB5_A1', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0, 0.7, 1],
+ },
+ {
+ texInternalFormat: 'RGB5_A1', texFormat: 'RGBA', texType: 'UNSIGNED_SHORT_5_5_5_1',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.7, 1, 0],
+ },
+ {
+ texInternalFormat: 'RGB5_A1', texFormat: 'RGBA', texType: 'UNSIGNED_INT_2_10_10_10_REV',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.7, 0, 1],
+ },
+ {
+ texInternalFormat: 'RGBA4', texFormat: 'RGBA', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.5, 0.7, 1, 0],
+ },
+ {
+ texInternalFormat: 'RGBA4', texFormat: 'RGBA', texType: 'UNSIGNED_SHORT_4_4_4_4',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [1, 0, 0.5, 0.7],
+ },
+ {
+ texInternalFormat: 'RGBA8UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_BYTE',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [127, 0, 255, 178],
+ },
+ {
+ texInternalFormat: 'RGBA8I', texFormat: 'RGBA_INTEGER', texType: 'BYTE',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [-55, 56, 80, 127],
+ },
+ {
+ texInternalFormat: 'RGB10_A2UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_INT_2_10_10_10_REV',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [178, 0, 127, 3],
+ },
+ {
+ texInternalFormat: 'RGBA16UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_SHORT',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [14189, 6735, 0, 19],
+ },
+ {
+ texInternalFormat: 'RGBA16I', texFormat: 'RGBA_INTEGER', texType: 'SHORT',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [14189, -6735, 0, 19],
+ },
+ {
+ texInternalFormat: 'RGBA32UI', texFormat: 'RGBA_INTEGER', texType: 'UNSIGNED_INT',
+ readFormat: 'RGBA_INTEGER', readType: 'UNSIGNED_INT',
+ clearColor: [126726, 6726, 98765, 2015],
+ },
+ {
+ texInternalFormat: 'RGBA32I', texFormat: 'RGBA_INTEGER', texType: 'INT',
+ readFormat: 'RGBA_INTEGER', readType: 'INT',
+ clearColor: [126726, -6726, -98765, 2015],
+ },
+
+ {
+ texInternalFormat: 'RGB10_A2', texFormat: 'RGBA', texType: 'UNSIGNED_INT_2_10_10_10_REV',
+ readFormat: 'RGBA', readType: 'UNSIGNED_BYTE',
+ clearColor: [0.7, 0, 0.5, 1],
+ },
+
+ // TODO(zmo): add float/half_float test cases with extension supports.
+];
+
+function getArrayTypeFromReadPixelsType(gl, type) {
+ switch (type) {
+ case gl.UNSIGNED_BYTE:
+ return Uint8Array;
+ case gl.BYTE:
+ return Int8Array;
+ case gl.UNSIGNED_SHORT:
+ case gl.UNSIGNED_SHORT_5_6_5:
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ return Uint16Array;
+ case gl.SHORT:
+ return Int16Array;
+ case gl.UNSIGNED_INT:
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ case gl.UNSIGNED_INT_10F_11F_11F_REV:
+ case gl.UNSIGNED_INT_5_9_9_9_REV:
+ return Uint32Array;
+ case gl.INT:
+ return Int32Array;
+ case gl.HALF_FLOAT:
+ return Uint16Array;
+ case gl.FLOAT:
+ return Float32Array;
+ default:
+ return null;
+ }
+}
+
+function getFormatString(gl, format) {
+ switch (format) {
+ case gl.RED:
+ return 'RED';
+ case gl.RED_INTEGER:
+ return 'RED_INTEGER';
+ case gl.RG:
+ return 'RG';
+ case gl.RG_INTEGER:
+ return 'RG_INTEGER';
+ case gl.RGB:
+ return 'RGB';
+ case gl.RGB_INTEGER:
+ return 'RGB_INTEGER';
+ case gl.RGBA:
+ return 'RGBA';
+ case gl.RGBA_INTEGER:
+ return 'RGBA_INTEGER';
+ case gl.LUMINANCE:
+ return 'LUMINANCE';
+ case gl.LUMINANCE_ALPHA:
+ return 'LUMINANCE_ALPHA';
+ case gl.ALPHA:
+ return 'ALPHA';
+ default:
+ return '';
+ };
+}
+
+function getTypeString(gl, type) {
+ switch (type) {
+ case gl.UNSIGNED_BYTE:
+ return 'UNSIGNED_BYTE';
+ case gl.BYTE:
+ return 'BYTE';
+ case gl.UNSIGNED_SHORT:
+ return 'UNSIGNED_SHORT';
+ case gl.SHORT:
+ return 'SHORT';
+ case gl.UNSIGNED_INT:
+ return 'UNSIGNED_INT';
+ case gl.INT:
+ return 'INT';
+ case gl.UNSIGNED_SHORT_5_6_5:
+ return 'UNSIGNED_SHORT_5_6_5';
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ return 'UNSIGNED_SHORT_5_5_5_1';
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ return 'UNSIGNED_INT_2_10_10_10_REV';
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ return 'UNSIGNED_SHORT_4_4_4_4';
+ case gl.UNSIGNED_INT_10F_11F_11F_REV:
+ return 'UNSIGNED_INT_10F_11F_11F_REV';
+ case gl.UNSIGNED_INT_5_9_9_9_REV:
+ return 'UNSIGNED_INT_5_9_9_9_REV';
+ default:
+ return '';
+ };
+}
+
+function elementCountPerPixel(gl, readFormat, readType) {
+ switch (readFormat) {
+ case gl.RED:
+ case gl.RED_INTEGER:
+ case gl.ALPHA:
+ case gl.LUMINANCE:
+ return 1;
+ case gl.RG:
+ case gl.RG_INTEGER:
+ case gl.LUMINANCE_ALPHA:
+ return 2;
+ case gl.RGB:
+ case gl.RGB_INTEGER:
+ switch (readType) {
+ case gl.UNSIGNED_SHORT_5_6_5:
+ return 1;
+ default:
+ return 3;
+ }
+ case gl.RGBA:
+ case gl.RGBA_INTEGER:
+ switch (readType) {
+ 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_5_9_9_9_REV:
+ return 1;
+ default:
+ return 4;
+ }
+ default:
+ testFailed("Unexpected read format/type = " + readFormat + "/" + readType);
+ return 0;
+ }
+}
+
+function testReadPixels(gl, srcInternalFormat, srcFormat, srcType,
+ readFormat, readType, expectedColor) {
+ var arrayType = getArrayTypeFromReadPixelsType(gl, readType);
+ var buf = new arrayType(width * height * 4);
+ gl.readPixels(0, 0, width, height, readFormat, readType, buf);
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR, "readPixels should generate no error");
+ var diffFound = false;
+ for (var ii = 0; ii < width * height; ++ii) {
+ var offset = ii * elementCountPerPixel(gl, readFormat, readType);
+ if (!compareColor(buf, offset, expectedColor, srcInternalFormat, srcFormat, srcType,
+ readFormat, readType)) {
+ diffFound = true;
+ break;
+ }
+ }
+ if (!diffFound) {
+ testPassed("Color read back as expected");
+ }
+}
+
+function clearBuffer(gl, texInternalFormat, clearColor) {
+ var value;
+ switch (texInternalFormat) {
+ case gl.R8UI:
+ case gl.R16UI:
+ case gl.R32UI:
+ case gl.RG8UI:
+ case gl.RG16UI:
+ case gl.RG32UI:
+ case gl.RGBA8UI:
+ case gl.RGBA16UI:
+ case gl.RGBA32UI:
+ case gl.RGB10_A2UI:
+ value = new Uint32Array(4);
+ for (var ii = 0; ii < 4; ++ii)
+ value[ii] = clearColor[ii];
+ gl.clearBufferuiv(gl.COLOR, 0, value);
+ break;
+ case gl.R8I:
+ case gl.R16I:
+ case gl.R32I:
+ case gl.RG8I:
+ case gl.RG16I:
+ case gl.RG32I:
+ case gl.RGBA8I:
+ case gl.RGBA16I:
+ case gl.RGBA32I:
+ value = new Int32Array(4);
+ for (var ii = 0; ii < 4; ++ii)
+ value[ii] = clearColor[ii];
+ gl.clearBufferiv(gl.COLOR, 0, value);
+ break;
+ default:
+ gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ break;
+ }
+}
+
+for (var tt = 0; tt < textureTestCases.length; ++tt) {
+ var test = textureTestCases[tt];
+ debug("");
+ debug("ReadPixels from fbo with texture = (" + test.texInternalFormat +
+ ", " + test.texFormat + ", " + test.texType +
+ "), format = " + test.readFormat + ", type = " + test.readType);
+ var width = 2;
+ var height = 2;
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var colorImage = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, colorImage);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.texInternalFormat], width, height, 0,
+ gl[test.texFormat], gl[test.texType], null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, colorImage, 0);
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR, "Setting up fbo should generate no error");
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("fbo is not complete, skip");
+ continue;
+ }
+ clearBuffer(gl, gl[test.texInternalFormat], test.clearColor);
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR, "Clear color should generate no error");
+
+ var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
+ var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
+ var implFormatString = getFormatString(gl, implFormat);
+ var implTypeString = getTypeString(gl, implType);
+
+ if (gl[test.texInternalFormat] == gl.RGB10_A2) {
+ // This is a special case where three read format/type are supported.
+ var readTypes = [gl.UNSIGNED_BYTE, gl.UNSIGNED_INT_2_10_10_10_REV];
+ var readTypeStrings = ['UNSIGNED_BYTE', 'UNSIGNED_INT_2_10_10_10_REV'];
+ if (implFormat == gl.RGBA && implTypeString != '') {
+ readTypes.push(implType);
+ readTypeStrings.push(implTypeString);
+ } else {
+ testFailed("Unimplemented Implementation dependent color read format/type = " +
+ implFormat + "/" + implType);
+ }
+ for (var rr = 0; rr < readTypes.length; ++rr) {
+ debug("Special case RGB10_A2, format = RGBA, type = " + readTypeStrings[rr]);
+ testReadPixels(gl, gl[test.texInternalFormat], gl[test.texFormat], gl[test.texType],
+ gl.RGBA, readTypes[rr], test.clearColor);
+ }
+ } else {
+ testReadPixels(gl, gl[test.texInternalFormat], gl[test.texFormat], gl[test.texType],
+ gl[test.readFormat], gl[test.readType], test.clearColor);
+
+ debug("Testing implementation dependent color read format = " + implFormatString +
+ ", type = " + implTypeString);
+ if (implFormatString == '') {
+ testFailed("Invalid IMPLEMENTATION_COLOR_READ_FORMAT = " + implFormat);
+ continue;
+ }
+ if (implTypeString == '') {
+ testFailed("Invalid IMPLEMENTATION_COLOR_READ_TYPE = " + implType);
+ continue;
+ }
+ testReadPixels(gl, gl[test.texInternalFormat], gl[test.texFormat], gl[test.texType],
+ implFormat, implType, test.clearColor);
+
+ gl.deleteTexture(colorImage);
+ gl.deleteFramebuffer(fbo);
+ }
+}
+
+debug("")
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html
new file mode 100644
index 0000000000..b4f91f1d3c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html
@@ -0,0 +1,85 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Conformance Test: readPixels from RGB8 Buffer Into Pixel Pack Buffer.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="4" height="4"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+debug("");
+description("Verifies readPixels from RGB8 buffer into PIXEL_PACK buffer works");
+
+debug("On MacOSX with AMD GPUs, the alpha channel is readback as 0 instead of 255");
+
+var wtu = WebGLTestUtils;
+var pixel = [0, 0, 0, 0];
+var expectedColor = [255, 102, 0, 255];
+
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ var width = 4;
+ var height = 4;
+
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB8, width, height);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer);
+
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("framebuffer with RGB8 color buffer is incomplete");
+ } else {
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ var pbo = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pbo);
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, width * height * 4, gl.STATIC_COPY);
+
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+
+ var data = new Uint8Array(width * height * 4);
+ gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, data);
+
+ for (var ii = 0; ii < width * height; ++ii) {
+ if (data[ii * 4] != 255 ||
+ data[ii * 4 + 1] != 0 ||
+ data[ii * 4 + 2] != 0 ||
+ data[ii * 4 + 3] != 255) {
+ testFailed("Expected in pixel " + ii + ": [255,0,0,255], got: " +
+ [data[ii * 4], data[ii * 4 + 1], data[ii * 4 + 2], data[ii * 4 + 3]]);
+ break;
+ }
+ }
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Tests should complete without gl errors");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-into-pixel-pack-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-into-pixel-pack-buffer.html
new file mode 100644
index 0000000000..7d646a6ecd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-into-pixel-pack-buffer.html
@@ -0,0 +1,152 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Conformance Test: ReadPixels Into Pixel Pack Buffer.</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="4" height="4"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+function checkFormatAndType()
+{
+ debug("");
+ debug("check format / type");
+ var invalidFormat = [gl.DEPTH_COMPONENT, gl.DEPTH_STENCIL, gl.R8, gl.RGBA4, gl.LUMINANCE, gl.LUMINANCE_ALPHA];
+ var invalidType = [gl.UNSIGNED_INT_24_8];
+ for (var ff = 0; ff < invalidFormat.length; ++ff) {
+ var format = invalidFormat[ff];
+ gl.readPixels(0, 0, 1, 1, format, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Format should not be able to read as " + wtu.glEnumToString(gl, format));
+ }
+ for (var tt = 0; tt < invalidType.length; ++tt) {
+ var type = invalidType[tt];
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, type, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Type should not be able to read as " + wtu.glEnumToString(gl, type));
+ }
+
+ debug("");
+ debug("check combinations of format and type");
+ var combinations = [
+ {format: gl.RGBA, type: gl.UNSIGNED_BYTE},
+ {format: gl.RGB, type: gl.UNSIGNED_BYTE},
+ {format: gl.RGB, type: gl.UNSIGNED_SHORT_5_6_5},
+ {format: gl.RGBA, type: gl.UNSIGNED_SHORT_5_5_5_1},
+ {format: gl.RGBA, type: gl.UNSIGNED_SHORT_4_4_4_4},
+ {format: gl.ALPHA, type: gl.UNSIGNED_BYTE},
+ {format: gl.RED, type: gl.UNSIGNED_BYTE},
+ {format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT},
+ {format: gl.RGBA_INTEGER, type: gl.INT}
+ ];
+
+ var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
+ var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
+ for (var tt = 0; tt < combinations.length; ++ tt) {
+ var info = combinations[tt];
+ var format = info.format;
+ var type = info.type;
+ gl.readPixels(0, 0, 1, 1, format, type, 0);
+ // Only two format/type parameter pairs are accepted. GL_RGBA/GL_UNSIGNED_BYTE is always
+ // accepted on default readbuffer. The other acceptable pair can be discovered by querying
+ // GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
+ if ((format == gl.RGBA && type == gl.UNSIGNED_BYTE) || (format == implFormat && type == implType)) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "The combination of format/type should be able to read as " +
+ wtu.glEnumToString(gl, format) + " / " + wtu.glEnumToString(gl, type));
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The combination of format/type should not be able to read as " +
+ wtu.glEnumToString(gl, format) + " / " + wtu.glEnumToString(gl, type));
+ }
+ }
+}
+
+function validatePixelPackBufferAndParameters(canvasWidth, canvasHeight)
+{
+ debug("");
+ debug("Validate PIXEL_PACK buffer and readPixels' parameters");
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.pixelStorei(gl.PACK_ALIGNMENT, 1);
+
+ var size = canvasWidth * canvasHeight * 4;
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, size, gl.STATIC_DRAW);
+ var array = new Uint8Array(size);
+
+ debug("");
+ debug("PIXEL_PACK buffer is bound");
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should generate INVALID_OPERATION if pixel pack buffer is bound");
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("Validate the offset of PIXEL_PACK buffer and buffer size");
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, -1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "offset < 0");
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, size);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "offset > buffer size");
+ gl.readPixels(0, 0, canvasWidth + 1, canvasHeight, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "pixel pack buffer is not large enough");
+
+ debug("");
+ debug("Validate the reading area of framebuffer");
+ gl.readPixels(-1, -2, canvasWidth, canvasHeight, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "reading pixels outside of the framebuffer should succeed.");
+ gl.readPixels(2, 1, canvasWidth, canvasHeight, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "reading pixels outside of the framebuffer should succeed.");
+ gl.readPixels(2, 1, -1, -1, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "reading pixels with negative width / height should generate INVALID_VALUE.");
+
+ checkFormatAndType();
+
+ debug("");
+ debug("no PIXEL_PACK buffer bound");
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "no pixel pack buffer bound");
+
+ gl.deleteBuffer(buffer);
+}
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var pixel = [0, 0, 0, 0];
+var expectedColor = [255, 102, 0, 255];
+
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ description('ReadPixels into PIXEL_PACK buffer');
+ validatePixelPackBufferAndParameters(4, 4);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html
new file mode 100644
index 0000000000..8d4559fb93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html
@@ -0,0 +1,353 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="4" height="4"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict"
+
+var wtu = WebGLTestUtils;
+var initialColor = [1, 2, 3, 4];
+var expectedColor = [[249, 102, 0, 255],
+ [2, 200, 102, 255],
+ [134, 87, 234, 255],
+ [99, 5, 76, 255]];
+
+function calculatePaddingBytes(bytesPerPixel, packAlignment, width)
+{
+ var padding = 0;
+ switch (packAlignment) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ padding = (bytesPerPixel * width) % packAlignment;
+ if (padding > 0)
+ padding = packAlignment - padding;
+ return padding;
+ default:
+ testFailed("should not reach here");
+ return;
+ }
+}
+
+function paintWebGLCanvas(gl)
+{
+ var program = wtu.setupTexturedQuad(gl);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var data = new Uint8Array(4 * 4);
+ for (var ii = 0; ii < 4; ++ii) {
+ data[ii * 4] = expectedColor[ii][0];
+ data[ii * 4 + 1] = expectedColor[ii][1];
+ data[ii * 4 + 2] = expectedColor[ii][2];
+ data[ii * 4 + 3] = expectedColor[ii][3];
+ }
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+
+ 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);
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ wtu.clearAndDrawUnitQuad(gl);
+}
+
+function samePixel(array, index, refPixel, row, pixelTag)
+{
+ for (var ii = 0; ii < refPixel.length; ++ii) {
+ if (array[index] == refPixel[ii][0] &&
+ array[index + 1] == refPixel[ii][1] &&
+ array[index + 2] == refPixel[ii][2] &&
+ array[index + 3] == refPixel[ii][3]) {
+ return true;
+ }
+ }
+ var refPixelText = "";
+ for (var ii = 0; ii < refPixel.length; ++ii) {
+ if (ii > 0)
+ refPixelText += " or ";
+ refPixelText += "[" + refPixel[ii] + "]";
+ }
+ testFailed(pixelTag + " pixel of row " + row + ": expected " + refPixelText + ", got [" +
+ [array[index], array[index + 1], array[index + 2], array[index + 3]] + "]");
+ return false;
+}
+
+function runTestIteration(xoffset, yoffset, width, height, packParams, usePixelPackBuffer, packParamsValid)
+{
+ if (!("alignment" in packParams))
+ packParams.alignment = 4;
+ if (!("rowLength" in packParams))
+ packParams.rowLength = 0;
+ if (!("skipPixels" in packParams))
+ packParams.skipPixels = 0;
+ if (!("skipRows" in packParams))
+ packParams.skipRows = 0;
+ debug("Testing xoffset = " + xoffset + ", yoffset " + yoffset +
+ ", width = " + width + ", height = " + height +
+ ", PACK_ALIGNMENT = " + packParams.alignment + ", PACK_ROW_LENGTH = " + packParams.rowLength +
+ ", PACK_SKIP_PIXELS = " + packParams.skipPixels + " , PACK_SKIP_ROWS = " + packParams.skipRows);
+ gl.pixelStorei(gl.PACK_ALIGNMENT, packParams.alignment);
+ gl.pixelStorei(gl.PACK_ROW_LENGTH, packParams.rowLength);
+ gl.pixelStorei(gl.PACK_SKIP_PIXELS, packParams.skipPixels);
+ gl.pixelStorei(gl.PACK_SKIP_ROWS, packParams.skipRows);
+
+ var actualWidth = packParams.rowLength > 0 ? packParams.rowLength : width;
+
+ var bytesPerPixel = 4; // see readPixels' parameters below, the format is gl.RGBA, type is gl.UNSIGNED_BYTE
+ var padding = calculatePaddingBytes(bytesPerPixel, packParams.alignment, actualWidth);
+ var bytesPerRow = actualWidth * bytesPerPixel + padding;
+
+ var size = bytesPerRow * (height - 1) + bytesPerPixel * width;
+ var skipSize = packParams.skipPixels * bytesPerPixel + packParams.skipRows * bytesPerRow;
+ var array = new Uint8Array(skipSize + size);
+ for (var ii = 0; ii < skipSize + size; ++ii) {
+ array[ii] = initialColor[ii % bytesPerPixel];
+ }
+ var arrayWrongSize = null;
+ if (size > 0)
+ arrayWrongSize = new Uint8Array(skipSize + size - 1);
+ if (usePixelPackBuffer) {
+ var offset = 0;
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer);
+ if (size > 0) {
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, arrayWrongSize, gl.STATIC_DRAW);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, offset);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+ }
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, array, gl.STATIC_DRAW);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, offset);
+ } else {
+ if (size > 0) {
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, arrayWrongSize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+ }
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ }
+ if (packParamsValid) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Invalid pack params combination");
+ return;
+ }
+
+ if (size == 0)
+ return;
+
+ if (usePixelPackBuffer) {
+ array = new Uint8Array(skipSize + size);
+ gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, array);
+ }
+
+ // Check skipped bytes are unchanged.
+ for (var ii = 0; ii < skipSize; ++ii) {
+ if (array[ii] != initialColor[ii % bytesPerPixel]) {
+ testFailed("skipped bytes changed at index " + ii + ": expected " +
+ initialColor[ii % bytesPerPixel] + " got " + array[ii]);
+ break;
+ }
+ }
+ // Check the first and last pixels of each row.
+ var canvasWidth = 4;
+ var canvasHeight = 4;
+ for (var row = 0; row < height; ++row) {
+ var refColor;
+ var yIndex = yoffset + row;
+ var xIndex;
+
+ // First pixel
+ var pos = skipSize + bytesPerRow * row;
+ xIndex = xoffset;
+ if (xIndex < 0 || xIndex >= canvasWidth || yIndex < 0 || yIndex >= canvasHeight) {
+ if (row > 0 && usePixelPackBuffer && packParams.rowLength > 0 && packParams.rowLength < width)
+ refColor = [initialColor, expectedColor[yIndex - 1]];
+ else
+ refColor = [initialColor];
+ } else {
+ refColor = [expectedColor[yIndex]];
+ }
+ samePixel(array, pos, refColor, row, "first");
+
+ // Last pixel
+ var xSpan;
+ if (row + 1 == height || packParams.rowLength > width)
+ xSpan = width;
+ else
+ xSpan = actualWidth;
+ xIndex = xoffset + xSpan - 1;
+ pos += (xSpan - 1) * bytesPerPixel;
+ if (xIndex < 0 || xIndex >= canvasWidth || yIndex < 0 || yIndex >= canvasHeight) {
+ if (row > 0 && usePixelPackBuffer && packParams.rowLength > 0 && packParams.rowLength < width)
+ refColor = [initialColor, expectedColor[yIndex - 1]];
+ else
+ refColor = [initialColor];
+ } else {
+ refColor = [expectedColor[yIndex]];
+ }
+ samePixel(array, pos, refColor, row, "last");
+
+ // Check padding bytes are unchanged and bytes beyond rowLength set correctly.
+ pos += bytesPerPixel;
+ if (row + 1 < height) {
+ // Beyond bytes filled for PACK_ROW_LENGTH, the row could have extra bytes due to
+ // padding. These extra bytes could be either filled with pixel data if
+ // PACK_ROW_LENGTH is set to be less than width, or they could be left unchanged
+ // if they are beyond |width| pixels.
+ if (packParams.rowLength > 0 && packParams.rowLength < width) {
+ var trailingBytes = Math.min((width - packParams.rowLength) * bytesPerPixel,
+ bytesPerRow - packParams.rowLength * bytesPerPixel);
+ for (var ii = 0; ii < trailingBytes; ++ii) {
+ if (array[pos + ii] != refColor[0][ii % bytesPerPixel]) {
+ testFailed("Trailing byte " + ii + " after rowLength of row " + row + " : expected " +
+ refColor[0][ii % bytesPerPixel] + ", got " + array[pos + ii]);
+ break;
+ }
+ }
+ pos += trailingBytes;
+ }
+ var paddingBytes = skipSize + bytesPerRow * (row + 1) - pos;
+ for (var ii = 0; ii < paddingBytes; ++ii) {
+ if (array[pos + ii] != initialColor[ii % bytesPerPixel]) {
+ testFailed("Padding byte " + ii + " of row " + row + " changed: expected " +
+ initialColor[ii % bytesPerPixel] + ", got " + array[pos + ii]);
+ break;
+ }
+ }
+ }
+ }
+}
+
+function testPackParameters(usePixelPackBuffer)
+{
+ debug("");
+ var destText = usePixelPackBuffer ? "PIXEL_PACK buffer" : "array buffer";
+ debug("Verify that reading pixels to " + destText + " works fine with various pack alignments.");
+ runTestIteration(0, 0, 1, 3, {alignment:1}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:2}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:8}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {alignment:8}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 3, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 3, 3, {alignment:8}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 0, 0, {alignment:1}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 1, 3, {alignment:8}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " is disallowed when PACK_ROW_LENGTH < width.");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:1}, usePixelPackBuffer, false);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH == width.");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:3}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH > width and with no padding");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:4}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with PACK_ROW_LENGTH > width and with padding");
+ runTestIteration(0, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(-1, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, -1, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(-1, -1, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(-5, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, -5, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(2, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, 2, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(2, 2, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(5, 0, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+ runTestIteration(0, 5, 3, 3, {alignment:8, rowLength:5}, usePixelPackBuffer, true);
+
+ debug("");
+ debug("Verify that reading pixels to " + destText + " works fine with pack skip parameters.");
+ runTestIteration(0, 0, 3, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 3, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 3, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
+ runTestIteration(0, 0, 2, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
+ runTestIteration(0, 0, 2, 3, {skipPixels:1, rowLength:4}, usePixelPackBuffer, true);
+}
+
+debug("");
+debug("Canvas.getContext");
+
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ description('ReadPixels into array buffer');
+ paintWebGLCanvas(gl);
+ var usePixelPackBuffer = false;
+ testPackParameters(usePixelPackBuffer);
+ usePixelPackBuffer = true;
+ testPackParameters(usePixelPackBuffer);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/00_test_list.txt
new file mode 100644
index 0000000000..c06bbe3770
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/00_test_list.txt
@@ -0,0 +1,10 @@
+framebuffer-object-attachment.html
+framebuffer-test.html
+framebuffer-texture-layer.html
+invalidate-framebuffer.html
+multisampled-renderbuffer-initialization.html
+--min-version 2.0.1 multisampled-depth-renderbuffer-initialization.html
+--min-version 2.0.1 multisampled-stencil-renderbuffer-initialization.html
+--min-version 2.0.1 multisample-with-full-sample-counts.html
+--min-version 2.0.1 multisample-draws-between-blits.html
+readbuffer.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-object-attachment.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-object-attachment.html
new file mode 100644
index 0000000000..754ff2cc73
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-object-attachment.html
@@ -0,0 +1,508 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+
+function checkFramebuffer(expected) {
+ var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (expected.indexOf(actual) < 0) {
+ var msg = "checkFramebufferStatus expects [";
+ for (var index = 0; index < expected.length; ++index) {
+ msg += wtu.glEnumToString(gl, expected[index]);
+ if (index + 1 < expected.length)
+ msg += ", ";
+ }
+ msg += "], was " + wtu.glEnumToString(gl, actual);
+ testFailed(msg);
+ } else {
+ var msg = "checkFramebufferStatus got " + wtu.glEnumToString(gl, actual) +
+ " as expected";
+ testPassed(msg);
+ }
+}
+
+function checkBufferBits(attachment0, attachment1) {
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)
+ return;
+ var haveDepthBuffer = attachment0 == gl.DEPTH_ATTACHMENT ||
+ attachment0 == gl.DEPTH_STENCIL_ATTACHMENT ||
+ attachment1 == gl.DEPTH_ATTACHMENT ||
+ attachment1 == gl.DEPTH_STENCIL_ATTACHMENT;
+ var haveStencilBuffer = attachment0 == gl.STENCIL_ATTACHMENT ||
+ attachment0 == gl.DEPTH_STENCIL_ATTACHMENT ||
+ attachment1 == gl.STENCIL_ATTACHMENT ||
+ attachment1 == gl.DEPTH_STENCIL_ATTACHMENT;
+ shouldBeTrue("gl.getParameter(gl.RED_BITS) + gl.getParameter(gl.GREEN_BITS) + " +
+ "gl.getParameter(gl.BLUE_BITS) + gl.getParameter(gl.ALPHA_BITS) >= 16");
+ if (haveDepthBuffer)
+ shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16");
+ else
+ shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0");
+ if (haveStencilBuffer)
+ shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) >= 8");
+ else
+ shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0");
+}
+
+
+function testFramebufferWebGL1RequiredCombinations() {
+ debug("Checking combinations of framebuffer attachments required to be valid by WebGL 1");
+
+ // Per discussion with the OpenGL ES working group, the following framebuffer attachment
+ // combinations are required to work in all WebGL 1 implementations:
+ // 1. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
+ // 2. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbuffer
+ // 3. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ var width = 64;
+ var height = 64;
+
+ // 1. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ 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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits();
+
+ // 2. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbuffer
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_ATTACHMENT);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
+
+ // 3. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_STENCIL_ATTACHMENT);
+
+ // Clean up
+ gl.deleteRenderbuffer(renderbuffer);
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+}
+
+function testDepthStencilAttachmentBehaviors() {
+ debug("");
+ debug("Checking ES3 DEPTH_STENCIL_ATTACHMENT behaviors are implemented for WebGL 2");
+ // DEPTH_STENCIL_ATTACHMENT is treated as an independent attachment point in WebGL 1;
+ // however, in WebGL 2, it is treated as an alias for DEPTH_ATTACHMENT + STENCIL_ATTACHMENT.
+ var size = 16;
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var colorBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, size, size);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ var depthBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, size, size);
+
+ var stencilBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, stencilBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, size, size);
+
+ var depthStencilBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, size, size);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("");
+ debug("color + depth");
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_ATTACHMENT);
+
+ debug("");
+ debug("color + depth + stencil: depth != stencil");
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, stencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", stencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ checkFramebuffer([gl.FRAMEBUFFER_UNSUPPORTED]);
+
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+
+ debug("");
+ debug("color + depth: DEPTH_STENCIL for DEPTH_ATTACHMENT");
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_ATTACHMENT);
+
+ debug("");
+ debug("color + depth + stencil: DEPTH_STENCIL for DEPTH_ATTACHMENT and STENCIL_ATTACHMENT");
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_STENCIL_ATTACHMENT);
+
+ debug("");
+ debug("color + depth_stencil");
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH24_STENCIL8, size, size, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, texture, 0);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", texture);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", texture);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", texture);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, null, 0);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_STENCIL_ATTACHMENT);
+
+ debug("");
+ debug("DEPTH_STENCIL_ATTACHMENT overwrites DEPTH_ATTACHMENT/STENCIL_ATTACHMENT")
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits();
+
+ debug("");
+ debug("STENCIL_ATTACHMENT overwrites stencil set by DEPTH_STENCIL_ATTACHMENT")
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", depthStencilBuffer);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ shouldEvaluateTo("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ checkBufferBits(gl.DEPTH_ATTACHMENT);
+}
+
+function testFramebufferIncompleteAttachment() {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var colorBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ debug("");
+ debug("Wrong storage type for type of attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 16, 16);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]);
+
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ debug("");
+ debug("0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]);
+
+ gl.deleteRenderbuffer(colorBuffer);
+ gl.deleteFramebuffer(fbo);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+function testFramebufferIncompleteMissingAttachment() {
+ debug("");
+ debug("No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT");
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]);
+
+ var colorBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]);
+
+ gl.deleteRenderbuffer(colorBuffer);
+ gl.deleteFramebuffer(fbo);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+function testFramebufferWithImagesOfDifferentSizes() {
+ debug("");
+ debug("Attachments of different sizes should NOT be allowed");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var colorBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
+
+ var depthBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 16, 16);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 32, 16);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]);
+ }
+
+ gl.deleteTexture(tex);
+ gl.deleteRenderbuffer(depthBuffer);
+ gl.deleteRenderbuffer(colorBuffer);
+ gl.deleteFramebuffer(fbo);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+function testUsingIncompleteFramebuffer() {
+ debug("");
+ debug("Test drawing or reading from an incomplete framebuffer");
+ var program = wtu.setupTexturedQuad(gl);
+ var tex = gl.createTexture();
+ wtu.fillTexture(gl, tex, 1, 1, [0,255,0,255]);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]);
+ debug("");
+ debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
+ testRenderingAndReading();
+
+ var colorBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]);
+ debug("");
+ debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
+ testRenderingAndReading();
+
+ function testRenderingAndReading() {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer");
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer");
+ // copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because
+ // the framebuffer is invalid OR INVALID_OPERATION because in the case of no attachments
+ // the framebuffer is not of a compatible type.
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION],
+ "copyTexImage2D from incomplete framebuffer");
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION],
+ "copyTexSubImage2D from incomplete framebuffer");
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer");
+ }
+
+ gl.deleteRenderbuffer(colorBuffer);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(tex);
+ gl.deleteProgram(program);
+}
+
+function testReadingFromMissingAttachment() {
+ debug("");
+ debug("Test drawing or reading from a framebuffer with no color image");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var object_type = gl.getFramebufferAttachmentParameter(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ if (object_type != gl.NONE)
+ testFailed("object type from empty attachment point should be NONE");
+ else
+ testPassed("object type from empty attachment point is NONE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query should not generate error");
+
+ var object_name = gl.getFramebufferAttachmentParameter(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
+ if (object_name)
+ testFailed("object name from empty attachment point should be null");
+ else
+ testPassed("object name from empty attachment point is null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query should not generate error");
+
+ var size = 16;
+
+ // The only scenario we can verify is an attempt to read or copy
+ // from a missing color attachment while the framebuffer is still
+ // complete.
+ var depthBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, size, size);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After depth renderbuffer setup");
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ // The FBO has no color attachment. ReadPixels, CopyTexImage2D,
+ // and CopyTexSubImage2D should all generate INVALID_OPERATION.
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Before ReadPixels from missing attachment");
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "After ReadPixels from missing attachment");
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Before CopyTexImage2D from missing attachment");
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, size, size, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "After CopyTexImage2D from missing attachment");
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Before CopyTexSubImage2D from missing attachment");
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, size, size);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "After CopyTexSubImage2D from missing attachment");
+
+ gl.deleteTexture(tex);
+ }
+
+ gl.deleteRenderbuffer(depthBuffer);
+ gl.deleteFramebuffer(fbo);
+}
+
+description("Test framebuffer object attachment behaviors");
+
+shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)");
+
+testFramebufferWebGL1RequiredCombinations();
+testDepthStencilAttachmentBehaviors();
+testFramebufferIncompleteAttachment();
+testFramebufferIncompleteMissingAttachment();
+testFramebufferWithImagesOfDifferentSizes();
+testUsingIncompleteFramebuffer();
+testReadingFromMissingAttachment();
+
+// -
+
+debug("");
+debug("Test calling framebufferTexture2D with impossible mip levels.");
+
+const fb = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+const tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 1000);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Mip level attachment impossibly high.");
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 10);
+wtu.glErrorShouldBe(gl, 0, "Mip level attachment within acceptable range.");
+
+// Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1636517 :
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 1000);
+wtu.glErrorShouldBe(gl, 0, "Mip level detachment can be impossibly high.");
+shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "0");
+
+// -
+
+debug("")
+var successfullyParsed = true;
+</script>
+
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-test.html
new file mode 100644
index 0000000000..5aa6c91847
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-test.html
@@ -0,0 +1,288 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Framebuffer Test Against WebGL 2</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+
+function testFramebufferRenderbuffer() {
+ debug("");
+ debug("Checking framebuffer/renderbuffer stuff.");
+
+ gl.getFramebufferAttachmentParameter(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
+ "getFramebufferAttachmentParameter(COLOR_ATTACHMENT0) on the default framebuffer.");
+ gl.getFramebufferAttachmentParameter(
+ gl.FRAMEBUFFER, gl.BACK, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "getFramebufferAttachmentParameter(BACK) on the default framebuffer.");
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "checkFramebufferStatus on the default framebuffer.");
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ 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.texImage2D(
+ gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "attach a texture to default framebuffer.");
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "detach default renderbuffer from default framebuffer.");
+
+ var rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, canvas.width, canvas.height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "allocate renderbuffer storage of a newly created renderbuffer.");
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "attach a renderbuffer to the default framebuffer.");
+
+ var fbtex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, fbtex);
+ gl.texImage2D(
+ gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ var fb = gl.createFramebuffer();
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bind a newly created framebuffer.");
+
+ var target = gl.READ_FRAMEBUFFER;
+ gl.getFramebufferAttachmentParameter(
+ target, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getFramebufferAttachmentParameter(READ_FRAMEBUFFER).");
+ assertMsg(gl.checkFramebufferStatus(target) != 0,
+ "checkFramebufferStatus(READ_FRAMEBUFFER) should succeed.");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "checkFramebufferStatus(READ_FRAMEBUFFER).");
+ var readFB = gl.createFramebuffer();
+ gl.bindFramebuffer(target, readFB);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindFramebuffer(READ_FRAMEBUFFER).");
+ assertMsg(readFB == gl.getParameter(gl.READ_FRAMEBUFFER_BINDING),
+ "bindFramebuffer(READ_FRAMEBUFFER) should change READ_FRAMEBUFFER_BINDING.");
+ assertMsg(fb == gl.getParameter(gl.DRAW_FRAMEBUFFER_BINDING),
+ "bindFramebuffer(READ_FRAMEBUFFER) should not change DRAW_FRAMEBUFFER_BINDING.");
+ gl.getFramebufferAttachmentParameter(
+ target, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) with no attachment.");
+ gl.framebufferTexture2D(target, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "framebufferTexImage2D(READ_FRAMEBUFFER).");
+ gl.framebufferRenderbuffer(target, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "framebufferRenderbuffer(READ_FRAMEBUFFER).");
+
+ var colorAttachmentsNum = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+ if (colorAttachmentsNum >= 2) {
+ var attachment = gl.COLOR_ATTACHMENT1;
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, fbtex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "framebufferTexImage2D(COLOR_ATTACHMENT1).");
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, null, 0);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, rb);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "framebufferRenderbuffer(COLOR_ATTACHMENT1).");
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, null);
+ }
+
+ gl.getFramebufferAttachmentParameter(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "with no attachment.");
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "attach a texture to a framebuffer.");
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "detach a texture from a framebuffer.");
+
+ function numLevelsFromSize(size) {
+ var levels = 0;
+ while ((size >> levels) > 0) {
+ ++levels;
+ }
+ return levels;
+ }
+
+ var maxTexSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
+ var maxLevels = numLevelsFromSize(maxTexSize);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, maxLevels - 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "framebufferTexture2D with an appropriate mipmap level.");
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, maxLevels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "framebufferTexture2D with a mipmap level out of range.");
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "attach a renderbuffer to a framebuffer.");
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "detach a renderbuffer from a framebuffer.");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bind default (null) framebuffer.");
+
+ // attach/detach a 2d texture to one framebuffer binding point,
+ // while no attachment to the other binding point.
+ function attachAndDetachTexture(targetA, targetB) {
+ gl.framebufferTexture2D(targetA, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "attach a texture to read/draw framebuffer binding point.");
+ gl.getFramebufferAttachmentParameter(
+ targetA, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on read/draw framebuffer.");
+ gl.getFramebufferAttachmentParameter(
+ targetB, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on read/draw framebuffer with no attachment.");
+ gl.framebufferTexture2D(targetA, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "detach a texture from read/draw framebuffer.");
+ }
+
+ var readFBWithTexture = gl.createFramebuffer();
+ var drawFBWithTexture = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFBWithTexture);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, drawFBWithTexture);
+ attachAndDetachTexture(gl.READ_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER);
+ attachAndDetachTexture(gl.DRAW_FRAMEBUFFER, gl.READ_FRAMEBUFFER);
+
+ // attach different textures as color attachment to read and draw framebuffer respectively,
+ // then detach these attachments.
+ var fbtex1 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, fbtex1);
+ gl.texImage2D(
+ gl.TEXTURE_2D, 0, gl.RG8, canvas.width, canvas.height, 0, gl.RG, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex1, 0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbtex, 0);
+ shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.READ_FRAMEBUFFER, ' +
+ 'gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE)');
+ shouldBe('gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ' +
+ 'gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE)', '0');
+
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.getFramebufferAttachmentParameter(
+ gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on read framebuffer with no attachment.");
+ gl.getFramebufferAttachmentParameter(
+ gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on draw framebuffer.");
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.getFramebufferAttachmentParameter(
+ gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on draw framebuffer with no attachment.");
+
+ // attach/detach a renderbuffer to one framebuffer binding point,
+ // while no attachment to the other binding point.
+ function attachAndDetachRenderbuffer(targetA, targetB) {
+ gl.framebufferRenderbuffer(targetA, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "attaching a renderbuffer to a read/draw framebuffer.");
+ gl.getFramebufferAttachmentParameter(
+ targetA, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on read/draw framebuffer.");
+ gl.getFramebufferAttachmentParameter(
+ targetB, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) " +
+ "on read/draw framebuffer with no attachment.");
+ gl.framebufferRenderbuffer(targetA, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "detach a renderbuffer from a read/draw framebuffer.");
+ }
+
+ var readFBWithRenderbuffer = gl.createFramebuffer();
+ var drawFBWithRenderbuffer = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFBWithRenderbuffer);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, drawFBWithRenderbuffer);
+ attachAndDetachRenderbuffer(gl.READ_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER);
+ attachAndDetachRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.READ_FRAMEBUFFER);
+
+ // attach different renderbuffers to read and draw framebuffer respectively,
+ // then detach these attachments.
+ var depthRB = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, depthRB);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, canvas.width, canvas.height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "allocating renderbuffer storage of a newly created renderbuffer.");
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.READ_FRAMEBUFFER, ' +
+ 'gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_RED_SIZE)');
+ gl.getFramebufferAttachmentParameter(
+ gl.READ_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_DEPTH_SIZE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) " +
+ "on read framebuffer without depth attachment.");
+ shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, ' +
+ 'gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE)');
+ gl.getFramebufferAttachmentParameter(
+ gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_RED_SIZE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) " +
+ "on draw framebuffer without color attachment.");
+
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.getFramebufferAttachmentParameter(
+ gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_RED_SIZE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) " +
+ "on read framebuffer with no attachment.");
+ shouldBeNonZero('gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, ' +
+ 'gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE)');
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
+ gl.getFramebufferAttachmentParameter(
+ gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_DEPTH_SIZE);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) " +
+ "on draw framebuffer with no attachment.");
+
+ // binding read/draw framebuffer to default framebuffer
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bind read framebuffer to default (null) framebuffer.");
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bind draw framebuffer to default (null) framebuffer.");
+}
+
+description("This tests framebuffer/renderbuffer-related functions");
+
+var canvas = document.getElementById("canvas");
+shouldBeNonNull("gl = wtu.create3DContext(canvas, undefined, 2)");
+
+testFramebufferRenderbuffer();
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-texture-layer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-texture-layer.html
new file mode 100644
index 0000000000..0e435d6a2e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-texture-layer.html
@@ -0,0 +1,144 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL FramebufferTextureLayer 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+var canvas = document.getElementById("canvas");
+
+function numLevelsFromSize(size) {
+ var levels = 0;
+ while ((size >> levels) > 0) {
+ ++levels;
+ }
+ return levels;
+}
+
+function checkFramebuffer(expected) {
+ var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (expected.indexOf(actual) < 0) {
+ var msg = "checkFramebufferStatus expects [";
+ for (var index = 0; index < expected.length; ++index) {
+ msg += wtu.glEnumToString(gl, expected[index]);
+ if (index + 1 < expected.length)
+ msg += ", ";
+ }
+ msg += "], was " + wtu.glEnumToString(gl, actual);
+ testFailed(msg);
+ } else {
+ var msg = "checkFramebufferStatus got " + wtu.glEnumToString(gl, actual) +
+ " as expected";
+ testPassed(msg);
+ }
+}
+
+function testFramebufferTextureLayer() {
+ debug("");
+ debug("Checking FramebufferTextureLayer stuff.");
+
+ var tex3d = gl.createTexture();
+ var fb = gl.createFramebuffer();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texImage3D(gl.TEXTURE_3D,
+ 0, // level
+ gl.RGBA, // internalFormat
+ 1, // width
+ 1, // height
+ 1, // depth
+ 0, // border
+ gl.RGBA, // format
+ gl.UNSIGNED_BYTE, // type
+ new Uint8Array([0xff, 0x00, 0x00, 0x00])); // data
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "attaching a texture to default framebuffer should generate INVALID_OPERATION.");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "attaching a texture to a framebuffer should succeed.");
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, null, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "detaching a texture from a framebuffer should succeed.");
+
+ var maxTexSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE);
+ var maxLevels = numLevelsFromSize(maxTexSize);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, maxLevels - 1, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling framebufferTextureLayer with an appropriate mipmap level should succeed.");
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, maxLevels, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling framebufferTextureLayer with a mipmap level out of range should generate INVALID_VALUE.");
+
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, -1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling framebufferTextureLayer with a negative texture layer should generate INVALID_VALUE.");
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, maxTexSize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling framebufferTextureLayer with a texture layer out of range should generate INVALID_VALUE.");
+
+ var tex2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex2d, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "attaching a 2d texture to a framebuffer should generate INVALID_OPERATION.");
+
+ var texDepthStencil = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, texDepthStencil);
+ var fbDepthStencil = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbDepthStencil);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY,
+ 0, // level
+ gl.DEPTH24_STENCIL8, // internalFormat
+ 1, // width
+ 1, // height
+ 1, // depth
+ 0, // border
+ gl.DEPTH_STENCIL, // format
+ gl.UNSIGNED_INT_24_8, // type
+ new Uint32Array([0])); // data
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, texDepthStencil, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "attaching a depth_stencil texture to a framebuffer should succeed.");
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ // Clean up
+ gl.deleteTexture(tex3d);
+ gl.deleteTexture(texDepthStencil);
+ gl.deleteTexture(tex2d);
+ gl.deleteFramebuffer(fb);
+ gl.deleteFramebuffer(fbDepthStencil);
+}
+
+description("This tests framebufferTextureLayer.");
+
+shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)");
+
+testFramebufferTextureLayer();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/invalidate-framebuffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/invalidate-framebuffer.html
new file mode 100644
index 0000000000..426148cf5e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/invalidate-framebuffer.html
@@ -0,0 +1,230 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Invalidate Framebuffer Against WebGL 2</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script>
+"use strict";
+description("This tests invalidateFramebuffer and invalidateSubFramebuffer");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, { depth : true, stencil : false }, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("invalidate framebuffer.");
+
+ gl.clearColor(0, 0, 0, 0);
+
+ // setup framebuffer with depth attachment and multi-sampled color attachment
+ var fb_m = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb_m);
+
+ var rb_m = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb_m);
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb_m);
+ // invalidate the framebuffer when the attachment is incomplete: no storage allocated to the attached renderbuffer
+ invalidateIncompleteAttachment(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.RGBA8, canvas.width, canvas.height);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no errors after attaching a multi-sampled renderbuffer to fbo.");
+
+ var rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
+ // invalidate the framebuffer when the attachment is incomplete: no storage allocated to the attached renderbuffer
+ invalidateIncompleteAttachment(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.DEPTH_COMPONENT16, canvas.width, canvas.height);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no errors after attaching a renderbuffer to fbo.");
+
+ // in real world case, after some drawing, we can invalidate the depth attachment of the bound fbo
+ invalidation(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT);
+
+ // set up framebuffer to blit to and read back from
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ var buffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, canvas.width, canvas.height);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, buffer);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no errors after attaching a renderbuffer to fbo.");
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb_m);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
+ gl.blitFramebuffer(0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no errors after bliting framebuffer.");
+
+ // invalidate the multi-sampled color attachment of the bound read framebuffer after blitFramebuffer.
+ invalidation(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT);
+
+ var maxColorAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+ gl.invalidateSubFramebuffer(gl.READ_FRAMEBUFFER, [gl.COLOR_ATTACHMENT0 + maxColorAttachments], 5, 5, 10, 10);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM],
+ "calling invalidateSubFramebuffer to invalidate a COLOR_ATTACHMENT that exceeds MAX_COLOR_ATTACHMENT should generate INVALID_ENUM or INVALID_OPERATION.");
+ gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, [gl.COLOR_ATTACHMENT0 + maxColorAttachments]);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM],
+ "calling invalidateFramebuffer to invalidate a COLOR_ATTACHMENT that exceeds MAX_COLOR_ATTACHMENT should generate INVALID_ENUM or INVALID_OPERATION.");
+
+ // invalidate the default framebuffer
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ invalidation(gl.FRAMEBUFFER, gl.DEPTH, gl.STENCIL);
+
+ gl.deleteFramebuffer(fb_m);
+ gl.deleteRenderbuffer(rb_m);
+ gl.deleteRenderbuffer(rb);
+ gl.deleteFramebuffer(fb);
+ gl.deleteRenderbuffer(buffer);
+
+ testInvalidateRGBThenDraw();
+ testInvalidateWithBlend();
+}
+
+function invalidation(target, valid_attachment, invalid_attachment) {
+ gl.invalidateSubFramebuffer(target, [invalid_attachment], 5, 5, 10, 10);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateSubFramebuffer to invalidate a specified attachment that does not exist will be ignored. There should be no errors.");
+ gl.invalidateSubFramebuffer(target, [valid_attachment], 5, 5, 10, 10);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateSubFramebuffer should succeed.");
+
+ gl.invalidateSubFramebuffer(target, [valid_attachment], 5, 5, -5, -5);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "calling invalidateSubFramebuffer should generate INVALID_VALUE if width < 0 or height < 0.");
+
+ gl.invalidateSubFramebuffer(target, [valid_attachment], -5, -5, 10, 10);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateSubFramebuffer should succeed, even the invalidated pixels may be outside of the framebuffer allocated to current context. These pixels are ignored.");
+ gl.invalidateSubFramebuffer(target, [valid_attachment], 5, 5, 20, 20);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateSubFramebuffer should succeed, even the invalidated pixels may be outside of the framebuffer allocated to current context. These pixels are ignored.");
+
+ gl.invalidateFramebuffer(target, [invalid_attachment]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateFramebuffer to invalidate a specified attachment that does not exist will be ignored. There should be no errors.");
+ gl.invalidateFramebuffer(target, [valid_attachment]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateFramebuffer should succeed.");
+}
+
+function invalidateIncompleteAttachment(target, incomplete_attachment) {
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)",
+ "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+ gl.invalidateSubFramebuffer(target, [incomplete_attachment], 5, 5, 10, 10);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateSubFramebuffer to invalidate an incomplete attachment will be ignored. There should be no errors");
+ gl.invalidateFramebuffer(target, [incomplete_attachment]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateFramebuffer to invalidate an incomplete attachment will be ignored. There should be no errors.");
+}
+
+function testInvalidateRGBThenDraw() {
+ const program = wtu.setupColorQuad(gl);
+
+ const texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+
+ const fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
+
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Verify that clearing alpha is ineffective on an RGB format.
+ const black = [0, 0, 0, 255];
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, black, `should be black`);
+
+ // Invalidate the framebuffer contents.
+ gl.invalidateFramebuffer(gl.FRAMEBUFFER, [gl.COLOR_ATTACHMENT0]);
+
+ // Without an explicit clear, draw blue and make sure alpha is unaffected. If RGB is emulated
+ // with RGBA, the previous invalidate shouldn't affect the alpha value.
+ wtu.drawFloatColorQuad(gl, [0, 0, 1, 1]);
+ const blue = [0, 0, 255, 255];
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, blue, `should be blue`);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteProgram(program);
+}
+
+function testInvalidateWithBlend() {
+ // Create the framebuffer that will be invalidated
+ const renderTarget = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, renderTarget);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ const drawFBO = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, drawFBO);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTarget, 0);
+
+ // Clear the framebuffer and invalidate it.
+ gl.clearColor(1, 1, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.invalidateFramebuffer(gl.DRAW_FRAMEBUFFER, [gl.COLOR_ATTACHMENT0]);
+
+ // Upload data to it
+ const cyan = new Uint8Array([0, 255, 255, 255]);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, cyan);
+
+ // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, drawFBO);
+
+ const program = wtu.setupColorQuad(gl);
+
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+ wtu.drawFloatColorQuad(gl, [1, 0, 0, 0.5]);
+ const expected = [127, 127, 127, 191];
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, expected, `should be ${expected}`, 1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling invalidateFramebuffer and then uploading data to texture in framebuffer. There should be no errors");
+
+ gl.deleteTexture(renderTarget);
+ gl.deleteFramebuffer(drawFBO);
+ gl.deleteProgram(program);
+ gl.disable(gl.BLEND);
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-draws-between-blits.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-draws-between-blits.html
new file mode 100644
index 0000000000..bc4ea25a95
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-draws-between-blits.html
@@ -0,0 +1,207 @@
+<!--
+Copyright (c) 2022 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="128" height="64" style="width: 32px; height: 32px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+const wtu = WebGLTestUtils;
+description(' Test multisample with blitting between draws');
+
+const gl = wtu.create3DContext("canvas", null, 2);
+const w = 128;
+const h = 64;
+
+if (!gl) {
+ testFailed('canvas.getContext() failed');
+} else {
+ gl.viewport(0, 0, w, h);
+ runTest(gl, 4);
+}
+
+function runTest(gl, sampleCount) {
+ const vs = `#version 300 es
+
+ layout(location = 0) in vec4 position;
+ uniform mat4 mat;
+
+ void main() {
+ gl_Position = mat * position;
+ }
+ `;
+
+ const fs = `#version 300 es
+ precision mediump float;
+ uniform vec4 color;
+ out vec4 outColor;
+ void main() {
+ outColor = color;
+ }
+ `;
+
+ const texVS = `#version 300 es
+
+ layout(location = 0) in vec4 position;
+ out vec2 texcoord;
+ uniform mat4 mat;
+
+ void main() {
+ gl_Position = mat * position;
+ texcoord = position.xy;
+ }
+ `;
+
+ const texFS = `#version 300 es
+ precision mediump float;
+ in vec2 texcoord;
+ uniform sampler2D tex;
+ out vec4 outColor;
+ void main() {
+ outColor = texture(tex, texcoord);
+ }
+ `;
+
+ const msRB = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, msRB);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, w, h);
+
+ const msFB = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, msFB);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msRB);
+
+ const dTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, dTex);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+
+ const dFB = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dFB);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, dTex, 0);
+
+ const positionLoc = 0; // hard coded in shaders so they match
+ const buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ 0, 0,
+ 1, 0,
+ 0, 1,
+ 0, 1,
+ 1, 0,
+ 1, 1,
+ ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(positionLoc);
+ gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
+
+ const program = wtu.setupProgram(gl, [vs, fs]);
+ const texProgram = wtu.setupProgram(gl, [texVS, texFS]);
+
+ const colorLoc = gl.getUniformLocation(program, 'color');
+ const matLoc = gl.getUniformLocation(program, 'mat');
+ const texMatLoc = gl.getUniformLocation(texProgram, 'mat');
+
+ gl.useProgram(program);
+
+ const drawAndResolve = (color, mat) => {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, msFB);
+ gl.uniform4fv(colorLoc, color);
+ gl.uniformMatrix4fv(matLoc, false, mat);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dFB);
+ gl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ };
+
+ const check = (x, y, w, h, expected, msg) => {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, dFB);
+ const tolerance = 2; // For multisampling resolution differences between GPUs
+ wtu.checkCanvasRect(gl, x, y, w, h, expected, msg, tolerance);
+ };
+
+ const f32Red = [1, 0, 0, 1];
+ const f32Green = [0, 1, 0, 1];
+ const f32Gray = [0.5, 0.5, 0.5, 1];
+
+ const u8Red = [255, 0, 0, 255];
+ const u8Green = [ 0, 255, 0, 255];
+ const u8LightRed = [255, 128, 128, 255];
+ const u8LightGreen = [128, 255, 128, 255];
+
+ debug('fill with red');
+ drawAndResolve(f32Red, [
+ 2, 0, 0, 0,
+ 0, 2, 0, 0,
+ 0, 0, 1, 0,
+ -1, -1, 0, 1,
+ ]);
+ check(0, 0, w, h, u8Red, 'whole thing');
+
+ debug('draw right in green');
+ drawAndResolve(f32Green, [
+ 1, 0, 0, 0,
+ 0, 2, 0, 0,
+ 0, 0, 1, 0,
+ 0, -1, 0, 1,
+ ]);
+ check(0, 0, w / 2, h, u8Red, 'left');
+ check(w / 2, 0, w / 2, h, u8Green, 'right');
+
+ debug('draw middle in gray with blending');
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.ONE, gl.ONE);
+ drawAndResolve(f32Gray, [
+ 1, 0, 0, 0,
+ 0, 2, 0, 0,
+ 0, 0, 1, 0,
+ -0.5, -1, 0, 1,
+ ]);
+ gl.disable(gl.BLEND);
+
+ /*
+ expected
+ +-----+-------+---------+--------+
+ | red | ltRed | ltGreen | green |
+ +-----+-------+---------+--------+
+ 0,0
+ */
+
+ check(0, 0, w / 4, h , u8Red, 'left edge')
+ check(w * 3 / 4, 0, w / 4, h, u8Green, 'right edge');
+ check(w / 4, 0, w / 4, h, u8LightRed, 'left of center');
+ check(w / 2, 0, w / 4, h, u8LightGreen, 'right of center');
+
+ // show it
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.useProgram(texProgram);
+ gl.uniformMatrix4fv(texMatLoc, false, [
+ 2, 0, 0, 0,
+ 0, 2, 0, 0,
+ 0, 0, 1, 0,
+ -1, -1, 0, 1,
+ ]);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ gl.deleteRenderbuffer(msRB);
+ gl.deleteTexture(dTex);
+ gl.deleteFramebuffer(msFB);
+ gl.deleteFramebuffer(dFB);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-with-full-sample-counts.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-with-full-sample-counts.html
new file mode 100644
index 0000000000..2e04385f28
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-with-full-sample-counts.html
@@ -0,0 +1,98 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="32" height="32" style="width: 32px; height: 32px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description(' Test multisample with sample number from 1 to max sample number which also includes the samples that may not be in the supported sample list');
+
+var gl = wtu.create3DContext("canvas", null, 2);
+var size = 32;
+var program;
+
+if (!gl) {
+ testFailed('canvas.getContext() failed');
+} else {
+ program = wtu.setupColorQuad(gl);
+ gl.viewport(0, 0, size, size);
+ var supportedSampleCountArray = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES);
+ var iterationCount = supportedSampleCountArray[0] + 1;
+ for (var i = 1; i < iterationCount; i++)
+ {
+ runTest(gl, i, false);
+ runTest(gl, i, true);
+ }
+}
+
+function runTest(gl, sampleCount, isInverted) {
+ // Setup multi-sample RBO
+ var msColorRbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, msColorRbo);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, sampleCount, gl.RGBA8, size, size);
+
+ // Setup multi-sample FBO.
+ var msFbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, msFbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msColorRbo);
+
+ // Setup resolve color RBO.
+ var resolveColorRbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, resolveColorRbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, size, size);
+ // Setup resolve FBO
+ var resolveFbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, resolveColorRbo);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, msFbo);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.enable(gl.SAMPLE_COVERAGE);
+ var coverageValue = isInverted ? 0.0 : 1.0;
+ gl.sampleCoverage(coverageValue, isInverted);
+
+ var quadColor = [1.0, 0.0, 0.0, 1.0];
+ gl.useProgram(program);
+ wtu.drawFloatColorQuad(gl, quadColor);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFbo);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo);
+ wtu.checkCanvasRect(gl, 0, 0, size, size, [255, 0, 0, 255],
+ "User buffer has been rendered to red with sample = "
+ + sampleCount + ", coverageValue = " + coverageValue
+ + " and isInverted = " + isInverted, 3);
+
+ gl.disable(gl.SAMPLE_COVERAGE);
+ gl.deleteRenderbuffer(msColorRbo);
+ gl.deleteRenderbuffer(resolveColorRbo);
+ gl.deleteFramebuffer(msFbo);
+ gl.deleteFramebuffer(resolveFbo);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html
new file mode 100644
index 0000000000..7bd87890e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html
@@ -0,0 +1,180 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="testbed" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description('Verify multisampled depth renderbuffers are initialized to 1.0 before being read in WebGL');
+
+var gl = wtu.create3DContext("testbed", null, 2);
+
+if (!gl) {
+ testFailed('canvas.getContext() failed');
+} else {
+ // Set the clear color to green. It should never show up.
+ gl.clearColor(0, 1, 0, 1);
+
+ debug("Test renderbufferStorageMultisample with webgl1's DEPTH_STENCIL.");
+ {
+ const rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ wtu.shouldGenerateGLError(gl, 0,
+ "gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, gl.DEPTH_STENCIL, 1, 1)");
+ wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION,
+ "gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 1, gl.DEPTH_STENCIL, 1, 1)");
+ wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION,
+ "gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, gl.DEPTH_STENCIL, 1, 1)");
+ gl.deleteRenderbuffer(rb);
+ }
+
+ let c = gl.canvas;
+ var maxSamples = gl.getInternalformatParameter(
+ gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES)[0];
+ for (let i = 0; i < 2; ++i) {
+ // Non-multisampled tests
+ runTest(gl, {alloc1: {w: c.width, h: c.height, s: 0}, alloc2: null});
+ runTest(gl, {alloc1: null, alloc2: {w: c.width, h: c.height, s: 0}});
+ // Multisampled tests
+ runTest(gl, {alloc1: {w: c.width, h: c.height, s: maxSamples}, alloc2: null});
+ runTest(gl, {alloc1: null, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+
+ // Tests for initially allocating at the wrong size.
+ // This is caused by a Qualcomm driver bug: http://crbug.com/696126
+ runTest(gl, {alloc1: {w: 5, h: 5, s: maxSamples}, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+ }
+
+ // Testing buffer clearing won't change the clear values.
+ var clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
+ shouldBe("clearColor", "[0, 1, 0, 1]");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+}
+
+function runTest(gl, params) {
+ debug("");
+ debug("Test for depth buffer: " + JSON.stringify(params));
+ let resolve = params.alloc2 ? params.alloc2 : params.alloc1;
+ gl.viewport(0, 0, resolve.w, resolve.h);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 0, 0, 0],
+ "internal buffers have been initialized to 0");
+
+ gl.disable(gl.DEPTH_TEST);
+
+ // fill the back buffer so we know that reading below happens from
+ // the renderbuffer.
+ gl.clearDepth(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ // Set up (color+depth) non-multisampled buffer to blit to and read back from.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var buffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, resolve.w, resolve.h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, buffer);
+ var depthBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, resolve.w, resolve.h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("Skip: framebuffer is allowed to be incomplete.");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+ gl.clearDepth(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 255, 0, 255],
+ "user buffer has been cleared to green");
+
+ // Set up (depth-only) multisampled buffer to test.
+ var fbo_m = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo_m);
+ var buffer_m = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer_m);
+
+ if (params.alloc1) {
+ allocStorage(params.alloc1.w, params.alloc1.h, params.alloc1.s);
+ }
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, buffer_m);
+ if (params.alloc2) {
+ if (params.alloc1) {
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("Skip: framebuffer is allowed to be incomplete.");
+ return;
+ }
+ // Clear the FBO in order to make sure framebufferRenderbuffer is
+ // committed. (In Firefox, framebufferRenderbuffer is deferred, so this
+ // is needed to trigger the bug.)
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ allocStorage(params.alloc2.w, params.alloc2.h, params.alloc2.s);
+ }
+
+ function allocStorage(width, height, samples) {
+ gl.renderbufferStorageMultisample(
+ gl.RENDERBUFFER, samples, gl.DEPTH_COMPONENT16, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no error after renderbufferStorageMultisample(DEPTH_COMPONENT16).");
+ }
+
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("Skip: framebuffer is allowed to be incomplete.");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+
+ // Blit from multisampled buffer to non-multisampled buffer.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_m);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
+ gl.clearDepth(0);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ // Blit depth from fbo_m (should be default value of 1.0) to fbo (should be 0.0).
+ gl.blitFramebuffer(0, 0, resolve.w, resolve.h,
+ 0, 0, resolve.w, resolve.h,
+ gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ // fbo depth should now be 1.0.
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ // Draw a blue quad (at clip z = 0.0, so depth = 0.5) (should pass the depth test: 0.5 < 1.0)
+ gl.depthFunc(gl.LESS);
+ gl.enable(gl.DEPTH_TEST);
+ wtu.setupColorQuad(gl);
+ wtu.setFloatDrawColor(gl, [0, 0, 1, 1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 0, 255, 255]);
+
+ gl.deleteFramebuffer(fbo_m);
+ gl.deleteRenderbuffer(buffer_m);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteRenderbuffer(buffer);
+
+ gl.canvas.width += 1;
+ gl.canvas.height += 1;
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+ debug('');
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html
new file mode 100644
index 0000000000..0b27da661d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html
@@ -0,0 +1,149 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="testbed" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description('Verify multisampled renderbuffers are initialized to 0 before being read in WebGL');
+
+var gl = wtu.create3DContext("testbed", null, 2);
+
+if (!gl) {
+ testFailed('canvas.getContext() failed');
+} else {
+ // Set the clear color to green. It should never show up.
+ gl.clearColor(0, 1, 0, 1);
+
+ let c = gl.canvas;
+ var maxSamples = gl.getInternalformatParameter(
+ gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES)[0];
+ for (let i = 0; i < 2; ++i) {
+ runTest(gl, {alloc1: {w: c.width, h: c.height, s: maxSamples}, alloc2: null});
+ runTest(gl, {alloc1: null, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+
+ // Tests for initially allocating at the wrong size.
+ // This is caused by a Qualcomm driver bug: http://crbug.com/696126
+ runTest(gl, {alloc1: {w: 5, h: 5, s: maxSamples}, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+ runTest(gl, {alloc1: {w: 5, h: 5, s: maxSamples}, alloc2: {w: c.width, h: c.height, s: 0}});
+ runTest(gl, {alloc1: {w: 5, h: 5, s: 0}, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+ }
+
+ // Testing buffer clearing won't change the clear values.
+ var clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
+ shouldBe("clearColor", "[0, 1, 0, 1]");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+}
+
+function runTest(gl, params) {
+ debug("Test for color buffer: " + JSON.stringify(params));
+ let resolve = params.alloc2 ? params.alloc2 : params.alloc1;
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 0, 0, 0],
+ "internal buffers have been initialized to 0");
+
+ // fill the back buffer so we know that reading below happens from
+ // the renderbuffer.
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Set up non-multisampled buffer to blit to and read back from.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var buffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, resolve.w, resolve.h);
+ attachBuffer(buffer);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)",
+ "gl.FRAMEBUFFER_COMPLETE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 255, 0, 255],
+ "user buffer has been cleared to green");
+
+ // Set up multisampled buffer to test.
+ var fbo_m = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo_m);
+ var buffer_m = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer_m);
+
+ if (params.alloc1) {
+ allocStorage(params.alloc1.w, params.alloc1.h, params.alloc1.s);
+ }
+ attachBuffer(buffer_m);
+ if (params.alloc2) {
+ if (params.alloc1) {
+ // Clear the FBO in order to make sure framebufferRenderbuffer is
+ // committed. (In Firefox, framebufferRenderbuffer is deferred, so
+ // this is needed to trigger the bug.)
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ }
+ allocStorage(params.alloc2.w, params.alloc2.h, params.alloc2.s);
+ }
+
+ function allocStorage(width, height, samples) {
+ gl.renderbufferStorageMultisample(
+ gl.RENDERBUFFER, samples, gl.RGBA8, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no error after renderbufferStorageMultisample(RGBA8).");
+ }
+
+ function attachBuffer(buffer) {
+ gl.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, buffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no error after framebufferRenderbuffer.");
+ }
+
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)",
+ "gl.FRAMEBUFFER_COMPLETE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+
+ // Blit from multisampled buffer to non-multisampled buffer.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_m);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
+ // Blit color from fbo_m (should be black) to fbo (should be green)
+ gl.blitFramebuffer(0, 0, resolve.w, resolve.h,
+ 0, 0, resolve.w, resolve.h,
+ gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 0, 0, 0],
+ "user buffer has been initialized to 0");
+
+ gl.deleteFramebuffer(fbo_m);
+ gl.deleteRenderbuffer(buffer_m);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteRenderbuffer(buffer);
+
+ // this clear should not matter we are about to resize
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.canvas.width += 1;
+ gl.canvas.height += 1;
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+ debug('');
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html
new file mode 100644
index 0000000000..cb351454d2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html
@@ -0,0 +1,167 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="testbed" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description('Verify multisampled stencil renderbuffers are initialized to 0 before being read in WebGL');
+
+var gl = wtu.create3DContext("testbed", null, 2);
+
+if (!gl) {
+ testFailed('canvas.getContext() failed');
+} else {
+ // Set the clear color to green. It should never show up.
+ gl.clearColor(0, 1, 0, 1);
+ gl.disable(gl.DEPTH_TEST);
+
+ let c = gl.canvas;
+ var maxSamples = gl.getInternalformatParameter(
+ gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES)[0];
+ for (let i = 0; i < 2; ++i) {
+ // Non-multisampled tests
+ runTest(gl, {alloc1: {w: c.width, h: c.height, s: 0}, alloc2: null});
+ runTest(gl, {alloc1: null, alloc2: {w: c.width, h: c.height, s: 0}});
+ // Multisampled tests
+ runTest(gl, {alloc1: {w: c.width, h: c.height, s: maxSamples}, alloc2: null});
+ runTest(gl, {alloc1: null, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+
+ // Tests for initially allocating at the wrong size.
+ // This is caused by a Qualcomm driver bug: http://crbug.com/696126
+ runTest(gl, {alloc1: {w: 5, h: 5, s: maxSamples}, alloc2: {w: c.width, h: c.height, s: maxSamples}});
+ }
+
+ // Testing buffer clearing won't change the clear values.
+ var clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
+ shouldBe("clearColor", "[0, 1, 0, 1]");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+}
+
+function runTest(gl, params) {
+ debug("Test for stencil buffer: " + JSON.stringify(params));
+ let resolve = params.alloc2 ? params.alloc2 : params.alloc1;
+ gl.viewport(0, 0, resolve.w, resolve.h);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 0, 0, 0],
+ "internal buffers have been initialized to 0");
+
+ gl.disable(gl.STENCIL_TEST);
+
+ // fill the back buffer so we know that reading below happens from
+ // the renderbuffer.
+ gl.clearStencil(2);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Set up (color+stencil) non-multisampled buffer to blit to and read back from.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var buffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, resolve.w, resolve.h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, buffer);
+ var stencilBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, stencilBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, resolve.w, resolve.h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, stencilBuffer);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("Skip: framebuffer is allowed to be incomplete.");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+ gl.clearStencil(2);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 255, 0, 255],
+ "user buffer has been cleared to green");
+
+ // Set up (stencil-only) multisampled buffer to test.
+ var fbo_m = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo_m);
+ var buffer_m = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, buffer_m);
+
+ if (params.alloc1) {
+ allocStorage(params.alloc1.w, params.alloc1.h, params.alloc1.s);
+ }
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, buffer_m);
+ if (params.alloc2) {
+ if (params.alloc1) {
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("Skip: framebuffer is allowed to be incomplete.");
+ return;
+ }
+ // Clear the FBO in order to make sure framebufferRenderbuffer is
+ // committed. (In Firefox, framebufferRenderbuffer is deferred, so this
+ // is needed to trigger the bug.)
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ }
+ allocStorage(params.alloc2.w, params.alloc2.h, params.alloc2.s);
+ }
+
+ function allocStorage(width, height, samples) {
+ gl.renderbufferStorageMultisample(
+ gl.RENDERBUFFER, samples, gl.STENCIL_INDEX8, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "should be no error after renderbufferStorageMultisample(STENCIL_INDEX8).");
+ }
+
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("Skip: framebuffer is allowed to be incomplete.");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+
+ // Blit from multisampled buffer to non-multisampled buffer.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_m);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
+ gl.clearStencil(2);
+ gl.clear(gl.STENCIL_BUFFER_BIT);
+ // Blit stencil from fbo_m (should be default value of 0) to fbo (should be 2).
+ gl.blitFramebuffer(0, 0, resolve.w, resolve.h,
+ 0, 0, resolve.w, resolve.h,
+ gl.STENCIL_BUFFER_BIT, gl.NEAREST);
+ // fbo stencil should now be 0.
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ // Draw a blue quad (with stencil = 1) (should pass the stencil test: 1 > 0)
+ gl.stencilFunc(gl.GREATER, 1, 0xffffffff);
+ gl.enable(gl.STENCIL_TEST);
+ wtu.setupColorQuad(gl);
+ wtu.setFloatDrawColor(gl, [0, 0, 1, 1]);
+ wtu.drawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, resolve.w, resolve.h,
+ [0, 0, 255, 255]);
+
+ gl.deleteFramebuffer(fbo_m);
+ gl.deleteRenderbuffer(buffer_m);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteRenderbuffer(buffer);
+
+ gl.canvas.width += 1;
+ gl.canvas.height += 1;
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'should be no errors');
+ debug('');
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/readbuffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/readbuffer.html
new file mode 100644
index 0000000000..56bfd656a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/readbuffer.html
@@ -0,0 +1,174 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test readBuffer Against WebGL 2</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script>
+"use strict";
+description("This tests reading from fbo");
+
+var clearDrawingbuffer = function(color) {
+ gl.clearColor(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+}
+
+var validateReadingFromFramebuffer = function(color, expected, msg) {
+ var pixels = new Uint8Array(1 * 1 * 4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ wtu.glErrorShouldBe(gl, expected, msg);
+ if (expected == gl.NO_ERROR)
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, color,
+ "the color should be [" + color + "]");
+}
+
+var setupRenderbuffer = function(attachment) {
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, canvas.width, canvas.height);
+ return renderbuffer;
+}
+
+var testReadBufferOnDefaultFB = function() {
+ gl.readBuffer(gl.NONE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling readBuffer with GL_NONE on the default framebuffer should succeed.");
+ var pixels = new Uint8Array(1 * 1 * 4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "should generate INVALID_OPERATION when reading from framebuffer and read buffer is GL_NONE.");
+ gl.readBuffer(gl.BACK);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling readBuffer with GL_BACK on the default framebuffer should succeed.");
+
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "calling readBuffer with GL_COLOR_ATTACHMENT0 on the default framebuffer should generate INVALID_OPERATION.");
+}
+
+var testReadBufferOnFBO = function() {
+ gl.readBuffer(gl.BACK);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "calling readBuffer with GL_BACK on fbo should generate INVALID_OPERATION.");
+
+ gl.readBuffer(gl.NONE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling readBuffer with GL_NONE on fbo should succeed.");
+ var pixels = new Uint8Array(1 * 1 * 4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "should generate INVALID_OPERATION when reading from framebuffer and read buffer is GL_NONE.");
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling readBuffer with GL_COLOR_ATTACHMENT0 on fbo should succeed.");
+
+ var maxColorAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0 + maxColorAttachments);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "calling readBuffer with GL_COLOR_ATTACHMENTi that exceeds MAX_COLOR_ATTACHMENT on fbo should generate INVALID_OPERATION.");
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "calling readBuffer with GL_COLOR_ATTACHMENT1 on the fbo should succeed.");
+ shouldBe('gl.getParameter(gl.READ_BUFFER)', 'gl.COLOR_ATTACHMENT1');
+}
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking reading from framebuffer.");
+
+ // Test on the default framebuffer. Read buffer is GL_BACK by default.
+ var backColor = [0, 0, 0, 255];
+ clearDrawingbuffer(backColor);
+ validateReadingFromFramebuffer(backColor, gl.NO_ERROR,
+ "should be no errors when reading from GL_BACK on the default framebuffer.");
+
+ shouldBe('gl.getParameter(gl.READ_BUFFER)', 'gl.BACK');
+ testReadBufferOnDefaultFB();
+
+ // Test on fbo. Read buffer is GL_COLOR_ATTACHMENT0 by default
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ var colorbuffer = setupRenderbuffer(gl.COLOR_ATTACHMENT0);
+ var red = [255, 0, 0, 255];
+ clearDrawingbuffer(red);
+ validateReadingFromFramebuffer(red, gl.NO_ERROR,
+ "should be no errors when reading from GL_COLOR_ATTACHMENT0 on fbo.");
+
+ shouldBe('gl.getParameter(gl.READ_BUFFER)', 'gl.COLOR_ATTACHMENT0');
+ testReadBufferOnFBO();
+
+ // Test on user defined read buffer (GL_COLOR_ATTACHMENT1) with or without corresponding image on fbo.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ var colorbuffer1 = setupRenderbuffer(gl.COLOR_ATTACHMENT1);
+ var green = [0, 255, 0, 255];
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ clearDrawingbuffer(green);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error after setup and clear render buffer");
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ validateReadingFromFramebuffer(green, gl.NO_ERROR,
+ "should be no errors when reading from GL_COLOR_ATTACHMENT1 on fbo.");
+ shouldBe('gl.getParameter(gl.READ_BUFFER)', 'gl.COLOR_ATTACHMENT1');
+ // Need to reset draw buffers, otherwise it triggers a mac driver bug.
+ // We add a separate test for that bug: conformance2/rendering/framebuffer-completeness-unaffected.html
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, null)
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ validateReadingFromFramebuffer(null, gl.INVALID_OPERATION,
+ "should generate INVALID_OPERATION when reading from GL_COLOR_ATTACHMENT1 but this attachment has no image currently.");
+
+ // switch to another fbo, read buffer is GL_COLOR_ATTACHMENT0, not GL_COLOR_ATTACHMENT1
+ var fb1 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb1);
+ var buffer = setupRenderbuffer(gl.COLOR_ATTACHMENT0);
+ shouldBe('gl.getParameter(gl.READ_BUFFER)', 'gl.COLOR_ATTACHMENT0');
+ var blue = [0, 0, 255, 255];
+ clearDrawingbuffer(blue);
+ validateReadingFromFramebuffer(blue, gl.NO_ERROR,
+ "should be no errors when reading from GL_COLOR_ATTACHMENT0 on another fbo.");
+
+ // switch from fbo to default fb, read buffer will switch to GL_BACK from GL_COLOR_ATTACHMENT0
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ shouldBe('gl.getParameter(gl.READ_BUFFER)', 'gl.BACK');
+ validateReadingFromFramebuffer(backColor, gl.NO_ERROR,
+ "should be no errors when reading from GL_BACK on the default framebuffer.");
+
+ gl.deleteFramebuffer(fb);
+ gl.deleteRenderbuffer(colorbuffer);
+ gl.deleteRenderbuffer(colorbuffer1);
+ gl.deleteFramebuffer(fb1);
+ gl.deleteRenderbuffer(buffer);
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/00_test_list.txt
new file mode 100644
index 0000000000..92ce232ee2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/00_test_list.txt
@@ -0,0 +1,51 @@
+attrib-type-match.html
+blitframebuffer-filter-outofbounds.html
+blitframebuffer-filter-srgb.html
+blitframebuffer-multisampled-readbuffer.html
+--min-version 2.0.1 blitframebuffer-outside-readbuffer.html
+--min-version 2.0.1 blitframebuffer-r11f-g11f-b10f.html
+--min-version 2.0.1 blitframebuffer-resolve-to-back-buffer.html
+blitframebuffer-scissor-enabled.html
+blitframebuffer-size-overflow.html
+--min-version 2.0.1 blitframebuffer-srgb-and-linear-drawbuffers.html
+--min-version 2.0.1 blitframebuffer-stencil-only.html
+blitframebuffer-test.html
+--min-version 2.0.1 blitframebuffer-unaffected-by-colormask.html
+--min-version 2.0.1 builtin-vert-attribs.html
+canvas-resizing-with-pbo-bound.html
+--min-version 2.0.1 clearbuffer-sub-source.html
+--min-version 2.0.1 clearbufferfv-with-alpha-false.html
+clear-func-buffer-type-match.html
+--min-version 2.0.1 clear-srgb-color-buffer.html
+--min-version 2.0.1 clipping-wide-points.html
+--min-version 2.0.1 depth-stencil-feedback-loop.html
+draw-buffers.html
+--min-version 2.0.1 draw-buffers-dirty-state-bug.html
+--min-version 2.0.1 draw-buffers-driver-hang.html
+--min-version 2.0.1 draw-buffers-sparse-output-locations.html
+--min-version 2.0.1 draw-with-integer-texture-base-level.html
+element-index-uint.html
+--min-version 2.0.1 framebuffer-completeness-draw-framebuffer.html
+framebuffer-completeness-unaffected.html
+--min-version 2.0.1 framebuffer-mismatched-attachment-targets.html
+--min-version 2.0.1 framebuffer-render-to-layer.html
+--min-version 2.0.1 framebuffer-render-to-layer-angle-issue.html
+--min-version 2.0.1 framebuffer-texture-changing-base-level.html
+--min-version 2.0.1 framebuffer-texture-level1.html
+--min-version 2.0.1 framebuffer-to-texture.html
+framebuffer-unsupported.html
+--min-version 2.0.1 fs-color-type-mismatch-color-buffer-type.html
+instanced-arrays.html
+--min-version 2.0.1 instanced-rendering-bug.html
+--min-version 2.0.1 instanced-rendering-large-divisor.html
+--min-version 2.0.1 line-rendering-quality.html
+--min-version 2.0.1 multisampling-depth-resolve.html
+--min-version 2.0.1 multisampling-fragment-evaluation.html
+out-of-bounds-index-buffers-after-copying.html
+--min-version 2.0.1 rasterizer-discard-and-implicit-clear.html
+--min-version 2.0.1 read-draw-when-missing-image.html
+rgb-format-support.html
+uniform-block-buffer-size.html
+--min-version 2.0.1 texture-switch-performance.html
+--min-version 2.0.1 vertex-id.html
+--min-version 2.0.1 vertex-id-large-count.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/attrib-type-match.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/attrib-type-match.html
new file mode 100644
index 0000000000..5b1b2884aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/attrib-type-match.html
@@ -0,0 +1,561 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Tests: Vertex Attribute Type Match</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing instanced draws -->
+<script id="outputVertexShader" type="x-shader/x-vertex">#version 300 es
+in vec4 aPosition;
+in ivec2 aOffsetI;
+in uvec2 aOffsetU;
+in vec4 aColor;
+out vec4 vColor;
+void main() {
+ vColor = aColor;
+ vec2 offset = vec2(float(aOffsetI.x) + float(aOffsetU.x),
+ float(aOffsetI.y) + float(aOffsetU.y));
+ gl_Position = aPosition + vec4(offset, 0.0, 0.0);
+}
+</script>
+
+<script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+in vec4 vColor;
+out vec4 fragColor;
+void main() {
+ fragColor = vColor;
+}
+</script>
+
+<script id='vshader_inactive_attrib' type='x-shader/x-vertex'>#version 300 es
+in ivec4 p;
+in ivec4 a;
+void main()
+{
+ gl_Position = vec4(p);
+}
+</script>
+<script id='vshader_active_attrib_int' type='x-shader/x-vertex'>#version 300 es
+in ivec4 p;
+in ivec4 a;
+in uvec4 b;
+void main()
+{
+ gl_Position = vec4(p) + vec4(a) + vec4(b);
+}
+</script>
+<script id='vshader_active_attrib_float' type='x-shader/x-vertex'>#version 300 es
+in vec4 p;
+in vec4 a;
+in vec4 c;
+void main()
+{
+ gl_Position = vec4(p) + vec4(a) + vec4(c);
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+void main()
+{
+ oColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+</script>
+
+
+<script>
+"use strict";
+description("This test verifies an active vertex attribute's base type has to match the verexAttrib function type.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ testGenericAttribs();
+ runTests();
+}
+
+function testGenericAttribs() {
+ debug("");
+ debug("Test Generic Vertex Attributes for some corner cases");
+
+ var pIndex = 2;
+ var aIndex = 3;
+ var bIndex = 4;
+ var cIndex = 5;
+ var program0 = wtu.setupProgram(gl, ["vshader_inactive_attrib", "fshader"],
+ ['p', 'a'], [pIndex, aIndex]);
+ var program1 = wtu.setupProgram(gl, ["vshader_active_attrib_int", "fshader"],
+ ['p', 'a', 'b'], [pIndex, aIndex, bIndex]);
+ var program2 = wtu.setupProgram(gl, ["vshader_active_attrib_float", "fshader"],
+ ['p', 'a', 'c'], [pIndex, aIndex, cIndex]);
+ if (!program0 || !program1 || !program2) {
+ testFailed("Set up program failed");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
+
+ wtu.setupUnitQuad(gl, 0);
+
+ debug("Inactive input in vertex shader");
+ gl.useProgram(program0);
+ gl.vertexAttribI4i(pIndex, 1, 0, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays succeeds: type in shader mismatch default vertex type is valid for inactive attrib");
+
+ gl.vertexAttrib4f(aIndex, 0.0, 1.0, 0.0, 0.0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays succeeds: type in shader mismatch vertexAttrib type is valid for inactive attrib");
+
+ debug("active int/uint inputs in vertex shader");
+ gl.useProgram(program1);
+ gl.vertexAttribI4i(pIndex, 1, 0, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Type mismatch: type in shader mismatch the default type for a vertex attrib");
+ gl.vertexAttribI4i(aIndex, 0, 1, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Type mismatch: type in shader mismatch the default type for a vertex attrib");
+ gl.vertexAttribI4ui(bIndex, 0, 0, 1, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays succeeds");
+
+ debug("active float input in vertex shader");
+ gl.useProgram(program2);
+ gl.vertexAttrib4f(pIndex, 1.0, 0.0, 0.0, 0.0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Type mismatch: generic attrib is valid per context. 'a' is set to int type by previous test case");
+ gl.vertexAttrib4f(aIndex, 0.0, 1.0, 0.0, 0.0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays succeeds: default type of generic attrib is float");
+}
+
+function setupAttribValues(offsetILoc, offsetULoc, colorLoc) {
+ gl.vertexAttribI4i(offsetILoc, -1, -2, 0, 0);
+ gl.vertexAttribI4ui(offsetULoc, 1, 2, 0, 0);
+ gl.vertexAttrib4f(colorLoc, 1.0, 0, 0, 1.0);
+}
+
+function setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetIBuffer);
+ gl.vertexAttribIPointer(offsetILoc, 2, gl.INT, 0, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetUBuffer);
+ gl.vertexAttribIPointer(offsetULoc, 2, gl.UNSIGNED_INT, 0, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
+}
+
+function runTests() {
+ debug("");
+ debug("Test vertexAttrib with drawArrays and drawArraysInstanced");
+
+ var instanceCount = 4;
+
+ var positionLoc = 0;
+ var offsetILoc = 2;
+ var offsetULoc = 3;
+ var colorLoc = 4;
+ var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"],
+ ['aPosition', 'aOffsetI', 'aOffsetU','aColor'],
+ [positionLoc, offsetILoc, offsetULoc, colorLoc]);
+ if (!program) {
+ testFailed("Set up program failed");
+ return;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
+
+ wtu.setupUnitQuad(gl, 0);
+
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
+
+ debug("int type function on uint type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4i(offsetULoc, 1, 2, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("float type function on uint type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttrib4f(offsetULoc, 1.0, 2.0, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("uint type function on int type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4ui(offsetILoc, 1, 2, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("float type function on int type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttrib4f(offsetILoc, 1.0, 2.0, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("int type function on float type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4i(colorLoc, 1, 0, 0, 1);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("uint type function on float type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4ui(colorLoc, 1, 0, 0, 1);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("");
+ debug("Test vertexAttrib with drawElements, drawRangeElements, and drawElementsInstanced");
+ wtu.setupIndexedQuad(gl, 1, 0);
+
+ debug("Correct setup");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawRangeElements succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
+
+ debug("int type function on uint type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4i(offsetULoc, 1, 2, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("float type function on uint type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttrib4f(offsetULoc, 1.0, 2.0, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("uint type function on int type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4ui(offsetILoc, 1, 2, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("float type function on int type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttrib4f(offsetILoc, 1.0, 2.0, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("int type function on float type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4i(colorLoc, 1, 0, 0, 1);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("uint type function on float type attrib");
+ setupAttribValues(offsetILoc, offsetULoc, colorLoc);
+ gl.vertexAttribI4ui(colorLoc, 1, 0, 0, 1);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+
+ var offsetIBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetIBuffer);
+ var offsetI = new Int32Array([-1, -2,
+ -1, -2,
+ -1, -2,
+ -1, -2,
+ -1, -2,
+ -1, -2]);
+ gl.bufferData(gl.ARRAY_BUFFER, offsetI, gl.STATIC_DRAW);
+
+ var offsetUBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetUBuffer);
+ var offsetU = new Uint32Array([1, 2,
+ 1, 2,
+ 1, 2,
+ 1, 2,
+ 1, 2,
+ 1, 2]);
+ gl.bufferData(gl.ARRAY_BUFFER, offsetU, gl.STATIC_DRAW);
+
+ var offsetFBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetFBuffer);
+ var offsetF = new Float32Array([1.0, 2.0,
+ 1.0, 2.0,
+ 1.0, 2.0,
+ 1.0, 2.0,
+ 1.0, 2.0,
+ 1.0, 2.0]);
+ gl.bufferData(gl.ARRAY_BUFFER, offsetF, gl.STATIC_DRAW);
+
+ var colorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ var colors = new Float32Array([0.0, 1.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0]);
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+
+ var colorUBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorUBuffer);
+ var colorsU = new Uint32Array([0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1]);
+ gl.bufferData(gl.ARRAY_BUFFER, colorsU, gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(offsetILoc);
+ gl.enableVertexAttribArray(offsetULoc);
+ gl.enableVertexAttribArray(colorLoc);
+
+ debug("");
+ debug("Test vertexAttrib{I}Pointer with drawArrays and drawArraysInstanced");
+ wtu.setupUnitQuad(gl, 0);
+
+ debug("Correct setup");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [0, 255, 0, 255]);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [0, 255, 0, 255]);
+
+ debug("vertexAttribIPointer with int type on uint type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetIBuffer);
+ gl.vertexAttribIPointer(offsetULoc, 2, gl.INT, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribPointer on uint type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetFBuffer);
+ gl.vertexAttribPointer(offsetULoc, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("VertexAttribIPointer with uint type on int type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetUBuffer);
+ gl.vertexAttribIPointer(offsetILoc, 2, gl.UNSIGNED_INT, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribPointer on int type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetFBuffer);
+ gl.vertexAttribPointer(offsetILoc, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribIPointer with uint type on float type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorUBuffer);
+ gl.vertexAttribIPointer(colorLoc, 4, gl.UNSIGNED_INT, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribIPointer with int type on float type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorUBuffer);
+ gl.vertexAttribIPointer(colorLoc, 4, gl.INT, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("");
+ debug("Test vertexAttrib{I}Pointer with drawElements, drawRangeElements, and drawElementsInstanced");
+ wtu.setupIndexedQuad(gl, 1, 0);
+
+ debug("Correct setup");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up succeeds");
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [0, 255, 0, 255]);
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawRangeElements succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [0, 255, 0, 255]);
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced succeeds");
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [0, 255, 0, 255]);
+
+ debug("vertexAttribIPointer with int type on uint type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetIBuffer);
+ gl.vertexAttribIPointer(offsetULoc, 2, gl.INT, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribPointer on uint type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetFBuffer);
+ gl.vertexAttribPointer(offsetULoc, 2, gl.FLOAT, false, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("VertexAttribIPointer with uint type on int type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetUBuffer);
+ gl.vertexAttribIPointer(offsetILoc, 2, gl.UNSIGNED_INT, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribPointer on int type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetFBuffer);
+ gl.vertexAttribPointer(offsetILoc, 2, gl.FLOAT, false, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribIPointer with uint type on float type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorUBuffer);
+ gl.vertexAttribIPointer(colorLoc, 4, gl.UNSIGNED_INT, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+
+ debug("vertexAttribIPointer with int type on float type attrib");
+ setupAttribPointers(offsetILoc, offsetULoc, colorLoc,
+ offsetIBuffer, offsetUBuffer, colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorUBuffer);
+ gl.vertexAttribIPointer(colorLoc, 4, gl.INT, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type mismatch");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-outofbounds.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-outofbounds.html
new file mode 100644
index 0000000000..f1fda162d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-outofbounds.html
@@ -0,0 +1,172 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer when src/dst region are out-of-bounds.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function checkPixel(color, expectedColor) {
+ var tolerance = 3;
+ return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
+ Math.abs(color[1] - expectedColor[1]) <= tolerance &&
+ Math.abs(color[2] - expectedColor[2]) <= tolerance &&
+ Math.abs(color[3] - expectedColor[3]) <= tolerance);
+}
+
+function blitframebuffer_filter_outofbounds(readbufferFormat, drawbufferFormat, filter) {
+ debug("");
+ debug("blitting pixels out-of-bounds, read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat) + ", draw buffer format is: " + wtu.glEnumToString(gl, drawbufferFormat) + ", filter is: " + wtu.glEnumToString(gl, filter));
+
+ // Initiate data to read framebuffer
+ var size = 8;
+ var uint_read = new Uint8Array(size * size * 4);
+ var color = 0x20;
+ for (var ii = 0; ii < size * size * 4; ii += 4) {
+ for (var jj = 0; jj < 3; ++jj) {
+ uint_read[ii + jj] = color;
+ }
+ uint_read[ii + 3] = 0xff;
+ }
+
+ // Create read framebuffer and feed data to read buffer
+ // Read buffer may have srgb image
+ var tex_read = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_read);
+ gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint_read);
+
+ var fbo_read = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
+
+ // Create draw framebuffer. Color in draw buffer is initialized to 0.
+ // Draw buffer may have srgb image
+ var tex_draw = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_draw);
+ gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var fbo_draw = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_draw, 0);
+
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ // Blit read framebuffer to the image in draw framebuffer.
+ var tests = [
+ // [srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1]
+
+ { args: [-2, -2, 4, 4, 1, 1, 4, 4], changedDstRect: [2, 2, 4, 4], desc: 'only src region is out-of-bounds, dst region has different width/height as src region.'},
+ { args: [-2, -2, 4, 4, 1, 1, 7, 7], changedDstRect: [3, 3, 7, 7], desc: 'only src region is out-of-bounds, dst region has the same width/height as src region.'},
+ { args: [0, 0, 6, 6, 7, 7, 10, 10], changedDstRect: [7, 7, 8, 8], desc: 'only dst region is out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.'},
+ { args: [0, 0, 6, 6, 4, 4, 10, 10], changedDstRect: [4, 4, 8, 8], desc: 'only dst region is out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.'},
+ { args: [-2, -2, 4, 4, 7, 7, 10, 10], changedDstRect: [8, 8, 8, 8], desc: 'both src and dst region are out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.'},
+ { args: [-2, -2, 4, 4, 4, 4, 10, 10], changedDstRect: [6, 6, 8, 8], desc: 'both src and dst region are out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.'},
+ { args: [-2, -2, 4, 4, 2, 2, 10, 10], changedDstRect: [2 + 2/6*8, 2 + 2/6*8, 8, 8], desc: 'both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 8] , and x or y equals to 4) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.'},
+ { args: [-2, -2, 4, 4, 3, 3, 10, 10], changedDstRect: [5, 5, 8, 8], desc: 'both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 7] , and x or y equals to 5) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.'},
+ { args: [-2, -2, 4, 4, 10, 10, 2, 2], changedDstRect: [2, 2, 7, 7], desc: 'both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [2, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.'},
+ { args: [-2, -2, 4, 4, 10, 10, 3, 3], changedDstRect: [3, 3, 8, 8], desc: 'both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [3, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the read sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.'},
+ ];
+
+ var readbufferHasSRGBImage = (readbufferFormat == gl.SRGB8_ALPHA8);
+ var drawbufferHasSRGBImage = (drawbufferFormat == gl.SRGB8_ALPHA8);
+
+ for (const test of tests) {
+ const args = test.args;
+ const changedDstRect = test.changedDstRect;
+ debug("");
+ debug("Both the read framebuffer and draw framebuffer bounds are [0, 0, 8, 8]");
+ debug(`Blitting from src region [${args.slice(0, 4)}] to dst region [${args.slice(4, 8)}]`);
+ debug(`Expects changed dst region of [${changedDstRect}]`);
+ debug(`Explaination: ${test.desc}`);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindTexture(gl.TEXTURE_2D, tex_draw);
+ gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.blitFramebuffer(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], gl.COLOR_BUFFER_BIT, filter);
+
+ // Read pixels and check the correctness.
+ var pixels = new Uint8Array(size * size * 4);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
+ gl.readPixels(0, 0, size, size, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+
+
+ for (var ii = 0; ii < size; ++ii) {
+ for (var jj = 0; jj < size; ++jj) {
+ var loc = ii * size + jj;
+ var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];
+
+ var expectedColor = [0, 0, 0, 0];
+ if (ii >= changedDstRect[0] && ii < changedDstRect[2] && jj >= changedDstRect[1] && jj < changedDstRect[3]) {
+ expectedColor = [0x20, 0x20, 0x20, 0xff];
+
+ // We may need to covert the color space for pixels in blit region
+ if (readbufferHasSRGBImage ^ drawbufferHasSRGBImage) {
+ if (drawbufferHasSRGBImage) {
+ expectedColor = wtu.linearToSRGB(expectedColor);
+ } else {
+ expectedColor = wtu.sRGBToLinear(expectedColor);
+ }
+ }
+ }
+
+ if (checkPixel(color, expectedColor) == true) {
+ testPassed("pixel at [" + jj + ", " + ii + "] is (" + color + "). It is correct!");
+ } else {
+ testFailed("pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + color + ")");
+ }
+ }
+ }
+ }
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo_read);
+ gl.deleteFramebuffer(fbo_draw);
+ gl.deleteTexture(tex_read);
+ gl.deleteTexture(tex_draw);
+};
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ var filters = [gl.LINEAR, gl.NEAREST];
+ for (var ii = 0; ii < filters.length; ++ii) {
+ blitframebuffer_filter_outofbounds(gl.RGBA8, gl.RGBA8, filters[ii]);
+ break;
+ blitframebuffer_filter_outofbounds(gl.RGBA8, gl.SRGB8_ALPHA8, filters[ii]);
+ blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.RGBA8, filters[ii]);
+ blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii]);
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-srgb.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-srgb.html
new file mode 100644
index 0000000000..4054a0af25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-srgb.html
@@ -0,0 +1,161 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer with sRGB framebuffers.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function checkPixel(color, expectedColor) {
+ var tolerance = 7;
+ return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
+ Math.abs(color[1] - expectedColor[1]) <= tolerance &&
+ Math.abs(color[2] - expectedColor[2]) <= tolerance &&
+ Math.abs(color[3] - expectedColor[3]) <= tolerance);
+}
+
+var tex_read = gl.createTexture();
+var tex_draw = gl.createTexture();
+var fbo_read = gl.createFramebuffer();
+var fbo_draw = gl.createFramebuffer();
+var size_read = 4;
+var size_draw = 0;
+
+function blitframebuffer_helper(readbufferFormat, drawbufferFormat, filter, data) {
+ // Create read framebuffer and feed data to read buffer
+ gl.bindTexture(gl.TEXTURE_2D, tex_read);
+ gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size_read, size_read, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
+
+ // Create draw framebuffer and feed 0 to draw buffer
+ gl.bindTexture(gl.TEXTURE_2D, tex_draw);
+ gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size_draw, size_draw, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_draw, 0);
+
+ gl.blitFramebuffer(0, 0, size_read, size_read, 0, 0, size_draw, size_draw, gl.COLOR_BUFFER_BIT, filter);
+
+ // Read pixels for comparision
+ var pixels = new Uint8Array(size_draw * size_draw * 4);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
+ gl.readPixels(0, 0, size_draw, size_draw, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ return pixels;
+}
+
+function blitframebuffer_filter_srgb(readbufferFormat, drawbufferFormat, filter, minified) {
+ debug("");
+ debug("Test srgb filtering for blitFramebuffer, the current filter is: " + wtu.glEnumToString(gl, filter));
+ var min_mag = minified ? "minified to half the size." : "magnified to double the size.";
+ debug("read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat) + ", draw buffer format is: " + wtu.glEnumToString(gl, drawbufferFormat) + ", minify/magnify: " + min_mag);
+
+ // Initiate data to read framebuffer
+ var src_buffer = new Uint8Array(size_read * size_read * 4);
+ var start = 0;
+ for (var ii = 0; ii < size_read * size_read * 4; ii += 4) {
+ for (var jj = 0; jj < 3; ++jj) {
+ src_buffer[ii + jj] = start;
+ }
+ src_buffer[ii + 3] = 0xff;
+ start += 0x10;
+ }
+
+ // We may need to decode srgb to linear for reference data
+ var ref_buffer = new Uint8Array(size_read * size_read * 4);
+ for (var ii = 0; ii < size_read * size_read * 4; ii += 4) {
+ var color = [src_buffer[ii], src_buffer[ii + 1], src_buffer[ii + 2], src_buffer[ii + 3]];
+ var ref_color;
+ if (readbufferFormat == gl.SRGB8_ALPHA8) {
+ ref_color = wtu.sRGBToLinear(color);
+ } else {
+ ref_color = color;
+ }
+ for (var jj = 0; jj < 4; ++jj) {
+ ref_buffer[ii + jj] = ref_color[jj];
+ }
+ }
+
+ // Blit framebuffer to filter srgb image, but the reference data is always retrieved by blitFramebuffer against linear image
+ size_draw = minified ? size_read / 2 : size_read * 2;
+ var pixels = blitframebuffer_helper(readbufferFormat, drawbufferFormat, filter, src_buffer);
+ var temp = blitframebuffer_helper(gl.RGBA, gl.RGBA, filter, ref_buffer);
+
+ // We may need to encode linear to srgb for reference data
+ var ref_pixels = new Uint8Array(size_draw * size_draw * 4);
+ for (var ii = 0; ii < size_draw * size_draw * 4; ii += 4) {
+ var color = [temp[ii], temp[ii + 1], temp[ii + 2], temp[ii + 3]];
+ var ref_color;
+ if (drawbufferFormat == gl.SRGB8_ALPHA8) {
+ ref_color = wtu.linearToSRGB(color);
+ } else {
+ ref_color = color;
+ }
+ for (var jj = 0; jj < 4; ++jj) {
+ ref_pixels[ii + jj] = ref_color[jj];
+ }
+ }
+
+ // Compare
+ for (var ii = 0; ii < size_draw; ++ii) {
+ for (var jj = 0; jj < size_draw; ++jj) {
+ var index = ii * size_draw * 4 + jj;
+ var color = [pixels[index], pixels[index + 1], pixels[index + 2], pixels[index + 3]];
+ var expectedColor = [ref_pixels[index], ref_pixels[index + 1], ref_pixels[index + 2], ref_pixels[index + 3]];
+ if (checkPixel(color, expectedColor) == true) {
+ testPassed("pixel at [" + jj + ", " + ii + "] is (" + color + "). It is correct!");
+ } else {
+ testFailed("pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + color + ")");
+ }
+ }
+ }
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ var filters = [gl.LINEAR, gl.NEAREST];
+ for (var ii = 0; ii < filters.length; ++ii) {
+ blitframebuffer_filter_srgb(gl.RGBA8, gl.SRGB8_ALPHA8, filters[ii], true);
+ blitframebuffer_filter_srgb(gl.RGBA8, gl.SRGB8_ALPHA8, filters[ii], false);
+ blitframebuffer_filter_srgb(gl.SRGB8_ALPHA8, gl.RGBA8, filters[ii], true);
+ blitframebuffer_filter_srgb(gl.SRGB8_ALPHA8, gl.RGBA8, filters[ii], false);
+ blitframebuffer_filter_srgb(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii], true);
+ blitframebuffer_filter_srgb(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii], false);
+ }
+}
+
+gl.bindTexture(gl.TEXTURE_2D, null);
+gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+gl.deleteFramebuffer(fbo_read);
+gl.deleteFramebuffer(fbo_draw);
+gl.deleteTexture(tex_read);
+gl.deleteTexture(tex_draw);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html
new file mode 100644
index 0000000000..73f8e8b735
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html
@@ -0,0 +1,112 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer with multisampled sRGB color buffer.");
+
+var gl = wtu.create3DContext("canvas", undefined, 2);
+
+var tex_blit = gl.createTexture();
+var fb0 = gl.createFramebuffer();
+var rb0 = gl.createRenderbuffer();
+var fbo_blit = gl.createFramebuffer();
+var size = 32;
+var program;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ init();
+
+ var filters = [gl.LINEAR, gl.NEAREST];
+ for (var ii = 0; ii < filters.length; ++ii) {
+ blitframebuffer_multisampled_readbuffer(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii]);
+ }
+}
+
+function init() {
+ program = wtu.setupColorQuad(gl);
+ gl.viewport(0, 0, size, size);
+}
+
+function blitframebuffer_helper(readbufferFormat, drawbufferFormat, filter) {
+ // Create draw framebuffer and feed 0 to draw buffer
+ gl.bindTexture(gl.TEXTURE_2D, tex_blit);
+ gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_blit);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_blit, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup draw framebuffer should succeed");
+
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, filter);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitframebuffer should succeed");
+}
+
+function blitframebuffer_multisampled_readbuffer(readbufferFormat, drawbufferFormat, filter) {
+ debug("");
+ debug("Test blitFramebuffer when the read buffer is a multisampled srgb image. The filter is: " + wtu.glEnumToString(gl, filter));
+ debug("read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat) + ", draw buffer format is: " + wtu.glEnumToString(gl, drawbufferFormat));
+
+ // Draw to a multi-sampled srgb image, and blit to a srgb image.
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, readbufferFormat, size, size);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb0);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ var color = [252, 122, 15, 255];
+ var expectedColor = wtu.linearToSRGB(color);
+ for (var i = 0; i < 4; ++i) {
+ color[i] = color[i] / 255;
+ }
+ // Draw a rectangle. Fill it with solid color.
+ // Note that the draw buffer is a multisampled srgb image. So during drawing, the color will be converted into srgb color space.
+ gl.useProgram(program);
+ wtu.drawFloatColorQuad(gl, color);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ blitframebuffer_helper(readbufferFormat, drawbufferFormat, filter);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Blit from a multi-sampled srgb image to a srgb image should succeed");
+
+ // Compare
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_blit);
+ wtu.checkCanvasRect(gl, 0, 0, size, size, expectedColor);
+}
+
+gl.bindTexture(gl.TEXTURE_2D, null);
+gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+gl.deleteRenderbuffer(rb0);
+gl.deleteTexture(tex_blit);
+gl.deleteFramebuffer(fb0);
+gl.deleteFramebuffer(fbo_blit);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-outside-readbuffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-outside-readbuffer.html
new file mode 100644
index 0000000000..a2e87034eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-outside-readbuffer.html
@@ -0,0 +1,267 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function checkPixel(color, expectedColor) {
+ var tolerance = 3;
+ return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
+ Math.abs(color[1] - expectedColor[1]) <= tolerance &&
+ Math.abs(color[2] - expectedColor[2]) <= tolerance &&
+ Math.abs(color[3] - expectedColor[3]) <= tolerance);
+}
+
+function blitframebuffer_outside_readbuffer(readbufferFormat, drawbufferFormat) {
+ debug("");
+ debug("blitting outside of read framebuffer, read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat) + ", draw buffer format is: " + wtu.glEnumToString(gl, drawbufferFormat));
+
+ // Initiate data to read framebuffer
+ var size_read = 3;
+ var uint_read = new Uint8Array(size_read * size_read * 4);
+ var start = 0x20;
+ for (var ii = 0; ii < size_read * size_read * 4; ii += 4) {
+ for (var jj = 0; jj < 3; ++jj) {
+ uint_read[ii + jj] = start;
+ }
+ uint_read[ii + 3] = 0xff;
+ start += 0x10;
+ }
+
+ // Create read framebuffer and feed data to read buffer
+ // Read buffer may has srgb image
+ var tex_read = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_read);
+ gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size_read, size_read, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint_read);
+
+ var fbo_read = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
+
+ // Initiate data to draw framebuffer
+ var size_draw = 7;
+ var uint_draw = new Uint8Array(size_draw * size_draw * 4);
+ for (var ii = 0; ii < size_draw * size_draw * 4; ii += 4) {
+ for (var jj = 0; jj < 3; ++jj) {
+ uint_draw[ii + jj] = 0x10;
+ }
+ uint_draw[ii + 3] = 0xff;
+ }
+
+ // Create draw framebuffer and feed data to draw buffer
+ // Draw buffer may has srgb image
+ var tex_draw = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_draw);
+ 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, drawbufferFormat, size_draw, size_draw, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint_draw);
+
+ var fbo_draw = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_draw, 0);
+
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ var ref = [
+ // The reference pixels of the 1st line: (0, 0) ~ (6, 0)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+
+ // The reference pixels of the 2nd line: (0, 1) ~ (6, 1)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+
+ // The reference pixels of the 3rd line: (0, 2) ~ (6, 2)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x20, 0x20, 0x20, 0xff], [0x30, 0x30, 0x30, 0xff],
+ [0x40, 0x40, 0x40, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+
+ // The reference pixels of the 4th line: (0, 3) ~ (6, 3)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x50, 0x50, 0x50, 0xff], [0x60, 0x60, 0x60, 0xff],
+ [0x70, 0x70, 0x70, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+
+ // The reference pixels of the 5th line: (0, 4) ~ (6, 4)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x80, 0x80, 0x80, 0xff], [0x90, 0x90, 0x90, 0xff],
+ [0xa0, 0xa0, 0xa0, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+
+ // The reference pixels of the 6th line: (0, 5) ~ (6, 5)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+
+ // The reference pixels of the 7th line: (0, 6) ~ (6, 6)
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+ [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
+ ];
+
+ // The 1st round test: blit read framebuffer to the image in draw framebuffer
+ // All directions of the read region have pixels outside of the read buffer
+ // The src region and/or dst region may be reversed during blitting.
+ var test1 = [
+ [-1, 4, 1, 6], // reverse neither src nor dst
+ [4, -1, 1, 6], // reverse src only
+ [-1, 4, 6, 1], // reverse dst only
+ [4, -1, 6, 1] // reverse both src and dst
+ ];
+
+ var readbufferHasSRGBImage = (readbufferFormat == gl.SRGB8_ALPHA8);
+ var drawbufferHasSRGBImage = (drawbufferFormat == gl.SRGB8_ALPHA8);
+
+ for (var i = 0; i < 4; ++i) {
+ debug("");
+ switch (i) {
+ case 0: debug("reverse neither src region nor dst region"); break;
+ case 1: debug("reverse src region only"); break;
+ case 2: debug("reverse dst region only"); break;
+ case 3: debug("reverse both src region and dst region"); break;
+ }
+ var srcStart = test1[i][0];
+ var srcEnd = test1[i][1];
+ var dstStart = test1[i][2];
+ var dstEnd = test1[i][3];
+ var realBlittedDstStart = 2;
+ var realBlittedDstEnd = 5;
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.blitFramebuffer(srcStart, srcStart, srcEnd, srcEnd, dstStart, dstStart, dstEnd, dstEnd, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+
+ // Read pixels and check the correctness.
+ var pixels = new Uint8Array(size_draw * size_draw * 4);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
+ gl.readPixels(0, 0, size_draw, size_draw, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+
+ for (var ii = 0; ii < size_draw; ++ii) {
+ for (var jj = 0; jj < size_draw; ++jj) {
+ var loc = ii * size_draw + jj;
+ var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];
+
+ // We may need to reverse the reference loc if necessary
+ var ref_loc = loc;
+ var reverse_src = (srcStart < srcEnd);
+ var reverse_dst = (dstStart < dstEnd);
+ var reversed = reverse_src ^ reverse_dst;
+ if (reversed) {
+ ref_loc = (size_draw - ii - 1) * size_draw + (size_draw - jj -1);
+ }
+ var expectedColor = ref[ref_loc];
+
+ // We may need to covert the color space for pixels in blit region
+ if ((readbufferHasSRGBImage ^ drawbufferHasSRGBImage) &&
+ (ii >= realBlittedDstStart && ii < realBlittedDstEnd && jj >= realBlittedDstStart && jj < realBlittedDstEnd)) {
+ if (drawbufferHasSRGBImage) {
+ expectedColor = wtu.linearToSRGB(expectedColor);
+ } else {
+ expectedColor = wtu.sRGBToLinear(expectedColor);
+ }
+ }
+ if (checkPixel(color, expectedColor) == true) {
+ testPassed("pixel at [" + jj + ", " + ii + "] is (" + color + "). It is correct!");
+ } else {
+ testFailed("pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + color + ")");
+ }
+ }
+ }
+ }
+
+ // The 2nd round test: blit read framebuffer to the image in draw framebuffer
+ // Only one direction of the read region have pixels outside of the read buffer
+ var tests = [
+ [-1, 0], // pixels are outside the left edge of the read buffer
+ [0, -1], // pixels are outside the bottom edge of the read buffer
+ [1, 0], // pixels are outside the right edge of the read buffer
+ [0, 1] // pixels are outside the top edge of the read buffer
+ ];
+ for (var i = 0; i < 4; ++i) {
+ debug("");
+ switch (i) {
+ case 0: debug("verify that pixels lying outside the left edge of the read buffer should remain untouched"); break;
+ case 1: debug("verify that pixels lying outside the bottom edge of the read buffer should remain untouched"); break;
+ case 2: debug("verify that pixels lying outside the right edge of the read buffer should remain untouched"); break;
+ case 3: debug("verify that pixels lying outside the top edge of the read buffer should remain untouched"); break;
+ }
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ var srcX = tests[i][0];
+ var srcY = tests[i][1];
+ var offset = dstStart - srcStart;
+ gl.blitFramebuffer(srcX, srcY, srcX + size_read, srcY + size_read,
+ srcX + offset, srcY + offset, srcX + offset + size_read, srcY + offset + size_read,
+ gl.COLOR_BUFFER_BIT, gl.LINEAR);
+
+ // Read pixels and check the correctness.
+ var pixels = new Uint8Array(size_draw * size_draw * 4);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
+ gl.readPixels(0, 0, size_draw, size_draw, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ for (var ii = srcY + offset; ii < srcY + offset + size_read; ++ii) {
+ for (var jj = srcX + offset; jj < srcX + offset + size_read; ++jj) {
+ var loc = ii * size_draw + jj;
+ var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];
+ var expectedColor = ref[loc];
+ // We may need to covert the color space for pixels in blit region
+ if ((readbufferHasSRGBImage ^ drawbufferHasSRGBImage) &&
+ (ii >= realBlittedDstStart && ii < realBlittedDstEnd && jj >= realBlittedDstStart && jj < realBlittedDstEnd)) {
+ if (drawbufferHasSRGBImage) {
+ expectedColor = wtu.linearToSRGB(expectedColor);
+ } else {
+ expectedColor = wtu.sRGBToLinear(expectedColor);
+ }
+ }
+ if (checkPixel(color, expectedColor) == true) {
+ testPassed("pixel at [" + jj + ", " + ii + "] is (" + color + "). It is correct!");
+ } else {
+ testFailed("pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + color + ")");
+ }
+ }
+ }
+ }
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo_read);
+ gl.deleteFramebuffer(fbo_draw);
+ gl.deleteTexture(tex_read);
+ gl.deleteTexture(tex_draw);
+};
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ blitframebuffer_outside_readbuffer(gl.RGBA8, gl.RGBA8);
+ blitframebuffer_outside_readbuffer(gl.RGBA8, gl.SRGB8_ALPHA8);
+ blitframebuffer_outside_readbuffer(gl.SRGB8_ALPHA8, gl.RGBA8);
+ blitframebuffer_outside_readbuffer(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html
new file mode 100644
index 0000000000..636e76ac29
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html
@@ -0,0 +1,113 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL R11F_G11F_B10F BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This tests multisample blitting with the R11F_G11F_B10F format.");
+
+var width = 8;
+var height = 8;
+
+function runWithContextCreationArguments(args) {
+ debug('');
+ debug('Running test with arguments: ' + JSON.stringify(args));
+
+ var canvas = document.createElement('canvas');
+ canvas.width = width;
+ canvas.height = height;
+
+ var gl = wtu.create3DContext(canvas, args, 2);
+ if (!gl) {
+ testFailed("WebGL 2.0 context does not exist");
+ return;
+ }
+
+ var ext = gl.getExtension("EXT_color_buffer_float");
+ if (!ext) {
+ testPassed("EXT_color_buffer_float extension not supported");
+ return;
+ }
+
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.R11F_G11F_B10F, gl.SAMPLES);
+
+ // Set up source framebuffer.
+ var rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.R11F_G11F_B10F, width, height);
+ var readfb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, readfb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after multisampled R11F_G11F_B10F FBO setup");
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Source framebuffer incomplete.");
+ return;
+ }
+
+ // Draw something to that framebuffer.
+ gl.clearColor(0.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after clearing R11F_G11F_B10F framebuffer");
+
+ // Set up destination framebuffer for resolving MSAA.
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R11F_G11F_B10F, width, height, 0, gl.RGB, gl.UNSIGNED_INT_10F_11F_11F_REV, null);
+ var drawfb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, drawfb);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after destination R11F_G11F_B10F FBO setup");
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ // Attempt a blit.
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after blitFramebuffer for multisample resolve");
+
+ // Try a readback.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, drawfb);
+ var readBackBuf = new Float32Array(width * height * 4);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0.0, 1.0, 0.0], "should be green", undefined, readBackBuf, gl.FLOAT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after floating-point canvas readback");
+
+ // If default backbuffer is RGB and non-antialiased, test blitting to it too.
+ if (args && !args['alpha'] && !args['antialias']) {
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, drawfb);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after blit to default back buffer");
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ wtu.checkCanvas(gl, [ 0, 255, 0, 255 ], "default back buffer should be green");
+ }
+}
+
+// The format of the back buffer should have no effect on the behavior of this test.
+runWithContextCreationArguments(undefined);
+runWithContextCreationArguments({ alpha: true, antialias: true });
+runWithContextCreationArguments({ alpha: true, antialias: false });
+runWithContextCreationArguments({ alpha: false, antialias: true });
+runWithContextCreationArguments({ alpha: false, antialias: false });
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html
new file mode 100644
index 0000000000..addbdc4e9d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html
@@ -0,0 +1,245 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Resolve to Back Buffer</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="canvasHeader"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the behavior of blitFramebuffer when resolving directly to the back buffer.");
+
+debug("Regression test for <a href='http://crbug.com/699566'>http://crbug.com/699566</a>");
+
+function runTest(testParams) {
+ const sz = 64;
+
+ if (testParams.multisampled === undefined) {
+ testParams.multisampled = true;
+ }
+
+ debug('');
+ debug('Testing with alpha = ' + testParams.attribs.alpha +
+ ', antialias = ' + testParams.attribs.antialias +
+ ', internalformat = ' + testParams.internalformat +
+ ', multisampled = ' + testParams.multisampled);
+
+ var canvas = document.createElement('canvas');
+ canvas.width = sz;
+ canvas.height = sz;
+ document.getElementById('canvasHeader').appendChild(canvas);
+ var gl = wtu.create3DContext(canvas, testParams.attribs, 2);
+
+ // Find the supported samples for a multisampled renderbuffer of the appropriate internal format.
+ let samples = [0];
+ if (testParams.multisampled) {
+ samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
+ if (!samples || !samples.length) {
+ testFailed("At least one multisampled format is required to be supported");
+ return;
+ }
+ }
+
+ // Create a framebuffer with a multisampled renderbuffer.
+ let rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl[testParams.internalformat], sz, sz);
+
+ // Create a framebuffer.
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+
+ // Check for completeness.
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Rendering to a multisampled renderbuffer of format " + testParams.internalformat + " is required by the spec");
+ return;
+ }
+
+ // Clear to specified color.
+ gl.clearColor.apply(gl, testParams.clearColor);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Unbind draw framebuffer. Read framebuffer is now user framebuffer;
+ // draw framebuffer is default framebuffer.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors before blit");
+
+ // Blit from user framebuffer to default framebuffer.
+ gl.blitFramebuffer(0, 0, sz, sz, 0, 0, sz, sz, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+
+ if (testParams.shouldSucceed) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be legal to blit/resolve to default back buffer");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "incompatible src/dest blitFramebuffer combination must fail");
+ }
+
+ // Unbind user framebuffer completely.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+
+ if (testParams.shouldSucceed) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error before readback");
+ wtu.checkCanvasRect(gl, 0, 0, 8, 8, testParams.resultColor);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+}
+
+var tests = [
+ // No-alpha, no-antialias, RGB8 source
+ {
+ attribs: {
+ alpha: false,
+ antialias: false,
+ },
+ internalformat: 'RGB8',
+ clearColor: [ 0.0, 1.0, 0.0, 0.5 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: true,
+ },
+ // No-alpha, no-antialias, RGBA8 source
+ {
+ attribs: {
+ alpha: false,
+ antialias: false,
+ },
+ internalformat: 'RGBA8',
+ clearColor: [ 0.0, 1.0, 0.0, 0.5 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: false,
+ },
+ // No-alpha, no-antialias, RGBA8 source, single-sampled blit
+ {
+ attribs: {
+ alpha: false,
+ antialias: false,
+ },
+ internalformat: 'RGBA8',
+ clearColor: [ 0.0, 1.0, 0.0, 0.5 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: true,
+ multisampled: false,
+ },
+ // Alpha, no-antialias, RGB8 source
+ {
+ attribs: {
+ alpha: true,
+ antialias: false,
+ },
+ internalformat: 'RGB8',
+ clearColor: [ 0.0, 1.0, 0.0, 1.0 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: false,
+ },
+ // No-alpha, no-antialias, RGBA8 source
+ // premultiplyAlpha:false just to avoid semantically incorrect
+ // colors (should only affect rendering, not contents of WebGL
+ // back buffer)
+ {
+ attribs: {
+ alpha: false,
+ antialias: false,
+ premultiplyAlpha: false,
+ },
+ internalformat: 'RGBA8',
+ clearColor: [ 0.0, 1.0, 0.0, 1.0 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: false,
+ },
+ // Alpha, no-antialias, RGBA8 source
+ // premultiplyAlpha:false just to avoid semantically incorrect
+ // colors (should only affect rendering, not contents of WebGL
+ // back buffer)
+ {
+ attribs: {
+ alpha: true,
+ antialias: false,
+ premultiplyAlpha: false,
+ },
+ internalformat: 'RGBA8',
+ clearColor: [ 0.0, 1.0, 0.0, 0.0 ],
+ resultColor: [ 0, 255, 0, 0 ],
+ shouldSucceed: true,
+ },
+
+ // All attempts to blit to an antialiased back buffer should fail.
+
+ // No-alpha, antialias, RGB8 source
+ {
+ attribs: {
+ alpha: false,
+ antialias: true,
+ },
+ internalformat: 'RGB8',
+ clearColor: [ 0.0, 1.0, 0.0, 1.0 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: false,
+ },
+ // Alpha, antialias, RGB8 source
+ {
+ attribs: {
+ alpha: true,
+ antialias: true,
+ },
+ internalformat: 'RGB8',
+ clearColor: [ 0.0, 1.0, 0.0, 1.0 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: false,
+ },
+ // No-alpha, antialias, RGBA8 source
+ // premultiplyAlpha:false just to avoid semantically incorrect
+ // colors (should only affect rendering, not contents of WebGL
+ // back buffer)
+ {
+ attribs: {
+ alpha: false,
+ antialias: true,
+ premultiplyAlpha: false,
+ },
+ internalformat: 'RGBA8',
+ clearColor: [ 0.0, 1.0, 0.0, 1.0 ],
+ resultColor: [ 0, 255, 0, 255 ],
+ shouldSucceed: false,
+ },
+ // Alpha, antialias, RGBA8 source
+ // premultiplyAlpha:false just to avoid semantically incorrect
+ // colors (should only affect rendering, not contents of WebGL
+ // back buffer)
+ {
+ attribs: {
+ alpha: true,
+ antialias: true,
+ premultiplyAlpha: false,
+ },
+ internalformat: 'RGBA8',
+ clearColor: [ 0.0, 1.0, 0.0, 0.0 ],
+ resultColor: [ 0, 255, 0, 0 ],
+ shouldSucceed: false,
+ },
+];
+
+for (var ii in tests) {
+ runTest(tests[ii]);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-scissor-enabled.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-scissor-enabled.html
new file mode 100644
index 0000000000..d0e2dfaefa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-scissor-enabled.html
@@ -0,0 +1,160 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer when scissor test is enabled.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+// Define the src region and dst region for blitFramebuffer
+var blit_src = [0, 0, 4, 4];
+var blit_dst = [2, 2, 6, 6];
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ var bounds = [
+ [0, 0, 4, 4], // Partially intersects with blitFramebuffer's dst region
+ [0, 0, 2, 2], // No intersection with blitFramebuffer's dst region
+ ];
+
+ // We can compute the real drawing area by intersecting the scissor bound with dst region of blitting.
+ var intersections = [
+ [2, 2, 4, 4],
+ [0, 0, 0, 0],
+ ];
+
+ for (var ii = 0; ii < bounds.length; ++ii) {
+ blitframebuffer_scissor(gl.RGBA8, gl.RGBA8, bounds[ii], intersections[ii]);
+ blitframebuffer_scissor(gl.RGBA8, gl.SRGB8_ALPHA8, bounds[ii], intersections[ii]);
+ blitframebuffer_scissor(gl.SRGB8_ALPHA8, gl.RGBA8, bounds[ii], intersections[ii]);
+ blitframebuffer_scissor(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, bounds[ii], intersections[ii]);
+ }
+}
+
+function checkPixel(color, expectedColor) {
+ var tolerance = 3;
+ return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
+ Math.abs(color[1] - expectedColor[1]) <= tolerance &&
+ Math.abs(color[2] - expectedColor[2]) <= tolerance &&
+ Math.abs(color[3] - expectedColor[3]) <= tolerance);
+}
+
+function blitframebuffer_scissor(readbufferFormat, drawbufferFormat, bound, intersection) {
+ debug("");
+ debug("read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat) + ", draw buffer format is: " + wtu.glEnumToString(gl, drawbufferFormat));
+
+
+ // Initiate data to read framebuffer
+ var size = 8;
+ var data = new Uint8Array(size * size * 4);
+ var color = [250, 100, 15, 255];
+ for (var ii = 0; ii < size * size * 4; ii += 4) {
+ for (var jj = 0; jj < 4; ++jj) {
+ data[ii + jj] = color[jj];
+ }
+ }
+
+ // Feed data to read buffer. Feed 0 to draw buffer.
+ var tex_read = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_read);
+ gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+
+ var fbo_read = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
+
+ var tex_draw = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_draw);
+ gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var fbo_draw = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_draw, 0);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE || gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ // Enable scissor test. Then blit framebuffer.
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(bound[0], bound[1], bound[2], bound[3]);
+ gl.blitFramebuffer(blit_src[0], blit_src[1], blit_src[2], blit_src[3], blit_dst[0], blit_dst[1], blit_dst[2], blit_dst[3], gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitframebuffer should succeed");
+
+ // Read pixels and Comparison
+ var pixels = new Uint8Array(size * size * 4);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
+ gl.readPixels(0, 0, size, size, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should succeed");
+
+ var blitColor;
+ var expectedColor;
+ var clearColor = [0, 0, 0, 0];
+
+ if (readbufferFormat == drawbufferFormat) {
+ blitColor = color;
+ } else if (readbufferFormat == gl.SRGB8_ALPHA8) {
+ blitColor = wtu.sRGBToLinear(color);
+ } else {
+ blitColor = wtu.linearToSRGB(color);
+ }
+
+ var failed = false;
+ for (var ii = 0; ii < size; ++ii) {
+ for (var jj = 0; jj < size; ++jj) {
+ if (ii >= intersection[0] && jj >= intersection[1] && ii < intersection[2] && jj < intersection[3]) {
+ expectedColor = blitColor;
+ } else {
+ expectedColor = clearColor;
+ }
+ var index = (ii * size + jj) * 4;
+ var pixelColor = [pixels[index], pixels[index + 1], pixels[index + 2], pixels[index + 3]];
+ if (checkPixel(pixelColor, expectedColor) == false) {
+ failed = true;
+ debug("Pixels comparison failed. Pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + pixelColor + ")");
+ }
+ }
+ }
+ if (failed == false) {
+ testPassed("All pixels comparision passed!");
+ }
+
+ // Deinit
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo_read);
+ gl.deleteFramebuffer(fbo_draw);
+ gl.deleteTexture(tex_read);
+ gl.deleteTexture(tex_draw);
+};
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-size-overflow.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-size-overflow.html
new file mode 100644
index 0000000000..512946cb82
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-size-overflow.html
@@ -0,0 +1,98 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies blitFramebuffer won't cause a crash when the computed sizes might overflow.");
+
+var width = 8;
+var height = 8;
+
+var gl = wtu.create3DContext("example", undefined, 2);
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ blit_region_test();
+}
+
+function blit_region_test() {
+
+ debug("");
+ debug("Begin to run blitFramebuffer. The computed width/height of src and/or dst region might overflow during blitting.");
+ var tex0 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ var fb0 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
+
+ var tex1 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ var fb1 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex1, 0);
+ if ((gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) ||
+ (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ var max = 0x7fffffff;
+ gl.blitFramebuffer(0, 0, max, max, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, max, max, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.blitFramebuffer(0, 0, max, max, 0, 0, max, max, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Using max 32-bit integer as blitFramebuffer parameter should succeed.");
+
+ gl.blitFramebuffer(-1, -1, max - 1, max - 1, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.blitFramebuffer(0, 0, width, height, -1, -1, max - 1, max - 1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.blitFramebuffer(-1, -1, max - 1, max - 1, -1, -1, max - 1, max - 1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Using blitFramebuffer parameters where calculated width/height matches max 32-bit integer should succeed.");
+
+ gl.blitFramebuffer(-1, -1, max, max, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Using source width/height greater than max 32-bit integer should fail.");
+ gl.blitFramebuffer(max, max, -1, -1, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Using source width/height greater than max 32-bit integer should fail.");
+ gl.blitFramebuffer(0, 0, width, height, -1, -1, max, max, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Using destination width/height greater than max 32-bit integer should fail.");
+ gl.blitFramebuffer(0, 0, width, height, max, max, -1, -1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Using destination width/height greater than max 32-bit integer should fail.");
+ gl.blitFramebuffer(-1, -1, max, max, -1, -1, max, max, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Using both source and destination width/height greater than max 32-bit integer should fail.");
+ gl.blitFramebuffer(-max - 1, -max - 1, max, max, -max - 1, -max - 1, max, max, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Using minimum and maximum integers for all boundaries should fail.");
+
+ gl.bindTexture(gl.TEXTURE_2D, null)
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteTexture(tex0);
+ gl.deleteTexture(tex1);
+ gl.deleteFramebuffer(fb0);
+ gl.deleteFramebuffer(fb1);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html
new file mode 100644
index 0000000000..35b8c3ddab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html
@@ -0,0 +1,207 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer with multiple draw buffers (srgb image and linear image).");
+
+var gl = wtu.create3DContext("canvas", undefined, 2);
+var linearMask = 1;
+var srgbMask = 2;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ var filters = [gl.LINEAR, gl.NEAREST];
+ var drawbuffersFormats = [linearMask, srgbMask, linearMask | srgbMask];
+ for (var ii = 0; ii < filters.length; ++ii) {
+ for (var jj = 0; jj < drawbuffersFormats.length; ++jj) {
+ blitframebuffer_srgb_and_linear_drawbuffers(gl.SRGB8_ALPHA8, drawbuffersFormats[jj], filters[ii]);
+ blitframebuffer_srgb_and_linear_drawbuffers(gl.RGBA8, drawbuffersFormats[jj], filters[ii]);
+ }
+ }
+}
+
+function blitframebuffer_srgb_and_linear_drawbuffers(readbufferFormat, drawbuffersFormatMask, filter) {
+ debug("");
+ debug("The filter is: " + wtu.glEnumToString(gl, filter));
+ debug("Read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat));
+ var drawbuffersFormat = "\0";
+ if (drawbuffersFormatMask & linearMask) {
+ drawbuffersFormat += " linear ";
+ }
+ if (drawbuffersFormatMask & srgbMask) {
+ drawbuffersFormat += " srgb ";
+ }
+ debug("The test have multiple draw buffers, the images are: " + drawbuffersFormat);
+
+ var tex_srgb0 = gl.createTexture();
+ var tex_srgb1 = gl.createTexture();
+ var tex_linear0 = gl.createTexture();
+ var tex_linear1 = gl.createTexture();
+ var tex_read = gl.createTexture();
+ var fbo_read = gl.createFramebuffer();
+ var fbo_draw = gl.createFramebuffer();
+
+ // Create read buffer and feed data to the read buffer
+ var size = 8;
+ var data = new Uint8Array(size * size * 4);
+ var color = [250, 100, 15, 255];
+ for (var ii = 0; ii < size * size * 4; ii += 4) {
+ for (var jj = 0; jj < 4; ++jj) {
+ data[ii + jj] = color[jj];
+ }
+ }
+ gl.bindTexture(gl.TEXTURE_2D, tex_read);
+ gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup read framebuffer should succeed");
+
+ // Create multiple textures. Attach them as fbo's draw buffers.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+
+ var drawbuffers = [gl.NONE, gl.NONE, gl.NONE, gl.NONE];
+ if (drawbuffersFormatMask & srgbMask) {
+ gl.bindTexture(gl.TEXTURE_2D, tex_srgb0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_srgb0, 0);
+ gl.bindTexture(gl.TEXTURE_2D, tex_srgb1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, tex_srgb1, 0);
+ drawbuffers[0] = gl.COLOR_ATTACHMENT0;
+ drawbuffers[2] = gl.COLOR_ATTACHMENT2;
+ }
+
+ if (drawbuffersFormatMask & linearMask) {
+ gl.bindTexture(gl.TEXTURE_2D, tex_linear0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex_linear0, 0);
+ gl.bindTexture(gl.TEXTURE_2D, tex_linear1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.TEXTURE_2D, tex_linear1, 0);
+ drawbuffers[1] = gl.COLOR_ATTACHMENT1;
+ drawbuffers[3] = gl.COLOR_ATTACHMENT3;
+ }
+
+ gl.drawBuffers(drawbuffers);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup draw framebuffer should succeed");
+
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete when setup draw framebuffer.");
+ return;
+ }
+
+ // Blit to multiple draw buffers with srgb images and linear images
+ var dstSize = size - 1;
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, dstSize, dstSize, gl.COLOR_BUFFER_BIT, filter);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitframebuffer should succeed");
+
+ // Read pixels from srgb images and linear images
+ var srgbPixels0 = new Uint8Array(dstSize * dstSize * 4);
+ var srgbPixels1 = new Uint8Array(dstSize * dstSize * 4);
+ var linearPixels0 = new Uint8Array(dstSize * dstSize * 4);
+ var linearPixels1 = new Uint8Array(dstSize * dstSize * 4);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
+ if (drawbuffersFormatMask & srgbMask) {
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, srgbPixels0);
+ gl.readBuffer(gl.COLOR_ATTACHMENT2);
+ gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, srgbPixels1);
+ }
+
+ if (drawbuffersFormatMask & linearMask) {
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, linearPixels0);
+ gl.readBuffer(gl.COLOR_ATTACHMENT3);
+ gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, linearPixels1);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixels should succeed");
+
+ // Compare
+ var expectedSRGBColor = (readbufferFormat == gl.SRGB8_ALPHA8) ? color : wtu.linearToSRGB(color);
+ var expectedLinearColor = (readbufferFormat == gl.SRGB8_ALPHA8) ? wtu.sRGBToLinear(color) : color;
+ var failed = false;
+ for (var ii = 0; ii < dstSize; ++ii) {
+ for (var jj = 0; jj < dstSize; ++jj) {
+ var index = (ii * dstSize + jj) * 4;
+ if (drawbuffersFormatMask & srgbMask) {
+ var srgbColor0 = [srgbPixels0[index], srgbPixels0[index + 1], srgbPixels0[index + 2], srgbPixels0[index + 3]];
+ if (checkPixel(srgbColor0, expectedSRGBColor) == false) {
+ failed = true;
+ debug("Pixels comparison failed for the 1st sRGB image. Pixel at [" + jj + ", " + ii + "] should be (" + expectedSRGBColor + "), but the actual color is (" + srgbColor0 + ")");
+ }
+ var srgbColor1 = [srgbPixels1[index], srgbPixels1[index + 1], srgbPixels1[index + 2], srgbPixels1[index + 3]];
+ if (checkPixel(srgbColor1, expectedSRGBColor) == false) {
+ failed = true;
+ debug("Pixels comparison failed for the 2nd sRGB image. Pixel at [" + jj + ", " + ii + "] should be (" + expectedSRGBColor + "), but the actual color is (" + srgbColor1 + ")");
+ }
+ }
+
+ if (drawbuffersFormatMask & linearMask) {
+ var linearColor0 = [linearPixels0[index], linearPixels0[index + 1], linearPixels0[index + 2], linearPixels0[index + 3]];
+ if (checkPixel(linearColor0, expectedLinearColor) == false) {
+ failed = true;
+ debug("Pixel comparison failed for the 1st linear image. Pixel at [" + jj + ", " + ii + "] should be (" + color + "), but the actual color is (" + linearColor0 + ")");
+ }
+ var linearColor1 = [linearPixels1[index], linearPixels1[index + 1], linearPixels1[index + 2], linearPixels1[index + 3]];
+ if (checkPixel(linearColor1, expectedLinearColor) == false) {
+ failed = true;
+ debug("Pixel comparison failed for the 2nd linear image. Pixel at [" + jj + ", " + ii + "] should be (" + color + "), but the actual color is (" + linearColor1 + ")");
+ }
+ }
+ }
+ }
+ if (failed == false) {
+ testPassed("All pixels comparision passed!");
+ }
+
+ // deinit
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteTexture(tex_srgb0);
+ gl.deleteTexture(tex_linear0);
+ gl.deleteTexture(tex_srgb1);
+ gl.deleteTexture(tex_linear1);
+ gl.deleteTexture(tex_read);
+ gl.deleteFramebuffer(fbo_read);
+ gl.deleteFramebuffer(fbo_draw);
+}
+
+function checkPixel(color, expectedColor) {
+ var tolerance = 3;
+ return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
+ Math.abs(color[1] - expectedColor[1]) <= tolerance &&
+ Math.abs(color[2] - expectedColor[2]) <= tolerance &&
+ Math.abs(color[3] - expectedColor[3]) <= tolerance);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-stencil-only.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-stencil-only.html
new file mode 100644
index 0000000000..b14acf3456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-stencil-only.html
@@ -0,0 +1,170 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Stencil-only Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+
+<script id="vs" type="x-shader/x-vertex">#version 300 es
+in vec4 position;
+void main() {
+ gl_Position = position;
+}
+</script>
+<script id="fs" type="x-shader/x-fragment">#version 300 es
+out mediump vec4 colorOut;
+uniform mediump vec3 color;
+void main() {
+ colorOut = vec4(color, 1.0);
+}
+</script>
+
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test covers some edge cases of blitFramebuffer with stencil.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var program, colorLoc;
+
+function init_buffer(format) {
+ var buf = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, buf)
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 16, 16);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ var rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, format, 16, 16);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER,
+ gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo);
+
+ gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after buffer init");
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ return { fbo: buf, color: tex, depthStencil: rbo };
+}
+
+var quadVB;
+
+function drawQuad(depth) {
+ if (!quadVB) {
+ quadVB = gl.createBuffer()
+ }
+
+ var quadVerts = new Float32Array(3 * 6);
+ quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth;
+ quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth;
+ quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth;
+ quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth;
+ quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth;
+ quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, quadVB);
+ gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawQuad");
+}
+
+// Test based on dEQP-GLES3.functional.blit.depth_stencil.depth_24_stencil8_stencil_only
+function test_stencil_only_blit(format) {
+ debug("testing format: " + wtu.glEnumToString(gl, format))
+
+ var src = init_buffer(format);
+ var dest = init_buffer(format);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, src.fbo);
+ gl.viewport(0, 0, 16, 16);
+
+ // Fill source with red, depth = 0.5, stencil = 7
+ gl.enable(gl.DEPTH_TEST);
+ gl.enable(gl.STENCIL_TEST);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ gl.stencilFunc(gl.ALWAYS, 7, 0xFF);
+ gl.uniform3f(colorLoc, 1.0, 0.0, 0.0);
+ drawQuad(0.5);
+
+ // Fill dest with yellow, depth = 0.0, stencil = 1
+ gl.bindFramebuffer(gl.FRAMEBUFFER, dest.fbo);
+ gl.stencilFunc(gl.ALWAYS, 1, 0xff);
+ gl.uniform3f(colorLoc, 1.0, 1.0, 0.0);
+ drawQuad(0.0);
+
+ // Perform copy.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, src.fbo);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dest.fbo);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.STENCIL_BUFFER_BIT, gl.NEAREST);
+
+ // Render blue where depth < 0, decrement on depth failure.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, dest.fbo);
+ gl.stencilOp(gl.KEEP, gl.DECR, gl.KEEP);
+ gl.stencilFunc(gl.ALWAYS, 0, 0xff);
+
+ gl.uniform3f(colorLoc, 0.0, 0.0, 1.0);
+ drawQuad(0.0);
+
+ // Render green where stencil == 6.
+ gl.disable(gl.DEPTH_TEST);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ gl.stencilFunc(gl.EQUAL, 6, 0xff);
+
+ gl.uniform3f(colorLoc, 0.0, 1.0, 0.0);
+ drawQuad(0.0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after test");
+ wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0, 255, 0, 255],
+ "stencil test should be green");
+
+ gl.deleteFramebuffer(src.fbo);
+ gl.deleteFramebuffer(dest.fbo);
+ gl.deleteTexture(src.color);
+ gl.deleteTexture(dest.color);
+ gl.deleteRenderbuffer(src.depthStencil);
+ gl.deleteRenderbuffer(dest.depthStencil);
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ program = wtu.setupProgram(gl, ["vs", "fs"], ["position"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after program initialization");
+ shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
+
+ colorLoc = gl.getUniformLocation(program, "color")
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "query uniform location");
+ shouldBeNonNull('colorLoc')
+
+ test_stencil_only_blit(gl.DEPTH24_STENCIL8);
+ test_stencil_only_blit(gl.DEPTH32F_STENCIL8);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-test.html
new file mode 100644
index 0000000000..c470b02e4e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-test.html
@@ -0,0 +1,361 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL BlitFramebuffer Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of blitFramebuffer for some corner cases.");
+
+var width = 8;
+var height = 8;
+
+var gl = wtu.create3DContext("example", undefined, 2);
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ blit_framebuffer_repeated();
+ blit_framebuffer_feedback_loop();
+ blit_framebuffer_multisampling_srgb();
+}
+
+function blit_framebuffer_repeated() {
+ debug("");
+ debug("This test verifies repeated calls to blitFramebuffer.");
+
+ // Create offscreen fbo and its color attachment.
+ var tex_2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_2d);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, width, height);
+ 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);
+
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ var prog = wtu.setupColorQuad(gl, 0);
+ wtu.setFloatDrawColor(gl, [ 1.0, 0.0, 0.0, 1.0 ]);
+ wtu.drawUnitQuad(gl);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ wtu.checkCanvas(gl, [ 255, 0, 0, 255 ], "should be red at first");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ wtu.setFloatDrawColor(gl, [ 0.0, 1.0, 0.0, 1.0 ]);
+ wtu.drawUnitQuad(gl);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ wtu.checkCanvas(gl, [ 0, 255, 0, 255 ], "should be green");
+}
+
+function blit_framebuffer_feedback_loop() {
+
+ debug("");
+ debug("This test checks whether the src resource and dst resource have identical images.");
+ // Create read fbo and its color attachment.
+ var tex_2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex_2d);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+
+ var fb0 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ // Create draw fbo and its color attachment.
+ var rb0 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, width, height);
+
+ var fb1 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ // Blit framebuffer, all conditions are OK.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
+
+ // Blit framebuffer, the src buffer and the dst buffer should not be identical.
+ // Exactly the same read/draw fbo
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb0);
+ gl.blitFramebuffer(0, 0, 2, 2, 4, 4, 6, 6, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw buffer are identical.");
+
+ // Exactly the same read/draw framebuffer: default framebuffer
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, 2, 2, 4, 4, 6, 6, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw buffer are identical.");
+
+ // The same image with the same level bound to read/draw buffer.
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 0);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 4, 4, 6, 6, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw color buffer are identical.");
+
+ // The same image in read/draw buffer, but different levels are bound to read/draw buffer respectively.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_2d, 1);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed if read/draw buffer has the same image with different levels.");
+
+ // The same cube_map image in read/draw buffer, but different faces are bound to read/draw buffer respectively.
+ var tex_cube_map = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex_cube_map);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, tex_cube_map, 0);
+ if ((gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) ||
+ (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed if read/draw buffer has the same CUBE_MAP image with different faces.");
+
+ // The same 3D/2D_ARRAY image in read/draw buffer, but different layers are bound to read/draw buffer respectively.
+ var tex_2d_array = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex_2d_array);
+ var depth = 2;
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ var level = 0, layer = 0;
+ gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex_2d_array, level, layer);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ layer = 1;
+ gl.framebufferTextureLayer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex_2d_array, level, layer);
+ if ((gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) ||
+ (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed if read/draw buffer has the same 3D/2D_ARRAY image with different layers.");
+
+ // The same image are bound as depth buffer in both read framebuffer and draw framebuffer
+ var rb1 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, width, height);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb1);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, tex_cube_map, 0);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb1);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ // But the mask doesn't have depth buffer bit.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
+
+ // The mask has depth buffer bit.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw framebuffer have identical depth buffer attachment.");
+
+ // The same image are bound as stencil buffer in both read framebuffer and draw framebuffer
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb1);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb1);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ // But the mask doesn't have stencil buffer bit.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
+
+ // The mask has stencil buffer bit.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw framebuffer have identical stencil buffer attachment.");
+
+ // The same image are bound as color buffer in both read framebuffer and draw framebuffer
+ var rb2 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb2);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, width, height);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb2);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, tex_cube_map, 0);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex_cube_map, 0);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb1);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ // But the mask doesn't have color buffer bit.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
+
+ // The mask has color buffer bit, but the same image is not specified as draw buffer.
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer should succeed.");
+
+ // The mask has color buffer bit, the same image is specified as both read buffer and draw buffer.
+ gl.drawBuffers([gl.COLOR_ATTACHENT0, gl.COLOR_ATTACHMENT1]);
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer should generate INVALID_OPERATION if read/draw buffers have identical color buffer attachment.");
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteTexture(tex_2d);
+ gl.deleteTexture(tex_cube_map);
+ gl.deleteTexture(tex_2d_array);
+ gl.deleteRenderbuffer(rb0);
+ gl.deleteRenderbuffer(rb1);
+ gl.deleteRenderbuffer(rb2);
+ gl.deleteFramebuffer(fb0);
+ gl.deleteFramebuffer(fb1);
+};
+
+function blit_framebuffer_multisampling_srgb() {
+
+ debug("");
+ debug("This test vefify the functionality of blitframebuffer from or to a multisampled srgb image.");
+
+ // Read buffer can have multisampled srgb image, but draw buffers can not.
+ var rb0 = gl.createRenderbuffer();
+ var fb0 = gl.createFramebuffer();
+ var rb1 = gl.createRenderbuffer();
+ var fb1 = gl.createFramebuffer();
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, gl.SAMPLES);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.SRGB8_ALPHA8, width, height);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb0);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, width, height);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb1);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
+ gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitFramebuffer from multisampled srgb image should succeed.");
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl.SRGB8_ALPHA8, width, height);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb1);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer to a multisampled srgb image should generate INVALID_OPERATION.");
+
+ // BlitFramebuffer from a multisampled srgb image, the src region and the dst region must be exactly the same.
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, width, height);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb1);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 2, 2, 4, 4, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer from a multisampled srgb image, the src region and the dst region must be exactly the same.");
+
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 4, 4, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer from a multisampled srgb image, the src region and the dst region must be exactly the same.");
+
+ // BlitFramebuffer from a multisampled srgb image, the format/type must be exactly the same. So blit from a multisampled srgb image to a linear image is invalid.
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.blitFramebuffer(0, 0, 2, 2, 0, 0, 2, 2, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "blitFramebuffer from a multisampled srgb image, the format/type must be exactly the same.");
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.deleteRenderbuffer(rb0);
+ gl.deleteRenderbuffer(rb1);
+ gl.deleteTexture(tex);
+ gl.deleteFramebuffer(fb0);
+ gl.deleteFramebuffer(fb1);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-unaffected-by-colormask.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-unaffected-by-colormask.html
new file mode 100644
index 0000000000..3d2d7f54bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-unaffected-by-colormask.html
@@ -0,0 +1,102 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>BlitFramebuffer Should Be Unaffected by ColorMask</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+const wtu = WebGLTestUtils;
+description("This test verifies that the blitFramebuffer is unaffected by the colorMask state.");
+
+debug('Regression test for <a href="https://crbug.com/1257769">https://crbug.com/1257769</a> and <a href="https://bugs.webkit.org/show_bug.cgi?id=220129">https://bugs.webkit.org/show_bug.cgi?id=220129</a>');
+
+function allocateTexture(gl, size) {
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ return tex;
+}
+
+function allocateFBO(gl, tex) {
+ const fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ return fbo;
+}
+
+function run() {
+ const gl = wtu.create3DContext("canvas", { antialias: false }, 2);
+
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ finishTest();
+ return;
+ }
+
+ const size = 8;
+
+ testPassed("WebGL context exists");
+
+ // Allocate source and destination textures and framebuffer objects.
+ const sourceTex = allocateTexture(gl, size);
+ const sourceFBO = allocateFBO(gl, sourceTex);
+
+ const destTex = allocateTexture(gl, size);
+ const destFBO = allocateFBO(gl, destTex);
+
+ const program = wtu.setupColorQuad(gl);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, sourceFBO);
+
+ // Clear the source framebuffer to red.
+ gl.clearColor(1, 0, 0, 1);
+ gl.colorMask(true, true, true, true);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Draw a transparent green quad.
+ gl.useProgram(program);
+ wtu.drawFloatColorQuad(gl, [ 0, 255, 0, 0 ]);
+
+ // Clear the alpha channel.
+ gl.colorMask(false, false, false, true);
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // At this point, even setting the colorMask to all-true won't
+ // work around the bug, since that state is latched inside ANGLE
+ // only during draws / clears.
+
+ // Blit source to dest.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, destFBO);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, destFBO);
+
+ // Note that the on-screen canvas is always black - we don't blit the result to it.
+ wtu.checkCanvas(gl, [ 0, 255, 0, 255 ], "should be green", 1);
+ finishTest();
+}
+
+var successfullyParsed = true;
+
+requestAnimationFrame(run);
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/builtin-vert-attribs.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/builtin-vert-attribs.html
new file mode 100644
index 0000000000..cc64c9034b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/builtin-vert-attribs.html
@@ -0,0 +1,408 @@
+<!--
+Copyright (c) 2022 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<link rel=stylesheet href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id=e_canvas width=1 height=1 style="width: 100px; height: 100px;"></canvas>
+<div id=description></div>
+<div id=console></div>
+<script>
+"use strict";
+description('gl_VertexID and gl_InstanceID should behave as per spec.');
+
+//
+
+/*
+So what are gl_VertexID and gl_InstanceID supposed to do?
+In ES 3.0 and GL 4.1 (Core), this is all we get:
+
+# ES 3.0
+
+> (p78) gl_VertexID holds the integer index i implicitly passed by DrawArrays or
+> one of the other drawing commands defined in section 2.9.3. The value of
+> gl_VertexID is defined if and only if all enabled vertex arrays have non-zero buffer
+> object bindings.
+> gl_InstanceID holds the integer instance number of the current primitive in
+> an instanced draw call (see section 2.9.3).
+
+
+# GL 4.1 (Core)
+
+> (p102) gl_VertexID holds the integer index i implicitly passed by DrawArrays or
+> one of the other drawing commands defined in section 2.8.3.
+> gl_InstanceID holds the integer index of the current primitive in an
+> instanced draw call (see section 2.8.3).
+
+
+# ES 3.1
+
+ES 3.1 retains the wording from ES 3.0, but adds the following clarifications:
+
+gl_VertexID:
+> (p252) The index of any element transferred to the GL by DrawArraysOneInstance
+> is referred to as its vertex ID, and may be read by a vertex shader as gl_VertexID.
+> The vertex ID of the ith element transferred is first + i.
+
+> (p254) The index of any element transferred to the GL by
+> DrawElementsOneInstance is referred to as its vertex ID, and may be read by a vertex shader as
+> gl_VertexID. If no element array buffer is bound, the vertex ID of the ith element
+> transferred is indices[i] + basevertex. Otherwise, the vertex ID of the ith
+> element transferred is the sum of basevertex and the value stored in the currently
+> bound element array buffer at offset indices + i.
+
+gl_InstanceID
+> (p255) If an enabled vertex attribute array is instanced (it has a non-zero divisor as
+> specified by VertexAttribDivisor), the element index that is transferred to the GL,
+> for all vertices, is given by
+> `floor(instance / divisor) + baseinstance`
+
+
+# Errata
+
+Drivers generally do implement the ES 3.1 behavior.
+A notable exception is Mac's legacy GL (4.1) driver which has two bugs here.
+(Both ANGLE-on-Metal and the system M1+ GL driver seem correct though)
+
+## gl_InstanceID random for DrawArrays calls
+Use ERRATA.IGNORE_GL_INSTANCE_ID to cause these tests to pass.
+
+## Adds `first` to user-attrib instanced fetch ids in DrawArrays calls.
+Use ERRATA.FIRST_ADDS_TO_INSTANCE to cause these tests to pass.
+*/
+
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext('e_canvas');
+
+const ERRATA = {};
+//ERRATA.IGNORE_GL_INSTANCE_ID = true; // Chrome on ANGLE-on-Mac-GL needs this.
+//ERRATA.FIRST_ADDS_TO_INSTANCE = true; // Firefox with MOZ_WEBGL_WORKAROUND_FIRST_AFFECTS_INSTANCE_ID=0 would need this.
+
+debug(`ERRATA: ${JSON.stringify(ERRATA)}`);
+
+function make_vs_point(vid, iid) {
+ return `\
+ #version 300 es
+
+ ${vid.name == 'gl_VertexID' ? '// ' : ''}layout(location=${vid.loc}) in highp int ${vid.name};
+ ${iid.name == 'gl_InstanceID' ? '// ' :''}layout(location=${iid.loc}) in highp int ${iid.name};
+ out vec4 v_color;
+
+ void main() {
+ gl_PointSize = 1.0;
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+ v_color = vec4(1.0, float(${vid.name}) / 255.0, float(${iid.name}) / 255.0, 1.0);
+#if ${(iid.name == 'gl_InstanceID' && ERRATA.IGNORE_GL_INSTANCE_ID)|0}
+ v_color.b = 0.0;
+#endif
+ }`;
+}
+
+function make_vs_tri(vid, iid) {
+ return `\
+ #version 300 es
+
+ ${vid.name == 'gl_VertexID' ? '// ' : ''}layout(location=${vid.loc}) in highp int ${vid.name};
+ ${iid.name == 'gl_InstanceID' ? '// ' :''}layout(location=${iid.loc}) in highp int ${iid.name};
+ out vec4 v_color;
+
+ void main() {
+ int prim_vert_id = ${vid.name} % 3;
+ int flat_vert_id = ${vid.name} - prim_vert_id + 2;
+ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+ gl_Position.x = (prim_vert_id == 1) ? 2.0 : -1.0;
+ gl_Position.y = (prim_vert_id == 2) ? 2.0 : -1.0;
+ v_color = vec4(1.0, float(flat_vert_id) / 255.0, float(${iid.name}) / 255.0, 1.0);
+#if ${(iid.name == 'gl_InstanceID' && ERRATA.IGNORE_GL_INSTANCE_ID)|0}
+ v_color.b = 0.0;
+#endif
+ }`;
+}
+
+const FS = `\
+ #version 300 es
+ precision mediump float;
+
+ in vec4 v_color;
+ out vec4 o_color;
+
+ void main() {
+ o_color = v_color;
+ }
+`;
+
+
+function crossCombine(...args) {
+ function crossCombine2(listA, listB) {
+ const listC = [];
+ for (const a of listA) {
+ for (const b of listB) {
+ const c = Object.assign({}, a, b);
+ listC.push(c);
+ }
+ }
+ return listC;
+ }
+
+ let res = [{}];
+ while (args.length) {
+ const next = args.shift();
+ next[0].defined;
+ res = crossCombine2(res, next);
+ }
+ return res;
+}
+
+/// makeCombiner('foo', [5, 3]) -> [{foo: 5}, {foo: 3}]
+function makeCombiner(key, vals) {
+ const ret = [];
+ for (const val of vals) {
+ const cur = {};
+ cur[key] = val;
+ ret.push(cur);
+ }
+ return ret;
+}
+
+debug('Draw a point with a shader that takes no attributes and verify it fills the whole canvas.');
+
+
+let TESTS = [
+ makeCombiner('vid', [
+ {name: 'a_VertexID', loc:0},
+ {name: 'a_VertexID', loc:2}, // Test 2, so that we're not only testing 0.
+ {name: 'gl_VertexID', loc:-1},
+ {name: 'gl_VertexID', loc:0}, // Enable a vertex array, despite not using it.
+ {name: 'gl_VertexID', loc:2}, // Enable a vertex array, despite not using it.
+ ]),
+ makeCombiner('iid', [
+ {name: 'a_InstanceID', loc:1},
+ {name: 'gl_InstanceID', loc:-1},
+ {name: 'gl_InstanceID', loc:1}, // Enable a vertex array, despite not using it.
+ ]),
+ makeCombiner('separate_vbufs', [true, false]),
+];
+//console.log('a', {TESTS});
+TESTS = crossCombine(...TESTS);
+//console.log('b', {TESTS});
+
+
+let vdata = new Int32Array(1000);
+vdata = vdata.map((v,i) => i);
+const vbuf = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
+gl.bufferData(gl.ARRAY_BUFFER, vdata, gl.STATIC_DRAW);
+
+
+const vbuf2 = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, vbuf2);
+gl.bufferData(gl.ARRAY_BUFFER, vdata, gl.STATIC_DRAW);
+
+
+let index_data = new Uint32Array(1000);
+index_data = index_data.map((x,i) => 10+i);
+const index_buffer = gl.createBuffer();
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
+gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, index_data, gl.STATIC_DRAW);
+
+
+gl.disable(gl.DEPTH_TEST);
+
+(async () => {
+ for (const desc of TESTS) {
+ await wtu.dispatchPromise(); // Yield, for responsiveness.
+ debug('');
+ debug('---------------------');
+ debug(`desc: ${JSON.stringify(desc)}`);
+
+ let fn = (vs) => {
+ //console.log({vs});
+ const prog = wtu.setupProgram(gl, [vs, FS]);
+
+ {
+ const WEBGL_debug_shaders = gl.getExtension('WEBGL_debug_shaders');
+ let i = -1;
+ for (const s of gl.getAttachedShaders(prog)) {
+ i += 1;
+ debug('');
+ debug(`shader[${i}] getShaderSource() -> `);
+ debug(gl.getShaderSource(s));
+ if (WEBGL_debug_shaders) {
+ debug(`shader[${i}] getTranslatedShaderSource() -> `);
+ debug(WEBGL_debug_shaders.getTranslatedShaderSource(s));
+ }
+ }
+ }
+ return prog;
+ };
+ const point_prog = fn(make_vs_point(desc.vid, desc.iid));
+ const tri_prog = fn(make_vs_tri(desc.vid, desc.iid));
+
+ // -
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ for (let i = 0; i <= 2; i++) {
+ gl.disableVertexAttribArray(i);
+ gl.vertexAttribPointer(i, 4, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(i, 0);
+ }
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
+ let loc = desc.vid.loc;
+ if (loc != -1) {
+ gl.enableVertexAttribArray(loc);
+ gl.vertexAttribIPointer(loc, 1, gl.INT, 0, 0);
+ };
+
+ if (desc.separate_vbufs) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbuf2);
+ }
+ loc = desc.iid.loc;
+ if (loc != -1) {
+ gl.enableVertexAttribArray(loc);
+ gl.vertexAttribIPointer(loc, 1, gl.INT, 0, 0);
+ gl.vertexAttribDivisor(loc, 1);
+ };
+
+ {
+ const err = gl.getError();
+ if (err) throw err; // Broken init.
+ }
+
+ // -
+
+ fn = (eval_str, expected_arr) => {
+ if (ERRATA.IGNORE_GL_INSTANCE_ID) {
+ if (desc.iid.name == 'gl_InstanceID') {
+ expected_arr = expected_arr.map(x => x);
+ expected_arr[2] = 0;
+ }
+ }
+
+ debug('');
+ //debug(`${eval_str} -> [${expected_arr.join(', ')}]`);
+ eval(eval_str);
+
+ const err = gl.getError();
+ if (err) throw err; // Broken subtest.
+
+ wtu.checkCanvas(gl, expected_arr, eval_str);
+ }
+
+ gl.useProgram(point_prog);
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawArrays(gl.POINTS, 0, 0)`, [0, 0, 0, 0]);
+ fn(`gl.drawArrays(gl.POINTS, 0, 1)`, [255, 0, 0, 255]);
+ fn(`gl.drawArrays(gl.POINTS, 0, 2)`, [255, 1, 0, 255]);
+ if (ERRATA.FIRST_ADDS_TO_INSTANCE) {
+ fn(`gl.drawArrays(gl.POINTS, 100, 2)`, [255, 100+2-1, 100, 255]);
+ } else {
+ fn(`gl.drawArrays(gl.POINTS, 100, 2)`, [255, 100+2-1, 0, 255]);
+ }
+ fn(`gl.drawArrays(gl.POINTS, 0, 255)`, [255, 254, 0, 255]);
+ fn(`gl.drawArrays(gl.POINTS, 0, 256)`, [255, 255, 0, 255]);
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 0, 1)`, [0, 0, 0, 0]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 1, 0)`, [0, 0, 0, 0]);
+
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 1, 1)`, [255, 0, 0, 255]);
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 2, 1)`, [255, 1, 0, 255]);
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 1, 2)`, [255, 0, 1, 255]);
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 2, 2)`, [255, 1, 1, 255]);
+ if (ERRATA.FIRST_ADDS_TO_INSTANCE) {
+ fn(`gl.drawArraysInstanced(gl.POINTS, 100, 2, 2)`, [255, 100+2-1, 101, 255]);
+ } else {
+ fn(`gl.drawArraysInstanced(gl.POINTS, 100, 2, 2)`, [255, 100+2-1, 1, 255]);
+ }
+ fn(`gl.drawArraysInstanced(gl.POINTS, 0, 255, 255)`, [255, 254, 254, 255]);
+
+ // -
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_INT, 4*0)`, [0, 0, 0, 0]);
+ fn(`gl.drawElements(gl.POINTS, 1, gl.UNSIGNED_INT, 4*0)`, [255, 10+0, 0, 255]);
+ fn(`gl.drawElements(gl.POINTS, 2, gl.UNSIGNED_INT, 4*0)`, [255, 10+1, 0, 255]);
+ fn(`gl.drawElements(gl.POINTS, 2, gl.UNSIGNED_INT, 4*100)`, [255, 100+10+1, 0, 255]);
+ fn(`gl.drawElements(gl.POINTS, 245, gl.UNSIGNED_INT, 4*0)`, [255, 10+244, 0, 255]);
+ fn(`gl.drawElements(gl.POINTS, 246, gl.UNSIGNED_INT, 4*0)`, [255, 10+245, 0, 255]);
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_INT, 4*0, 1)`, [0, 0, 0, 0]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 1, gl.UNSIGNED_INT, 4*0, 0)`, [0, 0, 0, 0]);
+
+ fn(`gl.drawElementsInstanced(gl.POINTS, 1, gl.UNSIGNED_INT, 4*0, 1)`, [255, 10+0, 0, 255]);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 2, gl.UNSIGNED_INT, 4*0, 1)`, [255, 10+1, 0, 255]);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 1, gl.UNSIGNED_INT, 4*0, 2)`, [255, 10+0, 1, 255]);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 2, gl.UNSIGNED_INT, 4*0, 2)`, [255, 10+1, 1, 255]);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 2, gl.UNSIGNED_INT, 4*100, 2)`, [255, 100+10+1, 1, 255]);
+ fn(`gl.drawElementsInstanced(gl.POINTS, 245, gl.UNSIGNED_INT, 4*0, 255)`, [255, 10+244, 254, 255]);
+
+ // -
+
+ gl.useProgram(tri_prog);
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawArrays(gl.TRIANGLES, 0, 0*3)`, [0, 0, 0, 0]);
+ fn(`gl.drawArrays(gl.TRIANGLES, 0, 1*3)`, [255, 1*3-1, 0, 255]);
+ fn(`gl.drawArrays(gl.TRIANGLES, 0, 2*3)`, [255, 2*3-1, 0, 255]);
+ if (ERRATA.FIRST_ADDS_TO_INSTANCE) {
+ fn(`gl.drawArrays(gl.TRIANGLES, 90, 2*3)`, [255, 90+2*3-1, 90, 255]);
+ } else {
+ fn(`gl.drawArrays(gl.TRIANGLES, 90, 2*3)`, [255, 90+2*3-1, 0, 255]);
+ }
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 0, 0, 1)`, [0, 0, 0, 0]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 0, 1*3, 0)`, [0, 0, 0, 0]);
+
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 0, 1*3, 1)`, [255, 1*3-1, 0, 255]);
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 0, 2*3, 1)`, [255, 2*3-1, 0, 255]);
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 0, 1*3, 2)`, [255, 1*3-1, 1, 255]);
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 0, 2*3, 2)`, [255, 2*3-1, 1, 255]);
+ if (ERRATA.FIRST_ADDS_TO_INSTANCE) {
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 90, 2*3, 2)`, [255, 90+2*3-1, 91, 255]);
+ } else {
+ fn(`gl.drawArraysInstanced(gl.TRIANGLES, 90, 2*3, 2)`, [255, 90+2*3-1, 1, 255]);
+ }
+
+ // -
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawElements(gl.TRIANGLES, 0*3, gl.UNSIGNED_INT, 4*0)`, [0, 0, 0, 0]);
+ fn(`gl.drawElements(gl.TRIANGLES, 1*3, gl.UNSIGNED_INT, 4*0)`, [255, 10+1*3-1, 0, 255]);
+ fn(`gl.drawElements(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, 4*0)`, [255, 10+2*3-1, 0, 255]);
+ fn(`gl.drawElements(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, 4*100)`, [255, 100+10+2*3-1, 0, 255]);
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 0*3, gl.UNSIGNED_INT, 4*0, 1)`, [0, 0, 0, 0]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 1*3, gl.UNSIGNED_INT, 4*0, 0)`, [0, 0, 0, 0]);
+
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 1*3, gl.UNSIGNED_INT, 4*0, 1)`, [255, 10+1*3-1, 0, 255]);
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, 4*0, 1)`, [255, 10+2*3-1, 0, 255]);
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 1*3, gl.UNSIGNED_INT, 4*0, 2)`, [255, 10+1*3-1, 1, 255]);
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, 4*0, 2)`, [255, 10+2*3-1, 1, 255]);
+ fn(`gl.drawElementsInstanced(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, 4*100, 2)`, [255, 100+10+2*3-1, 1, 255]);
+ }
+
+ finishTest();
+})();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/canvas-resizing-with-pbo-bound.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/canvas-resizing-with-pbo-bound.html
new file mode 100644
index 0000000000..713c88f515
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/canvas-resizing-with-pbo-bound.html
@@ -0,0 +1,111 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Resizing With PBO Bound 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas1" style="width: 256px; height: 256px;"> </canvas>
+<canvas id="canvas2" style="width: 256px; height: 256px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+
+description("Verifies that resizing the canvas (recreating the backing framebuffer) works correctly while a PBO is bound.");
+
+debug("");
+debug("Regression test for Chromium <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=644572'>Issue 644572</a>");
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas;
+var largeSize = 256;
+var smallSize = 128;
+var currentSize;
+var gl;
+var numFrames = 0;
+var testNumber = 0;
+var pbo;
+
+function nextTest() {
+ ++testNumber;
+ numFrames = 0;
+ currentSize = largeSize;
+ if (testNumber > 2) {
+ finishTest();
+ return;
+ }
+
+ canvas = document.getElementById("canvas" + testNumber);
+ canvas.width = currentSize;
+ canvas.height = currentSize;
+ var usePreserveDrawingBuffer = (testNumber == 1) ? true : false;
+ debug("Testing preserveDrawingBuffer = " + usePreserveDrawingBuffer);
+ gl = wtu.create3DContext(canvas, { preserveDrawingBuffer: usePreserveDrawingBuffer }, 2);
+
+ if (!gl) {
+ testFailed("context does not exist");
+
+ wtu.requestAnimFrame(nextTest);
+ } else {
+ testPassed("context exists");
+
+ gl.clearColor(0, 1, 0, 1);
+
+ pbo = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo);
+
+ wtu.requestAnimFrame(render);
+ }
+}
+
+function render() {
+ if (++numFrames < 4) {
+ if (currentSize == largeSize) {
+ canvas.height = smallSize;
+ currentSize = smallSize;
+ } else {
+ canvas.height = largeSize;
+ currentSize = largeSize;
+ }
+ }
+
+ gl.viewport(0, 0, largeSize, currentSize);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Check the four corners
+ var green = [ 0, 255, 0, 255 ];
+ var inset = 3;
+ wtu.checkCanvasRect(gl, inset, inset, 1, 1, green, "lower left should be green", 1);
+ wtu.checkCanvasRect(gl, largeSize - inset, inset, 1, 1, green, "lower right should be green", 1);
+ wtu.checkCanvasRect(gl, inset, currentSize - inset, 1, 1, green, "upper left should be green", 1);
+ wtu.checkCanvasRect(gl, largeSize - inset, currentSize - inset, 1, 1, green, "upper right should be green", 1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error");
+ if (gl.getParameter(gl.PIXEL_UNPACK_BUFFER_BINDING) != pbo) {
+ testFailed("Pixel unpack buffer binding was lost");
+ }
+
+ if (numFrames < 4) {
+ wtu.requestAnimFrame(render);
+ } else {
+ wtu.requestAnimFrame(nextTest);
+ }
+}
+
+wtu.requestAnimFrame(nextTest);
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-func-buffer-type-match.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-func-buffer-type-match.html
new file mode 100644
index 0000000000..8054d74df2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-func-buffer-type-match.html
@@ -0,0 +1,145 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test clear and clearBuffer functions have to match fbo's buffer format</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script>
+"use strict";
+description("This tests the WebGL2 specific constraint that clear or clearBuffer* functions have to be compatible with fbo's buffer format");
+
+var setupRenderbuffer = function(attachment, format) {
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, format, canvas.width, canvas.height);
+ return renderbuffer;
+}
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ debug("");
+ debug("Signed integer buffer");
+
+ var colorbuffer = setupRenderbuffer(gl.COLOR_ATTACHMENT0, gl.RGBA8);
+ var colorbuffer1 = setupRenderbuffer(gl.COLOR_ATTACHMENT1, gl.RGBA32I);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clear and INT buffer");
+
+ gl.clearBufferfv(gl.COLOR, 1, new Float32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferfv and INT buffer");
+
+ gl.clearBufferuiv(gl.COLOR, 1, new Uint32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferuiv and INT buffer");
+
+ debug("Set up draw buffer so INT buffer is set to NONE");
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clear and INT buffer is NONE");
+
+ gl.clearBufferfv(gl.COLOR, 1, new Float32Array(4));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBufferfv and INT buffer is NONE");
+
+ gl.clearBufferuiv(gl.COLOR, 0, new Uint32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferuiv and float buffer");
+
+ debug("");
+ debug("Unsigned integer buffer");
+
+ colorbuffer = setupRenderbuffer(gl.COLOR_ATTACHMENT0, gl.RGBA32UI);
+ colorbuffer1 = setupRenderbuffer(gl.COLOR_ATTACHMENT1, gl.RGBA8);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clear and UINT buffer");
+
+ gl.clearBufferfv(gl.COLOR, 0, new Float32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferfv and UINT buffer");
+
+ gl.clearBufferiv(gl.COLOR, 0, new Int32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferiv and UINT buffer");
+
+ debug("Set up draw buffer so INT buffer is set to NONE");
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clear and UINT buffer is NONE");
+
+ gl.clearBufferfv(gl.COLOR, 0, new Float32Array(4));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBufferfv and UINT buffer is NONE");
+
+ gl.clearBufferiv(gl.COLOR, 1, new Int32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferiv and float buffer");
+
+ debug("");
+ debug("Float buffer");
+
+ colorbuffer = setupRenderbuffer(gl.COLOR_ATTACHMENT0, gl.RGBA8);
+ var numAttachments = 1;
+ var ext = gl.getExtension("EXT_color_buffer_float");
+ var bufferType = "float buffer";
+ if (ext) {
+ debug("EXT_color_buffer_float is available: testing RGBA8 + RGBA32F");
+ colorbuffer1 = setupRenderbuffer(gl.COLOR_ATTACHMENT1, gl.RGBA32F);
+ ++numAttachments;
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ } else {
+ debug("EXT_color_buffer_float is unavailable: testing RGBA8");
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ bufferType = "RGBA8 buffer";
+ }
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clear and " + bufferType);
+
+ for (var ii = 0; ii < numAttachments; ++ii) {
+ gl.clearBufferfv(gl.COLOR, ii, new Float32Array(4));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBufferfv and " + bufferType);
+
+ gl.clearBufferiv(gl.COLOR, ii, new Int32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferiv and " + bufferType);
+
+ gl.clearBufferuiv(gl.COLOR, ii, new Uint32Array(4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "clearBufferuiv and " + bufferType);
+ }
+
+ gl.deleteFramebuffer(fb);
+ gl.deleteRenderbuffer(colorbuffer);
+ gl.deleteRenderbuffer(colorbuffer1);
+}
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-srgb-color-buffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-srgb-color-buffer.html
new file mode 100644
index 0000000000..b88518635e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-srgb-color-buffer.html
@@ -0,0 +1,89 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Clear sRGB Color Buffer</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of clearing srgb color buffer.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var tex = gl.createTexture();
+var fbo = gl.createFramebuffer();
+var size = 8;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ // Create a srgb color buffer
+ init();
+
+ clear_srgb_color_buffer(0);
+ clear_srgb_color_buffer(1);
+}
+
+function init() {
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ } else {
+ testPassed("framebuffer complete!");
+ }
+}
+
+function clear_srgb_color_buffer(iter) {
+ debug("");
+ debug("Clear sRGB color buffer through glClear or glClearBufferfv");
+
+ var color = [0x33, 0x88, 0xbb, 0xff];
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ if (iter == 0) {
+ gl.clearColor(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ } else {
+ var data = new Float32Array([color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255]);
+ gl.clearBufferfv(gl.COLOR, 0, data);
+ }
+
+ var color_ref = wtu.linearToSRGB(color);
+ var tolerance = 3;
+ var msg = "";
+ wtu.checkCanvasRect(gl, 0, 0, size, size, color_ref, msg, tolerance);
+}
+
+gl.bindTexture(gl.TEXTURE_2D, null);
+gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+gl.deleteTexture(tex);
+gl.deleteFramebuffer(fbo);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-and-draw.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-and-draw.html
new file mode 100644
index 0000000000..051066c8ea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-and-draw.html
@@ -0,0 +1,216 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test clearBuffer with drawing</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body onload="runTest()">
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="64" height="64" style="position:fixed;left:0;top:0"> </canvas>
+<script>
+"use strict";
+description("This tests the operation of clearBuffer followed by a draw call.");
+
+debug("Verifies that these combined with preserveDrawingBuffer's implicit clears work properly together.");
+debug("Regression test for <a href='http://crbug.com/828262'>Chromium bug 828262</a>.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl;
+var testIndex = 0;
+var iterations = 0;
+var maxIterations = 10;
+var prog;
+var tests;
+var stage = 0;
+var blackUint8 = [0, 0, 0, 255];
+var redFloat = [1.0, 0.0, 0.0, 0.0];
+var redUint8 = [255, 0, 0, 255];
+var greenFloat = [0.0, 1.0, 0.0, 0.0];
+var greenUint8 = [0, 255, 0, 255];
+
+function verifyOnePixel(kind, x, y, readFormat, readType, arrayType, expectedColor) {
+ var buffer = new arrayType(4);
+ gl.readPixels(Math.floor(x), Math.floor(y), 1, 1, readFormat, readType, buffer);
+ if (buffer[0] == expectedColor[0] &&
+ buffer[1] == expectedColor[1] &&
+ buffer[2] == expectedColor[2] &&
+ buffer[3] == expectedColor[3]) {
+ testPassed(kind + " succeeded");
+ } else {
+ testFailed(kind + " failed. Expected: " + expectedColor + ", got: " + buffer);
+ }
+}
+
+function testClearBufferAndDraw(test) {
+ gl.stencilFunc(gl.EQUAL, 0, 0xFF);
+ test['clear']();
+ wtu.setFloatDrawColor(gl, greenFloat);
+ wtu.drawUnitQuad(gl);
+ // Back buffer has no alpha channel.
+ let readFormat = gl.RGBA;
+ let readType = gl.UNSIGNED_BYTE;
+ if (stage == 2) {
+ verifyOnePixel("Clearing outside scissor",63, 63, readFormat, readType, Uint8Array, blackUint8);
+ verifyOnePixel("Drawing outside scissor", 40, 40, readFormat, readType, Uint8Array, blackUint8);
+ }
+ verifyOnePixel("Clearing", 0, 0, readFormat, readType, Uint8Array, test['bgColor']);
+ verifyOnePixel("Drawing", 32, 32, readFormat, readType, Uint8Array, test['drawColor']);
+}
+
+function runNextTest() {
+ if (testIndex >= tests.length) {
+ // Restore after the last clearBufferiv test
+ gl.enable(gl.DEPTH_TEST);
+ if (stage == 0) {
+ debug('');
+ debug('Enabling full-canvas scissor');
+ gl.enable(gl.SCISSOR_TEST);
+ } else if (stage == 1) {
+ debug('');
+ debug('Limiting scissor rect');
+ gl.scissor(0, 0, 33, 33);
+ } else if (stage == 2) {
+ finishTest();
+ return;
+ }
+ testIndex = 0;
+ stage++;
+ }
+
+
+ let test = tests[testIndex];
+ if (iterations == 0) {
+ debug('');
+ debug('Testing: ' + test['desc'])
+ }
+ testClearBufferAndDraw(test);
+
+ if (++iterations == maxIterations) {
+ iterations = 0;
+ ++testIndex;
+
+ // Clear to yellow between the tests to ensure that
+ // subsequent tests do not rely on past results.
+ gl.clearColor(1.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ }
+
+ wtu.waitForComposite(runNextTest);
+}
+
+function runTest() {
+ gl = wtu.create3DContext(canvas, { alpha: false, stencil: true }, 2);
+
+ if (!gl) {
+ testFailed("context does not exist");
+ return;
+ } else {
+ testPassed("context exists");
+ }
+
+ prog = wtu.setupColorQuad(gl, 0, { scale: 0.5 });
+
+ tests = [
+ {
+ desc: 'Implicit clear',
+ clear: function() {},
+ bgColor: blackUint8,
+ // The implicit clear clears depth to 1.0, and since the quad is
+ // drawn at a depth of 0.0, it's always discarded.
+ drawColor: blackUint8,
+ },
+ {
+ desc: 'clearBufferfi only',
+ clear: function() {
+ gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 0.0, 1);
+ gl.stencilFunc(gl.EQUAL, 1, 0xFF);
+ },
+ bgColor: blackUint8,
+ drawColor: greenUint8,
+ },
+ {
+ desc: 'clearBufferfv only',
+ clear: function() {
+ gl.clearBufferfv(gl.DEPTH, 0, [0.0]);
+ },
+ bgColor: blackUint8,
+ drawColor: greenUint8,
+ },
+ {
+ desc: 'clearBufferfv and clear',
+ clear: function() {
+ gl.clearBufferfv(gl.COLOR, 0, redFloat);
+ gl.clearDepth(0.0);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ },
+ bgColor: redUint8,
+ drawColor: greenUint8,
+ },
+ {
+ desc: 'clearBufferfv (no-op) and clear',
+ clear: function() {
+ gl.clearBufferfv(gl.COLOR, 1, greenFloat);
+ gl.clearDepth(0.0);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ },
+ bgColor: blackUint8,
+ drawColor: greenUint8,
+ },
+ {
+ desc: 'clearBuffer{fv} and {fi}',
+ clear: function() {
+ gl.clearBufferfv(gl.COLOR, 0, redFloat);
+ gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 0.0, 2);
+ gl.stencilFunc(gl.EQUAL, 2, 0xFF);
+ },
+ bgColor: redUint8,
+ drawColor: greenUint8,
+ },
+ {
+ desc: 'clearBufferiv only',
+ clear: function() {
+ gl.disable(gl.DEPTH_TEST);
+ gl.clearBufferiv(gl.STENCIL, 0, [3]);
+ gl.stencilFunc(gl.EQUAL, 3, 0xFF);
+ },
+ bgColor: blackUint8,
+ drawColor: greenUint8,
+ },
+ ];
+
+ // Clear canvas to something other than black to start.
+ gl.clearColor(0.0, 0.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.enable(gl.DEPTH_TEST);
+ // Unreal Engine's depth test is reversed from the
+ // default. Including the clear of the depth buffer in this test
+ // case highlights the rendering error more clearly, since neither
+ // the background nor any rendered object show up.
+ gl.depthFunc(gl.GEQUAL);
+
+ gl.enable(gl.STENCIL_TEST);
+
+ // Must run in a requestAnimationFrame loop to provoke implicit
+ // clears of the canvas.
+ wtu.waitForComposite(runNextTest);
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-sub-source.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-sub-source.html
new file mode 100644
index 0000000000..616d2bda4c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-sub-source.html
@@ -0,0 +1,110 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test clearBuffer functions with optional srcOffset argument</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script>
+"use strict";
+description("This tests clearBuffer* functions with optional srcOffset argument");
+
+function verifyOnePixel(readFormat, readType, arrayType, expectedColor) {
+ var buffer = new arrayType(4);
+ gl.readPixels(0, 0, 1, 1, readFormat, readType, buffer);
+ if (buffer[0] == expectedColor[0] &&
+ buffer[1] == expectedColor[1] &&
+ buffer[2] == expectedColor[2] &&
+ buffer[3] == expectedColor[3]) {
+ testPassed("clearBuffer sets the renderbuffer with the correct data");
+ } else {
+ testFailed("clearBuffer fails to work. Expected: " + expectedColor + ", got: " + buffer);
+ }
+}
+
+function testClearBuffer(func, format, arrayType, readFormat, readType) {
+ debug("");
+ debug("Testing " + func);
+
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, format, canvas.width, canvas.height);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ var srcData = new arrayType([1, 2, 3, 4, 5, 6]);
+ gl[func](gl.COLOR, 0, srcData);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBuffer with no srcOffset should succeed");
+ verifyOnePixel(readFormat, readType, arrayType, [1,2,3,4]);
+
+ gl[func](gl.COLOR, 0, srcData, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBuffer with srcOffset = 0 should succeed");
+ verifyOnePixel(readFormat, readType, arrayType, [1,2,3,4]);
+
+ gl[func](gl.COLOR, 0, srcData, 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBuffer with srcOffset = 2 should succeed");
+ verifyOnePixel(readFormat, readType, arrayType, [3,4, 5, 6]);
+
+ gl[func](gl.COLOR, 0, srcData, 4);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "clearBuffer with srcOffset = 4 should fail: out of bounds");
+
+ gl.deleteFramebuffer(fb);
+ gl.deleteRenderbuffer(renderbuffer);
+}
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ var testCases = [
+ {
+ func: "clearBufferiv", format: gl.RGBA32I, arrayType: Int32Array,
+ readFormat: gl.RGBA_INTEGER, readType: gl.INT,
+ },
+ {
+ func: "clearBufferuiv", format: gl.RGBA32UI, arrayType: Uint32Array,
+ readFormat: gl.RGBA_INTEGER, readType: gl.UNSIGNED_INT,
+ },
+ {
+ func: "clearBufferfv", format: gl.RGBA32F, arrayType: Float32Array,
+ readFormat: gl.RGBA, readType: gl.FLOAT,
+ extension: "EXT_color_buffer_float",
+ },
+ ];
+
+ for (var tt = 0; tt < testCases.length; ++tt) {
+ var test = testCases[tt];
+ if (test.extension && !gl.getExtension(test.extension))
+ continue;
+ testClearBuffer(test.func, test.format, test.arrayType, test.readFormat, test.readType);
+ }
+}
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbufferfv-with-alpha-false.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbufferfv-with-alpha-false.html
new file mode 100644
index 0000000000..a50b6f8e2f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbufferfv-with-alpha-false.html
@@ -0,0 +1,80 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test clearBufferfv with alpha:false canvas</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script>
+"use strict";
+description("This tests the operation of clearBufferfv with the back buffer of an alpha:false canvas.");
+
+function verifyOnePixel(readFormat, readType, arrayType, expectedColor) {
+ var buffer = new arrayType(4);
+ gl.readPixels(0, 0, 1, 1, readFormat, readType, buffer);
+ if (buffer[0] == expectedColor[0] &&
+ buffer[1] == expectedColor[1] &&
+ buffer[2] == expectedColor[2] &&
+ buffer[3] == expectedColor[3]) {
+ testPassed("clearBufferfv set the color buffer to the correct value");
+ } else {
+ testFailed("clearBufferfv failed to work. Expected: " + expectedColor + ", got: " + buffer);
+ }
+}
+
+function testClearBuffer(func, format, arrayType, readFormat, readType, readArrayType) {
+ debug("");
+ debug("Testing " + func);
+
+ var srcData = new arrayType([0, 1, 0, 0]);
+ gl[func](gl.COLOR, 0, srcData);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBuffer with no srcOffset should succeed");
+ // Back buffer has no alpha channel
+ verifyOnePixel(readFormat, readType, Uint8Array, [0, 255, 0, 255]);
+}
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, { alpha:false }, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ var testCases = [
+ {
+ func: "clearBufferfv", format: gl.RGBA, arrayType: Float32Array,
+ readFormat: gl.RGBA, readType: gl.UNSIGNED_BYTE, readArrayType: Uint8Array,
+ },
+ ];
+
+ for (var tt = 0; tt < testCases.length; ++tt) {
+ var test = testCases[tt];
+ if (test.extension && !gl.getExtension(test.extension))
+ continue;
+ testClearBuffer(test.func, test.format, test.arrayType,
+ test.readFormat, test.readType, test.readArrayType);
+ }
+}
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clipping-wide-points.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clipping-wide-points.html
new file mode 100644
index 0000000000..ab2457a6a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clipping-wide-points.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<title>Clipping wide points test</title>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="testbed" width="1" height="1"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/clipping-wide-points.js"></script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/depth-stencil-feedback-loop.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/depth-stencil-feedback-loop.html
new file mode 100644
index 0000000000..e7678017ee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/depth-stencil-feedback-loop.html
@@ -0,0 +1,165 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Rendering and Sampling Feedback Loop Tests for Depth/Stencil Buffer</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in highp vec4 aPosition;
+in vec2 aTexCoord;
+out vec2 texCoord;
+void main() {
+ gl_Position = aPosition;
+ texCoord = aTexCoord;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform sampler2D tex;
+in vec2 texCoord;
+out vec4 oColor;
+void main() {
+ oColor = texture(tex, texCoord);
+}
+</script>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of rendering to the same texture where it samples from.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var width = 8;
+var height = 8;
+var tex0;
+var tex1;
+var tex2;
+var fbo;
+var program;
+var positionLoc;
+var texCoordLoc;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ init();
+ detect_depth_stencil_feedback_loop();
+ deinit();
+}
+
+function init() {
+ // Setup program
+ program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['aPosition', 'aTexCoord'], [0, 1]);
+ positionLoc = gl.getAttribLocation(program, "aPosition");
+ texCoordLoc = gl.getAttribLocation(program, "aTexCoord");
+ if (!program || positionLoc < 0 || texCoordLoc < 0) {
+ testFailed("Set up program failed");
+ return;
+ }
+ testPassed("Set up program succeeded");
+
+ wtu.setupUnitQuad(gl, 0, 1);
+ gl.viewport(0, 0, width, height);
+
+ var texLoc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(texLoc, 0);
+
+ // Create textures and allocate storage
+ tex0 = gl.createTexture();
+ tex1 = gl.createTexture();
+ tex2 = gl.createTexture();
+ wtu.fillTexture(gl, tex0, width, height, [0x0, 0xff, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ wtu.fillTexture(gl, tex1, width, height, [0x80], 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, gl.DEPTH_COMPONENT16);
+ 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_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ wtu.fillTexture(gl, tex2, width, height, [0x40], 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, gl.DEPTH24_STENCIL8);
+ 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_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Succeed to create textures.");
+
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
+}
+
+function detect_depth_stencil_feedback_loop() {
+ // Test rendering and sampling feedback loop for depth buffer
+ gl.bindTexture(gl.TEXTURE_2D, tex1);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, tex1, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+ gl.enable(gl.DEPTH_TEST);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as depth buffer during rendering.");
+
+ gl.depthMask(gl.FALSE);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as depth buffer. A feedback loop is formed regardless of the status of depth mask.");
+
+ gl.depthMask(gl.TRUE);
+ gl.disable(gl.DEPTH_TEST);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as depth buffer. A feedback loop is formed regardless of whether the depth test is enabled.");
+
+ // Test rendering and sampling feedback loop for stencil buffer
+ gl.bindTexture(gl.TEXTURE_2D, tex2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, null, 0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, tex2, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ gl.enable(gl.STENCIL_TEST);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as stencil buffer during rendering.");
+
+ gl.stencilMask(0x0);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test sampls from a image. The same image is used as stencil buffer. A feedback loop is formed regardless of the status of stencil mask.");
+
+ gl.stencilMask(0xffff);
+ gl.disable(gl.STENCIL_TEST);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as stencil buffer. A feedback loop is formed regardless of whether the stencil test is enabled.");
+}
+
+function deinit() {
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteTexture(tex0);
+ gl.deleteTexture(tex1);
+ gl.deleteTexture(tex2);
+ gl.deleteFramebuffer(fbo);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-dirty-state-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-dirty-state-bug.html
new file mode 100644
index 0000000000..2b54d4c255
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-dirty-state-bug.html
@@ -0,0 +1,111 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Draw Buffers Dirty State Bug Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1, 0, 0, 1);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies a bug in draw buffers dirty state management in Chrome (crbug.com/678153).");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTest();
+
+ debug("");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runTest() {
+ debug("");
+
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position"]);
+ wtu.setupUnitQuad(gl);
+
+ var width = 2, height = 2;
+
+ var colorTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, colorTex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var depthTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, depthTex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT24, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
+
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup should cause no GL errors");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Clear and draw should cause no GL errors");
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [255, 0, 0, 255], "should be red");
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTex, 0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Clear and draw should cause no GL errors");
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, null, 0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
+
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [255, 0, 0, 255], "should be red");
+
+ gl.clearColor(0.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ // Previously in Chrome, switching around the attachments on a framebuffer
+ // affected a DrawBuffers cache that was maintained properly during draw
+ // calls, but not clears.
+ wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 0, 255], "should be green");
+
+ gl.deleteProgram(program);
+ gl.deleteFramebuffer(fb);
+ gl.deleteTexture(colorTex);
+ gl.deleteTexture(depthTex);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-driver-hang.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-driver-hang.html
new file mode 100644
index 0000000000..70a8360d6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-driver-hang.html
@@ -0,0 +1,187 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Draw Buffers Driver Hang Conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1, 0, 0, 1);
+}
+</script>
+<script>
+"use strict";
+description("This is a regression test for a driver bug causing a hang in the driver and thereby the browser (crbug.com/696187).")
+
+debug("Thanks to Andre Weissflog (@FlohOfWoe / @floooh) for this test.");
+debug("If the bug exists, this test doesn't fail or time out per the harness; the browser basically hangs.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, { depth: true, stencil: true, alpha: false }, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTest();
+}
+
+function runTest() {
+ // create a global VAO
+ let vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+
+ // create a 3 MSAA 'offscreen render targets', each consisting of:
+ // - 1 color texture which will hold the MSAA resolve result
+ // - 1 MSAA color renderbuffer
+ // plus one depth-stencil renderbuffer
+ let tex0 = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, tex0);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ 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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 200, 200, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ let c_rb0 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, c_rb0);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, 200, 200);
+ let ds_rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ds_rb);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.DEPTH24_STENCIL8, 200, 200);
+
+ // 2nd offscreen render target
+ let tex1 = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, tex1);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ 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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 200, 200, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ let c_rb1 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, c_rb1);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, 200, 200);
+
+ // 3rd offscreen render target
+ let tex2 = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, tex2);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ 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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 200, 200, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ let c_rb2 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, c_rb2);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, 200, 200);
+
+ // an MRT framebuffer with the 3 MSAA renderbuffers and MSAA depth/stencil attachments
+ let mrt_fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, mrt_fb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, c_rb0);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, c_rb1);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.RENDERBUFFER, c_rb2);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ds_rb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, ds_rb);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // 3 'MSAA resolve framebuffers' which are the target for the MSAA-resolve-blit,
+ // with the 3 color textures as color attachments
+ let res_fb0 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, res_fb0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ let res_fb1 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, res_fb1);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex1, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ let res_fb2 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, res_fb2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, tex2, 0);
+ let frameNumber = 0;
+
+ function draw() {
+ // draw one frame
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, 1024, 768);
+
+ //--- BEGIN: comment out the block begin BEGIN/END to make the demo run
+ // clear the 3 MSAA offscreen color renderbuffers and depth/stencil renderbuffer
+ gl.bindFramebuffer(gl.FRAMEBUFFER, mrt_fb);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
+ gl.viewport(0, 0, 200, 200);
+ gl.depthMask(true);
+ gl.clearBufferfv(gl.COLOR, 0, [0.25,0.0,0.0,1.0]);
+ gl.clearBufferfv(gl.COLOR, 1, [0.0,0.25,0.0,1.0]);
+ gl.clearBufferfv(gl.COLOR, 2, [0.0,0.0,0.25,1.0]);
+ gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // the MSAA resolve operation
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, mrt_fb);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, res_fb0);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ gl.blitFramebuffer(0, 0, 200, 200, 0, 0, 200, 200, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, res_fb1);
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ gl.blitFramebuffer(0, 0, 200, 200, 0, 0, 200, 200, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, res_fb2);
+ gl.readBuffer(gl.COLOR_ATTACHMENT2);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ gl.blitFramebuffer(0, 0, 200, 200, 0, 0, 200, 200, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+//--- END
+
+ // bind and clear the default framebuffer
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, 1024, 768);
+ gl.clearColor(0.5, 0.5, 0.5, 1.0);
+ gl.clearDepth(1.0);
+ gl.clearStencil(0);
+ gl.clear(gl.COLOR_BUFFER_BIT|gl.STENCIL_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
+
+ if (++frameNumber < 10) {
+ requestAnimationFrame(draw);
+ } else {
+ finishTest();
+ }
+ }
+
+ // Start the rendering loop
+ draw();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-sparse-output-locations.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-sparse-output-locations.html
new file mode 100644
index 0000000000..4c679df6a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-sparse-output-locations.html
@@ -0,0 +1,108 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Conformance Tests: Verify drawBuffers sparse output locations</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="1" height="1" style="width: 4px; height: 4px;"> </canvas>
+<div id="console"></div>
+
+<script id="vs" type="x-shader/x-vertex">#version 300 es
+void main() {
+ gl_PointSize = 100.0;
+ gl_Position = vec4(0, 0, 0, 1);
+}
+</script>
+
+<script id="fs" type="x-shader/x-fragment">#version 300 es
+// fragment shader only outputs to attachments 1 and 3
+precision highp float;
+layout(location = 1) out vec4 output1;
+layout(location = 3) out vec4 output2;
+void main()
+{
+ output1 = vec4(0.0, 1.0, 0.0, 1.0);
+ output2 = vec4(0.0, 0.0, 1.0, 1.0);
+}
+
+</script>
+<script>
+"use strict";
+description("This test verifies sparse output locations of fragment shaders render correctly");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ runTests();
+}
+
+function testAttachment(attachment, expected) {
+ gl.readBuffer(gl.COLOR_ATTACHMENT0 + attachment);
+ wtu.checkCanvas(gl, expected, `check COLOR_ATTACHMENT${attachment}`, 1);
+}
+
+function runTests() {
+ var program = wtu.setupProgram(gl, ["vs", "fs"]);
+ if (!program) {
+ testFailed("Set up program failed");
+ return;
+ }
+ gl.useProgram(program);
+
+ // create a framebuffer with 4 1x1 pixel color attachments
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ for (let i = 0; i < 4; ++i) {
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, tex, 0);
+ }
+
+ // draw only to the 1st and 3rd attachments
+ gl.drawBuffers([
+ gl.NONE,
+ gl.COLOR_ATTACHMENT1,
+ gl.NONE,
+ gl.COLOR_ATTACHMENT3,
+ ]);
+
+ // draw
+ gl.drawArrays(gl.POINTS, 0, 1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
+
+ // check we got the correct values
+ testAttachment(0, [0, 0, 0, 0]);
+ testAttachment(1, [0, 255, 0, 255]);
+ testAttachment(2, [0, 0, 0, 0]);
+ testAttachment(3, [0, 0, 255, 255]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from testing");
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers.html
new file mode 100644
index 0000000000..0e2ecb8f47
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers.html
@@ -0,0 +1,598 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Draw Buffers Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/webgl-draw-buffers-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+<script id="vshaderESSL3" type="x-shader/x-vertex">#version 300 es
+in vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+<script id="vshaderESSL1" type="x-shader/x-vertex">
+attribute vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform vec4 u_colors[$(numDrawingBuffers)];
+
+// Only one out variable - does not need explicit output layout (ESSL 3 section 4.3.8.2)
+out vec4 my_FragData[$(numDrawingBuffers)];
+void main() {
+$(assignUColorsToFragData)
+}
+</script>
+<script id="fshaderDiscard" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform vec4 u_colors[$(numDrawingBuffers)];
+uniform float u_zero;
+
+// Only one out variable - does not need explicit output layout (ESSL 3 section 4.3.8.2)
+out vec4 my_FragData[$(numDrawingBuffers)];
+void main() {
+$(assignUColorsToFragData)
+ if (u_zero < 1.0) {
+ discard;
+ }
+}
+</script>
+<script id="fshaderRed" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = vec4(1, 0, 0, 1);
+}
+</script>
+<script id="fshaderBlueESSL1" type="x-shader/x-fragment">
+precision mediump float;
+
+void main() {
+ gl_FragColor = vec4(0, 0, 1, 1);
+}
+</script>
+<script id="fshaderBuiltInConstEnabled" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+
+out vec4 my_FragColor;
+void main() {
+ my_FragColor = (gl_MaxDrawBuffers == $(numDrawingBuffers)) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the functionality of Multiple Render Targets.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var drawBuffersUtils;
+let fb;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ drawBuffersUtils = WebGLDrawBuffersUtils(gl);
+
+ if (testParameters()) {
+ runShadersTest();
+ runAttachmentTest();
+ runDrawTests();
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function createDrawBuffersProgram(scriptId, sub) {
+ var fsource = wtu.getScript(scriptId);
+ fsource = wtu.replaceParams(fsource, sub);
+ return wtu.setupProgram(gl, ["vshaderESSL3", fsource], ["a_position"], undefined, true);
+}
+
+function runShadersTest() {
+ debug("");
+ debug("test shaders");
+
+ var sub = {numDrawingBuffers: gl.getParameter(gl.MAX_DRAW_BUFFERS)};
+ var program = createDrawBuffersProgram("fshaderBuiltInConstEnabled", sub);
+ wtu.setupUnitQuad(gl);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+ gl.deleteProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function makeArray(size, value) {
+ var array = []
+ for (var ii = 0; ii < size; ++ii) {
+ array.push(value);
+ }
+ return array;
+}
+
+function runAttachmentTest() {
+ debug("");
+ debug("test attachment enabled");
+
+ var maxDrawingBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS);
+ var maxColorAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+
+ var tex = gl.createTexture();
+ fb = gl.createFramebuffer();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + maxColorAttachments, gl.TEXTURE_2D, tex, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "should not be able to attach pass the max attachment point: gl.COLOR_ATTACHMENT0 + " + maxColorAttachments);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + maxColorAttachments - 1, gl.TEXTURE_2D, tex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to attach to the max attachment point: gl.COLOR_ATTACHMENT0 + " + (maxColorAttachments - 1));
+ gl.drawBuffers(makeArray(maxDrawingBuffers, gl.NONE));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffers with array NONE of size " + maxColorAttachments);
+ var bufs = drawBuffersUtils.makeColorAttachmentArray(maxDrawingBuffers);
+ gl.drawBuffers(bufs);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffers with array attachments of size " + maxColorAttachments);
+ bufs[0] = gl.NONE;
+ gl.drawBuffers(bufs);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffers with mixed array attachments of size " + maxColorAttachments);
+ if (maxDrawingBuffers > 1) {
+ bufs[0] = gl.COLOR_ATTACHMENT1;
+ bufs[1] = gl.COLOR_ATTACHMENT0;
+ gl.drawBuffers(bufs);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be able to call drawBuffers with out of order attachments of size " + maxColorAttachments);
+ var bufs = drawBuffersUtils.makeColorAttachmentArray(Math.floor(maxDrawingBuffers / 2));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffers with short array of attachments of size " + bufs.length);
+ }
+
+ gl.deleteFramebuffer(fb);
+ gl.deleteTexture(tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+
+ debug("Testing drawBuffers and getParameter with bindFramebuffer, without drawing.");
+ fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0)", "gl.COLOR_ATTACHMENT0");
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0+1)", "gl.NONE");
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawBuffers([gl.NONE])");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0)", "gl.BACK");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0)", "gl.NONE");
+
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawBuffers([gl.NONE,gl.COLOR_ATTACHMENT0+1])");
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0)", "gl.NONE");
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0+1)", "gl.COLOR_ATTACHMENT0+1");
+
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawBuffers([gl.COLOR_ATTACHMENT0,gl.COLOR_ATTACHMENT0+1])");
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0)", "gl.COLOR_ATTACHMENT0");
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0+1)", "gl.COLOR_ATTACHMENT0+1");
+
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fb)");
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0)", "gl.BACK");
+}
+
+function makeColorByIndex(index) {
+ var low = (index - 1) % 15 + 1;
+ var high = (index - 1) / 15;
+
+ var zeroOrOne = function(v) {
+ return v ? 1 : 0;
+ };
+
+ var oneOrTwo = function(v) {
+ return v ? 2 : 1;
+ }
+
+ var makeComponent = function(b0, b1, b2) {
+ return Math.floor(255 * zeroOrOne(b0) / oneOrTwo(b1) / oneOrTwo(b2));
+ };
+ return [
+ makeComponent(low & (1 << 0), high & (1 << 0), high & (1 << 4)),
+ makeComponent(low & (1 << 1), high & (1 << 1), high & (1 << 5)),
+ makeComponent(low & (1 << 2), high & (1 << 2), high & (1 << 6)),
+ makeComponent(low & (1 << 3), high & (1 << 3), high & (1 << 7)),
+ ];
+}
+
+function runDrawTests() {
+ debug("");
+ debug("--------- draw tests -----------");
+ var fb = gl.createFramebuffer();
+ var fb2 = gl.createFramebuffer();
+ var halfFB1 = gl.createFramebuffer();
+ var halfFB2 = gl.createFramebuffer();
+ var endsFB = gl.createFramebuffer();
+ var middleFB = gl.createFramebuffer();
+
+ var maxDrawingBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS);
+ var maxUsable = drawBuffersUtils.getMaxUsableColorAttachments();
+ var half = Math.floor(maxUsable / 2);
+ var bufs = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
+ var nones = makeArray(maxUsable, gl.NONE);
+
+ [fb, fb2, halfFB1, halfFB2, endsFB, middleFB].forEach(function(fbo) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.drawBuffers(bufs);
+ });
+
+ var checkProgram = wtu.setupTexturedQuad(gl);
+ var redProgram = wtu.setupProgram(gl, ["vshaderESSL3", "fshaderRed"], ["a_position"]);
+ var blueProgramESSL1 = wtu.setupProgram(gl, ["vshaderESSL1", "fshaderBlueESSL1"], ["a_position"]);
+
+ var assignCode = [];
+ for (var i = 0; i < maxDrawingBuffers; ++i) {
+ assignCode.push(" my_FragData[" + i + "] = u_colors[" + i + "];");
+ }
+
+ var drawProgram = createDrawBuffersProgram("fshader",
+ {numDrawingBuffers: maxDrawingBuffers, assignUColorsToFragData: assignCode.join("\n")});
+ var width = 64;
+ var height = 64;
+ var attachments = [];
+ // Makes 6 framebuffers.
+ // fb and fb2 have all the attachments.
+ // halfFB1 has the first half of the attachments
+ // halfFB2 has the second half of the attachments
+ // endsFB has the first and last attachments
+ // middleFB has all but the first and last attachments
+ for (var ii = 0; ii < maxUsable; ++ii) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ 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.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + ii, gl.TEXTURE_2D, tex, 0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + ii, gl.TEXTURE_2D, tex, 0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ii < half ? halfFB1 : halfFB2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + ii, gl.TEXTURE_2D, tex, 0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, (ii == 0 || ii == (maxUsable - 1)) ? endsFB : middleFB);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + ii, gl.TEXTURE_2D, tex, 0);
+ var location = gl.getUniformLocation(drawProgram, "u_colors[" + ii + "]");
+ var color = makeColorByIndex(ii + 1);
+ var floatColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255];
+ gl.uniform4fv(location, floatColor);
+ attachments.push({
+ texture: tex,
+ color: color
+ });
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+
+ var drawAndCheckAttachments = function(testFB, msg, testFn) {
+ debug("test clearing " + msg);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, testFB);
+
+ attachments.forEach(function(attachment, index) {
+ debug("attachment: " + index + " = " + wtu.glEnumToString(gl, gl.getParameter(gl.DRAW_BUFFER0 + index)) +
+ ", " + wtu.glEnumToString(gl, gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + index, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)));
+ });
+
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ debug("framebuffer not complete");
+ debug("");
+ return;
+ }
+
+ // Clear all the attachments
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ //drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ // return [0, 0, 0, 0];
+ //});
+ //debug("--");
+
+ // Clear some attachments using testFB
+ gl.bindFramebuffer(gl.FRAMEBUFFER, testFB);
+
+ gl.clearColor(0, 1, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return testFn(attachment, index) ? [0, 255, 0, 255] : [0, 0, 0, 0];
+ });
+
+ debug("test drawing to " + msg);
+
+ // Draw to some attachments using testFB
+ gl.useProgram(drawProgram);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, testFB);
+ wtu.drawUnitQuad(gl);
+
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return testFn(attachment, index) ? attachment.color : [0, 0, 0, 0];
+ });
+ };
+
+ gl.useProgram(drawProgram);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.drawBuffers(bufs);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+
+ wtu.drawUnitQuad(gl);
+
+ debug("test that each texture got the correct color.");
+
+ drawBuffersUtils.checkAttachmentsForColor(attachments);
+
+ debug("test clearing clears all the textures");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.clearColor(0, 1, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
+
+ debug("test that NONE draws nothing");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(nones);
+ gl.useProgram(redProgram);
+ wtu.clearAndDrawUnitQuad(gl);
+
+ drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
+
+ // GLES3 spec section 3.9.2 Shader Outputs
+ debug("test that gl_FragColor only writes to color number zero");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+ gl.useProgram(blueProgramESSL1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Active draw buffers with missing frag outputs.");
+ gl.enable(gl.RASTERIZER_DISCARD);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors when RASTERIZER_DISCARD is enabled.");
+ gl.disable(gl.RASTERIZER_DISCARD);
+ gl.colorMask(false, false, false, false);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors when all 4 channels of color mask are disabled.");
+ gl.colorMask(false, true, false, false);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "partially diabled color mask shall have no impact.");
+ gl.colorMask(true, true, true, true);
+
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ wtu.drawUnitQuad(gl);
+
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return (index == 0) ? [0, 0, 255, 255] : [0, 255, 0, 255];
+ });
+
+ // If there is only a single output, the location defaults to zero if not specified.
+ // See GLSL ES Spec 3.00.4, Section 4.3.8.2, Output Layout Qualifiers.
+ debug("test that an OpenGL ES Shading Language 3.00 shader with a single output color defaults to color number zero");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+ gl.useProgram(redProgram);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Active draw buffers with missing frag outputs.");
+
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ wtu.drawUnitQuad(gl);
+
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return (index == 0) ? [255, 0, 0, 255] : [0, 255, 0, 255];
+ });
+
+ if (maxUsable > 1) {
+ // Prepare for following tests by clearing all attachments to red.
+ debug("prepare by clearing all attachments to red");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
+
+ var bufs1 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
+ var bufs2 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
+ for (var ii = 0; ii < maxUsable; ++ii) {
+ if (ii < half) {
+ bufs1[ii] = gl.NONE;
+ } else {
+ bufs2[ii] = gl.NONE;
+ }
+ }
+
+ debug("test setting first half to NONE and clearing");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs1);
+ gl.clearColor(0, 1, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return index < half ? [255, 0, 0, 255] : [0, 255, 0, 255];
+ });
+
+ debug("test setting first half to NONE and drawing");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.useProgram(drawProgram);
+ wtu.drawUnitQuad(gl);
+
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return index < half ? [255, 0, 0, 255] : attachment.color;
+ });
+
+ debug("test setting second half to NONE and clearing");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawBuffers(bufs2);
+ gl.clearColor(0, 0, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return index < half ? [0, 0, 255, 255] : [255, 0, 0, 255];
+ });
+
+ debug("test setting second half to NONE and drawing");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.useProgram(drawProgram);
+ wtu.drawUnitQuad(gl);
+
+ drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
+ return index < half ? attachment.color : [255, 0, 0, 255];
+ });
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, halfFB1);
+ gl.drawBuffers(bufs);
+ drawAndCheckAttachments(
+ halfFB1, "framebuffer that only has first half of attachments",
+ function(attachment, index) {
+ return index < half;
+ });
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, halfFB2);
+ gl.drawBuffers(bufs);
+ drawAndCheckAttachments(
+ halfFB2, "framebuffer that only has second half of attachments",
+ function(attachment, index) {
+ return index >= half;
+ });
+
+ if (maxUsable > 2) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, endsFB);
+ gl.drawBuffers(bufs);
+ drawAndCheckAttachments(
+ endsFB, "framebuffer that only has first and last attachments",
+ function(attachment, index) {
+ return index == 0 || index == (maxUsable - 1);
+ });
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, middleFB);
+ gl.drawBuffers(bufs);
+ drawAndCheckAttachments(
+ middleFB,
+ "framebuffer that has all but the first and last attachments",
+ function(attachment, index) {
+ return index != 0 && index != (maxUsable - 1);
+ });
+ }
+ }
+
+ debug("test switching between fbos keeps drawbuffer state");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.drawBuffers(nones);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.useProgram(drawProgram);
+ wtu.drawUnitQuad(gl);
+ drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.useProgram(drawProgram);
+ wtu.drawUnitQuad(gl);
+ drawBuffersUtils.checkAttachmentsForColor(attachments);
+
+ debug("test that none of the attachments are written in case the fragment shader discards");
+ var discardProgram = createDrawBuffersProgram("fshaderDiscard",
+ {numDrawingBuffers: maxDrawingBuffers, assignUColorsToFragData: assignCode.join("\n")});
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.drawBuffers(bufs);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.useProgram(discardProgram);
+ wtu.drawUnitQuad(gl);
+ drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 0, 0, 0]);
+
+ debug("test queries");
+ debug("check framebuffer with all attachments on");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ for (var ii = 0; ii < maxUsable; ++ii) {
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0 + " + ii + ")", "gl.COLOR_ATTACHMENT0 + " + ii);
+ }
+
+ debug("check framebuffer with all attachments off");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ for (var ii = 0; ii < maxUsable; ++ii) {
+ shouldBe("gl.getParameter(gl.DRAW_BUFFER0 + " + ii + ")", "gl.NONE");
+ }
+
+ // WebGL generates FRAMEBUFFER_INCOMPLETE_DIMENSIONS when attached images have different sizes.
+ // This behavior differs from GLES 3.
+ debug("");
+ debug("test attachment size mis-match");
+ gl.bindTexture(gl.TEXTURE_2D, attachments[0].texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width * 2, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
+
+ // TODO: Rendering when framebuffer attachments have mismatched size should be tested, maybe in a separate test.
+
+ gl.deleteFramebuffer(fb);
+ gl.deleteFramebuffer(fb2);
+ gl.deleteFramebuffer(halfFB1);
+ gl.deleteFramebuffer(halfFB2);
+ attachments.forEach(function(attachment) {
+ gl.deleteTexture(attachment.texture);
+ });
+ gl.deleteProgram(checkProgram);
+ gl.deleteProgram(redProgram);
+ gl.deleteProgram(drawProgram);
+}
+
+function testParameters() {
+ debug("");
+ debug("check that MAX_DRAW_BUFFERS and MAX_COLOR_ATTACHMENTS are valid");
+ var maxDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS);
+ var maxColorAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
+ debug("MAX_DRAW_BUFFERS = " + maxDrawBuffers);
+ debug("MAX_COLOR_ATTACHMENTS = " + maxColorAttachments);
+ if (maxDrawBuffers != maxColorAttachments) {
+ testFailed("MAX_DRAW_BUFFERS and MAX_COLOR_ATTACHMENTS should be the same");
+ return false;
+ }
+ if (maxDrawBuffers < 4) {
+ testFailed("MAX_DRAW_BUFFERS should be at least 4");
+ return false;
+ }
+ return true;
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-with-integer-texture-base-level.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-with-integer-texture-base-level.html
new file mode 100644
index 0000000000..e2f9fd13c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-with-integer-texture-base-level.html
@@ -0,0 +1,65 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Draw With Integer Texture Base Level Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/tests/tex-image-and-sub-image-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var canvas;
+var wtu = WebGLTestUtils;
+canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+var tiu = TexImageUtils;
+
+// Both Chrome and Firefox fail on this test on NVIDIA Windows, see crbug.com/679639.
+function testDrawIntegerTextureBaseLevel()
+{
+ description("This test verifies the functionality of rendering with integer texture non-zero base level.");
+
+ var green = [0, 255, 0, 255];
+
+ var width = 16;
+ var height = 16;
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+
+ var texture = gl.createTexture();
+ var level = 1;
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ 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_BASE_LEVEL, level);
+ wtu.fillTexture(gl, texture, width, height, green, level, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, gl.RGBA8UI);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var program = tiu.setupTexturedQuad(gl, "RGBA8UI");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ wtu.checkCanvas(gl, green);
+}
+
+testDrawIntegerTextureBaseLevel();
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/element-index-uint.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/element-index-uint.html
new file mode 100644
index 0000000000..123254f4cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/element-index-uint.html
@@ -0,0 +1,432 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Uint element indices Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+
+<script id="vs" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec4 vColor;
+varying vec4 color;
+void main() {
+ gl_Position = vPosition;
+ color = vColor;
+}
+</script>
+<script id="fs" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 color;
+void main() {
+ gl_FragColor = color;
+}
+</script>
+<script id="vsCheckOutOfBounds" type="x-shader/x-vertex">
+ precision mediump float;
+ attribute vec2 position;
+ attribute vec4 vecRandom;
+ varying vec4 v_color;
+
+ // Per the spec, each component can either contain existing contents
+ // of the buffer or 0.
+ bool testFloatComponent(float component) {
+ return (component == 0.2 || component == 0.0);
+ }
+ // The last component is additionally allowed to be 1.0.
+ bool testLastFloatComponent(float component) {
+ return testFloatComponent(component) || component == 1.0;
+ }
+
+ void main() {
+ if (testFloatComponent(vecRandom.x) &&
+ testFloatComponent(vecRandom.y) &&
+ testFloatComponent(vecRandom.z) &&
+ testLastFloatComponent(vecRandom.w)) {
+ v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- Out of range
+ } else {
+ v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value
+ }
+ gl_Position = vec4(position, 0.0, 1.0);
+ }
+</script>
+
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the Uint element indices.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = null;
+var canvas = null;
+
+// Test both STATIC_DRAW and DYNAMIC_DRAW as a regression test
+// for a bug in ANGLE which has since been fixed.
+for (var ii = 0; ii < 2; ++ii) {
+ canvas = document.createElement("canvas");
+ canvas.width = 50;
+ canvas.height = 50;
+
+ gl = wtu.create3DContext(canvas, null, 2);
+
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ } else {
+ testPassed("WebGL context exists");
+
+ var drawType = (ii == 0) ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW;
+ debug("Testing " + ((ii == 0) ? "STATIC_DRAW" : "DYNAMIC_DRAW"));
+
+ runDrawTests(drawType);
+
+ // These tests are tweaked duplicates of the buffers/index-validation* tests
+ // using unsigned int indices to ensure that behavior remains consistent
+ runIndexValidationTests(drawType);
+ runIndexOutOfRangeTests(drawType);
+ runResizedBufferTests(drawType);
+ runCrashWithBufferSubDataTests(drawType);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+ }
+}
+
+function runDrawTests(drawType) {
+ debug("Test that draws with unsigned integer indices produce the expected results");
+
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+
+ var program = wtu.setupNoTexCoordTextureProgram(gl);
+
+ function setupDraw(s) {
+ // Create a vertex buffer that cannot be fully indexed via shorts
+ var quadArrayLen = 65537 * 3;
+ var quadArray = new Float32Array(quadArrayLen);
+
+ // Leave all but the last 4 values zero-ed out
+ var idx = quadArrayLen - 12;
+
+ // Initialized the last 4 values to a quad
+ quadArray[idx++] = 1.0 * s;
+ quadArray[idx++] = 1.0 * s;
+ quadArray[idx++] = 0.0;
+
+ quadArray[idx++] = -1.0 * s;
+ quadArray[idx++] = 1.0 * s;
+ quadArray[idx++] = 0.0;
+
+ quadArray[idx++] = -1.0 * s;
+ quadArray[idx++] = -1.0 * s;
+ quadArray[idx++] = 0.0;
+
+ quadArray[idx++] = 1.0 * s;
+ quadArray[idx++] = -1.0 * s;
+ quadArray[idx++] = 0.0;
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, quadArray, drawType);
+
+ // Create an unsigned int index buffer that indexes the last 4 vertices
+ var baseIndex = (quadArrayLen / 3) - 4;
+
+ var indexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([
+ baseIndex + 0,
+ baseIndex + 1,
+ baseIndex + 2,
+ baseIndex + 2,
+ baseIndex + 3,
+ baseIndex + 0]), drawType);
+
+ var opt_positionLocation = 0;
+ gl.enableVertexAttribArray(opt_positionLocation);
+ gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
+ };
+ function readLocation(x, y) {
+ var pixels = new Uint8Array(1 * 1 * 4);
+ gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ return pixels;
+ };
+ function testPixel(blockList, allowList) {
+ function testList(list, expected) {
+ for (var n = 0; n < list.length; n++) {
+ var l = list[n];
+ var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2;
+ var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2;
+ var source = readLocation(x, y);
+ if (Math.abs(source[0] - expected) > 2) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return testList(blockList, 0) && testList(allowList, 255);
+ };
+ function verifyDraw(drawNumber, s) {
+ gl.clearColor(1.0, 1.0, 1.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
+
+ var blockList = [];
+ var allowList = [];
+ var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0];
+ for (var n = 0; n < points.length; n++) {
+ if (points[n] <= s) {
+ blockList.push(points[n]);
+ } else {
+ allowList.push(points[n]);
+ }
+ }
+ if (testPixel(blockList, allowList)) {
+ testPassed("Draw " + drawNumber + " passed pixel test");
+ } else {
+ testFailed("Draw " + drawNumber + " failed pixel test");
+ }
+ };
+
+ setupDraw(0.5);
+ verifyDraw(0, 0.5);
+}
+
+function runIndexValidationTests(drawType) {
+ description("Tests that index validation verifies the correct number of indices");
+
+ function sizeInBytes(type) {
+ switch (type) {
+ case gl.BYTE:
+ case gl.UNSIGNED_BYTE:
+ return 1;
+ case gl.SHORT:
+ case gl.UNSIGNED_SHORT:
+ return 2;
+ case gl.INT:
+ case gl.UNSIGNED_INT:
+ case gl.FLOAT:
+ return 4;
+ default:
+ throw "unknown type";
+ }
+ }
+
+ var program = wtu.loadStandardProgram(gl);
+
+ // 3 vertices => 1 triangle, interleaved data
+ var dataComplete = new Float32Array([0, 0, 0, 1,
+ 0, 0, 1,
+ 1, 0, 0, 1,
+ 0, 0, 1,
+ 1, 1, 1, 1,
+ 0, 0, 1]);
+ var dataIncomplete = new Float32Array([0, 0, 0, 1,
+ 0, 0, 1,
+ 1, 0, 0, 1,
+ 0, 0, 1,
+ 1, 1, 1, 1]);
+ var indices = new Uint32Array([0, 1, 2]);
+
+ debug("Testing with valid indices");
+
+ var bufferComplete = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufferComplete);
+ gl.bufferData(gl.ARRAY_BUFFER, dataComplete, drawType);
+ var elements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
+ gl.useProgram(program);
+ var vertexLoc = gl.getAttribLocation(program, "a_vertex");
+ var normalLoc = gl.getAttribLocation(program, "a_normal");
+ gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
+ gl.enableVertexAttribArray(vertexLoc);
+ gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
+ gl.enableVertexAttribArray(normalLoc);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var bufferIncomplete = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufferIncomplete);
+ gl.bufferData(gl.ARRAY_BUFFER, dataIncomplete, drawType);
+ gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
+ gl.enableVertexAttribArray(vertexLoc);
+ gl.disableVertexAttribArray(normalLoc);
+ debug("Enable vertices, valid");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ debug("Test with enabled attribute that does not belong to current program");
+
+ gl.disableVertexAttribArray(normalLoc);
+ var extraLoc = Math.max(vertexLoc, normalLoc) + 1;
+ gl.enableVertexAttribArray(extraLoc);
+ debug("Enable an extra attribute with null");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
+ debug("Enable an extra attribute with insufficient data buffer");
+ gl.vertexAttribPointer(extraLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+ debug("Pass large negative index to vertexAttribPointer");
+ gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), -2000000000 * sizeInBytes(gl.FLOAT));
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
+ shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
+}
+
+function runIndexOutOfRangeTests(drawType) {
+ debug("Testing with out-of-range indices");
+
+ var bufferPos = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufferPos);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ 1.0, 1.0,
+ -1.0, 1.0,
+ -1.0, -1.0,
+ 1.0, -1.0]), drawType);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+ var bufferIncomplete = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufferIncomplete);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]), drawType);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);
+
+ var glProgram = wtu.setupProgram(gl, ["vsCheckOutOfBounds", wtu.simpleVertexColorFragmentShader], ["position", "vecRandom"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Shader and buffer setup successfully");
+
+ var indices = new Uint32Array([0, 1, 2, 0, 2, 3]);
+ var elements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
+
+ gl.clearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+
+
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
+ var error = gl.getError();
+ if (error === gl.INVALID_OPERATION) {
+ testPassed("drawElements flagged INVALID_OPERATION, which is valid so long as all canvas pixels were not touched.");
+ wtu.checkCanvas(gl, [0, 0, 255, 255]);
+ } else if (error === gl.NO_ERROR) {
+ testPassed("drawElements flagged NO_ERROR, which is valid so long as all canvas pixels are green.");
+ wtu.checkCanvas(gl, [0, 255, 0, 255]);
+ } else {
+ testFailed("Invalid error flagged by drawElements. Should be INVALID_OPERATION or NO_ERROR");
+ }
+
+ debug("Test that client data is always copied during bufferData and bufferSubData calls");
+
+ indices[5] = 1;
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
+ var error = gl.getError();
+ if (error === gl.INVALID_OPERATION) {
+ testPassed("drawElements flagged INVALID_OPERATION, which is valid so long as all canvas pixels were not touched.");
+ wtu.checkCanvas(gl, [0, 0, 255, 255]);
+ } else if (error === gl.NO_ERROR) {
+ testPassed("drawElements flagged NO_ERROR, which is valid so long as all canvas pixels are green.");
+ wtu.checkCanvas(gl, [0, 255, 0, 255]);
+ } else {
+ testFailed("Invalid error flagged by drawElements. Should be INVALID_OPERATION or NO_ERROR");
+ }
+}
+
+function runResizedBufferTests(drawType) {
+ debug("Test that updating the size of a vertex buffer is properly noticed by the WebGL implementation.");
+
+ var program = wtu.setupProgram(gl, ["vs", "fs"], ["vPosition", "vColor"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after initialization");
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
+ [-1,1,0, 1,1,0, -1,-1,0,
+ -1,-1,0, 1,1,0, 1,-1,0]), drawType);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex setup");
+
+ var texCoordObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
+ [0,0, 1,0, 0,1,
+ 0,1, 1,0, 1,1]), drawType);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coord setup");
+
+ // Now resize these buffers because we want to change what we're drawing.
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ -1,1,0, 1,1,0, -1,-1,0, 1,-1,0,
+ -1,1,0, 1,1,0, -1,-1,0, 1,-1,0]), drawType);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex redefinition");
+ gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255]), drawType);
+ gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coordinate / color redefinition");
+
+ var numQuads = 2;
+ var indices = new Uint32Array(numQuads * 6);
+ for (var ii = 0; ii < numQuads; ++ii) {
+ var offset = ii * 6;
+ var quad = (ii == (numQuads - 1)) ? 4 : 0;
+ indices[offset + 0] = quad + 0;
+ indices[offset + 1] = quad + 1;
+ indices[offset + 2] = quad + 2;
+ indices[offset + 3] = quad + 2;
+ indices[offset + 4] = quad + 1;
+ indices[offset + 5] = quad + 3;
+ }
+ var indexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices");
+ gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_INT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
+}
+
+function runCrashWithBufferSubDataTests(drawType) {
+ debug('Verifies that the index validation code which is within bufferSubData does not crash.')
+
+ var elementBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 256, drawType);
+ var data = new Uint32Array(127);
+ gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 64, data);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "after attempting to update a buffer outside of the allocated bounds");
+ testPassed("bufferSubData, when buffer object was initialized with null, did not crash");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-draw-framebuffer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-draw-framebuffer.html
new file mode 100644
index 0000000000..1c0709e0b8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-draw-framebuffer.html
@@ -0,0 +1,74 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test draw framebuffer completeness when an incomplete framebuffer is bound to read framebuffer</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+// This exposes a bug in Chrome 67: If the read framebuffer is incomplete, then draw can fail even if the draw framebuffer is complete.
+// http://anglebug.com/2737
+
+"use strict";
+description();
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ var incompleteFb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, incompleteFb);
+ var incompleteTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, incompleteTex);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, incompleteTex, 0);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT');
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ var testProgram = wtu.setupSimpleColorProgram(gl, 0);
+
+ // If this is changed to gl.FRAMEBUFFER, the rendering succeeds on Chrome 67.
+ var drawFbTarget = gl.DRAW_FRAMEBUFFER;
+
+ var completeFb = gl.createFramebuffer();
+ gl.bindFramebuffer(drawFbTarget, completeFb);
+ var completeTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, completeTex);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 128, 128);
+ gl.framebufferTexture2D(drawFbTarget, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, completeTex, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error after setup");
+
+ shouldBe('gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER)', 'gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT');
+ shouldBe('gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.viewport(0, 0, 128, 128);
+ gl.uniform4f(gl.getUniformLocation(testProgram, 'u_color'), 0, 1, 0, 1);
+ wtu.drawUnitQuad(gl);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error after draw");
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, completeFb);
+ wtu.checkCanvasRect(gl, 0, 0, 128, 128, [0, 255, 0, 255], 'should be green', 2);
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-unaffected.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-unaffected.html
new file mode 100644
index 0000000000..74b6106419
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-unaffected.html
@@ -0,0 +1,89 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test drawBuffers, readBuffer, and fbo completeness</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="20" height="20"> </canvas>
+<script>
+// In MacOSX, if drawBuffers() and readBuffer() both select an attachment with no image attached,
+// fbo becomes incomplete. However, drawBuffers() and readBuffer() should not affect fbo completeness.
+
+"use strict";
+description("This tests drawBuffers, readBuffer, and fbo completeness");
+
+var setupRenderbuffer = function(attachment) {
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, canvas.width, canvas.height);
+ return renderbuffer;
+}
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ var fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ debug("fbo with two color images attached should be complete");
+ var colorbuffer = setupRenderbuffer(gl.COLOR_ATTACHMENT0);
+ var colorbuffer1 = setupRenderbuffer(gl.COLOR_ATTACHMENT1);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ debug("drawBuffers selects ATTACHMENT1, fbo should be complete");
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ debug("remove image attached to ATTACHMENT1, fbo should be complete");
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, null);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ debug("set read buffer to ATTACHMENT1, fbo should be complete");
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ debug("drawBuffers selects ATTACHMENT0, fbo should be complete");
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ debug("drawBuffers selects ATTACHMENT1, fbo should be complete");
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ debug("set read buffer to ATTACHMENT0, fbo should be complete");
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+
+ gl.deleteFramebuffer(fb);
+ gl.deleteRenderbuffer(colorbuffer);
+ gl.deleteRenderbuffer(colorbuffer1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no error after setup and clear render buffer");
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-mismatched-attachment-targets.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-mismatched-attachment-targets.html
new file mode 100644
index 0000000000..a8a28d6444
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-mismatched-attachment-targets.html
@@ -0,0 +1,162 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 can render to framebuffer attachments with different targets</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+void main(void) {
+ gl_Position = vec4(-0.5, -0.5, 0, 1);
+ gl_PointSize = 1.0;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 outColor;
+void main() {
+ outColor = vec4(0, 1, 0, 1);
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="1", height="1"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+description("Test framebuffer attachments with different targets");
+
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext("example", undefined, 2);
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+function newResource(target, mipLevels, format, size) {
+ let ret;
+ switch (target) {
+ case gl.RENDERBUFFER: {
+ ret = gl.createRenderbuffer();
+ ret.mips = [ ret ];
+ for (let i = 1; i < mipLevels; i++) {
+ ret.mips.push(gl.createRenderbuffer());
+ }
+ for (const i in ret.mips) {
+ const rb = ret.mips[i];
+ gl.bindRenderbuffer(target, rb);
+ gl.renderbufferStorage(target, format, size>>i, size>>i);
+ }
+ ret.attach = (attachEnum, mipLevel) => {
+ const rb = ret.mips[mipLevel];
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachEnum, gl.RENDERBUFFER, rb);
+ };
+ break;
+ }
+ case gl.TEXTURE_2D:
+ case gl.TEXTURE_CUBE_MAP: {
+ ret = gl.createTexture();
+ gl.bindTexture(target, ret);
+ gl.texStorage2D(target, mipLevels, format, size, size);
+ let imageTarget = target;
+ if (imageTarget == gl.TEXTURE_CUBE_MAP) {
+ imageTarget = gl.TEXTURE_CUBE_MAP_POSITIVE_X+2; // Deliberately don't choose the first image.
+ }
+ ret.attach = (attachEnum, mipLevel) => {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachEnum, imageTarget, ret, mipLevel);
+ };
+ break;
+ }
+ case gl.TEXTURE_3D:
+ case gl.TEXTURE_2D_ARRAY: {
+ ret = gl.createTexture();
+ gl.bindTexture(target, ret);
+ gl.texStorage3D(target, mipLevels, format, size, size, 1);
+ ret.attach = (attachEnum, mipLevel) => {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, attachEnum, ret, mipLevel, 0);
+ };
+ break;
+ }
+ default:
+ throw new Error();
+ }
+ ret.target = wtu.glEnumToString(gl, target);
+ ret.format = wtu.glEnumToString(gl, format);
+ return ret;
+}
+
+function runTest() {
+ const MIP_LEVELS = 2;
+ const SIZE = 2;
+
+ gl.clearColor(1, 0, 0, 1);
+
+ const program = wtu.setupProgram(gl, ['vshader','fshader'], [], console.log.bind(console));
+ gl.useProgram(program);
+
+ const colorResList = [
+ newResource(gl.RENDERBUFFER, MIP_LEVELS, gl.RGBA8, SIZE),
+ newResource(gl.TEXTURE_2D, MIP_LEVELS, gl.RGBA8, SIZE),
+ newResource(gl.TEXTURE_CUBE_MAP, MIP_LEVELS, gl.RGBA8, SIZE),
+ newResource(gl.TEXTURE_3D, MIP_LEVELS, gl.RGBA8, SIZE),
+ newResource(gl.TEXTURE_2D_ARRAY, MIP_LEVELS, gl.RGBA8, SIZE),
+ ];
+
+ const depthResList = [
+ newResource(gl.RENDERBUFFER, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
+ newResource(gl.TEXTURE_2D, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
+ newResource(gl.TEXTURE_CUBE_MAP, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
+ //newResource(gl.TEXTURE_3D, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE), // Depth formats forbidden for TEXTURE_3D.
+ newResource(gl.TEXTURE_2D_ARRAY, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
+ ];
+
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ for (const color of colorResList) {
+ for (const depth of depthResList) {
+ debug(`\ncolor: ${color.target}; depth: ${depth.target}`);
+ for (let mipLevel = 0; mipLevel < MIP_LEVELS; mipLevel++) {
+ debug(`mipLevel: ${mipLevel}`);
+ color.attach(gl.COLOR_ATTACHMENT0, mipLevel);
+ depth.attach(gl.DEPTH_ATTACHMENT, mipLevel);
+ const maybeStatus = wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [gl.FRAMEBUFFER_COMPLETE, gl.FRAMEBUFFER_UNSUPPORTED]);
+ if (!maybeStatus || maybeStatus[0] != gl.FRAMEBUFFER_COMPLETE) {
+ continue;
+ }
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], `framebuffer layer ${mipLevel} should be cleared red`);
+
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], `framebuffer layer ${mipLevel} should be drawn green`);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors`);
+ }
+ }
+ }
+
+ // make sure we were not rendering to the canvas.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
+ wtu.checkCanvas(gl, [0, 0, 0, 0], "canvas should be zero");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer-angle-issue.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer-angle-issue.html
new file mode 100644
index 0000000000..1fbdb6bbeb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer-angle-issue.html
@@ -0,0 +1,90 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 can render to layers in 3D texture angle issue check</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+void main(void) {
+ gl_Position = vec4(0, 0, 0, 1);
+ gl_PointSize = 1.0;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 outColor;
+void main() {
+ outColor = vec4(0, 1, 0, 1);
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="1", height="1"></canvas>
+<div id="description"></div>
+<a href='https://bugs.chromium.org/p/angleproject/issues/detail?id=4417'>ANGLE issue #4417</a>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+description("Test that WebGL2 can render to layers in 3D textures");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+function runTest() {
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, gl.canvas.width, gl.canvas.height, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ for (let i = 0; i < 2; i++) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, i);
+
+ const rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, gl.canvas.width, gl.canvas.height);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
+
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
+
+ const program = wtu.setupProgram(gl, ['vshader','fshader'], [], console.log.bind(console));
+ gl.useProgram(program);
+
+ gl.drawArrays(gl.POINTS, 0, 1);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors`);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], `framebuffer layer ${i} should be green`);
+ }
+
+ // make sure we were not rendering to the canvas.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
+ wtu.checkCanvas(gl, [0, 0, 0, 0], "canvas should be zero");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer.html
new file mode 100644
index 0000000000..c34f2a4143
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer.html
@@ -0,0 +1,440 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 can render to layers in 3D and 2D_ARRAY textures</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+void main(void) {
+ gl_Position = vec4(0, 0, 0, 1);
+ gl_PointSize = 1.0;
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="100", height="100"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+description("Test that WebGL2 can render to layers in 3D and 2D_ARRAY textures");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+function runTest() {
+ const texWidth = 1;
+ const texHeight = 1;
+ const texDepth = 2;
+
+ function makeFragmentShader(typeInfo) {
+ const src = `#version 300 es
+ precision mediump float;
+ out ${typeInfo.outType} color;
+ void main() {
+ color = ${typeInfo.outValue};
+ }
+ `;
+ return src;
+ }
+
+ const textureInternalFormatInfo = {};
+ {
+ const t = textureInternalFormatInfo;
+ // unsized formats
+ // If understand correctly these 3 unsized formats are not required to be color renderable
+ t[gl.ALPHA] = { textureFormat: gl.ALPHA, colorRenderable: false, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
+ t[gl.LUMINANCE] = { textureFormat: gl.LUMINANCE, colorRenderable: false, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
+ t[gl.LUMINANCE_ALPHA] = { textureFormat: gl.LUMINANCE_ALPHA, colorRenderable: false, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
+
+ t[gl.RGB] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_5_6_5], };
+ t[gl.RGBA] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_4_4_4_4, gl.UNSIGNED_SHORT_5_5_5_1], };
+
+ // sized formats
+ t[gl.R8] = { textureFormat: gl.RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
+ t[gl.R8_SNORM] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [gl.BYTE], };
+ t[gl.R16F] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.R32F] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT], };
+ t[gl.R8UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
+ t[gl.R8I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [gl.BYTE], };
+ t[gl.R16UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.UNSIGNED_SHORT], };
+ t[gl.R16I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.SHORT], };
+ t[gl.R32UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
+ t[gl.R32I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.INT], };
+ t[gl.RG8] = { textureFormat: gl.RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RG8_SNORM] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [gl.BYTE], };
+ t[gl.RG16F] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.RG32F] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [gl.FLOAT], };
+ t[gl.RG8UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RG8I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.BYTE], };
+ t[gl.RG16UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_SHORT], };
+ t[gl.RG16I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.SHORT], };
+ t[gl.RG32UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.UNSIGNED_INT], };
+ t[gl.RG32I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.INT], };
+ t[gl.RGB8] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
+ t[gl.SRGB8] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGB565] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_6_5], };
+ t[gl.RGB8_SNORM] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [gl.BYTE], };
+ t[gl.R11F_G11F_B10F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_10F_11F_11F_REV], };
+ t[gl.RGB9_E5] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_5_9_9_9_REV], };
+ t[gl.RGB16F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.RGB32F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.FLOAT], };
+ t[gl.RGB8UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGB8I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [gl.BYTE], };
+ t[gl.RGB16UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [gl.UNSIGNED_SHORT], };
+ t[gl.RGB16I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [gl.SHORT], };
+ t[gl.RGB32UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.UNSIGNED_INT], };
+ t[gl.RGB32I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.INT], };
+ t[gl.RGBA8] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
+ t[gl.SRGB8_ALPHA8] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGBA8_SNORM] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [gl.BYTE], };
+ t[gl.RGB5_A1] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_5_5_1, gl.UNSIGNED_INT_2_10_10_10_REV], };
+ t[gl.RGBA4] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_4_4_4_4], };
+ t[gl.RGB10_A2] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
+ t[gl.RGBA16F] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.RGBA32F] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [gl.FLOAT], };
+ t[gl.RGBA8UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGBA8I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.BYTE], };
+ t[gl.RGB10_A2UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
+ t[gl.RGBA16UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.UNSIGNED_SHORT], };
+ t[gl.RGBA16I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.SHORT], };
+ t[gl.RGBA32I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [gl.INT], };
+ t[gl.RGBA32UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [gl.UNSIGNED_INT], };
+
+ // Sized Internal
+ t[gl.DEPTH_COMPONENT16] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [gl.UNSIGNED_SHORT, gl.UNSIGNED_INT], };
+ t[gl.DEPTH_COMPONENT24] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
+ t[gl.DEPTH_COMPONENT32F] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT], };
+ t[gl.DEPTH24_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_24_8], };
+ t[gl.DEPTH32F_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT_32_UNSIGNED_INT_24_8_REV], };
+
+ Object.keys(t).forEach(function(internalFormat) {
+ const info = t[internalFormat];
+ info.bytesPerElementMap = {};
+ info.bytesPerElement.forEach(function(bytesPerElement, ndx) {
+ const type = info.type[ndx];
+ info.bytesPerElementMap[type] = bytesPerElement;
+ });
+ });
+ }
+
+ const validChannelsByTextureFormat = {};
+ {
+ const v = validChannelsByTextureFormat;
+ v[gl.RED] = [1, 0, 0, 0];
+ v[gl.RG] = [1, 1, 0, 0];
+ v[gl.RGB] = [1, 1, 1, 0];
+ v[gl.RGBA] = [1, 1, 1, 1];
+ v[gl.RED_INTEGER] = [1, 0, 0, 0];
+ v[gl.RG_INTEGER] = [1, 1, 0, 0];
+ v[gl.RGB_INTEGER] = [1, 1, 1, 0];
+ v[gl.RGBA_INTEGER] = [1, 1, 1, 1];
+ }
+
+ const depthTextureFormats = [
+ gl.DEPTH_COMPONENT16,
+ gl.DEPTH_COMPONENT24,
+ gl.DEPTH_COMPONENT32F,
+ gl.DEPTH24_STENCIL8,
+ gl.DEPTH32F_STENCIL8,
+ ];
+
+ const intTextureFormats = [
+ gl.R8I,
+ gl.R16I,
+ gl.R32I,
+ gl.RG8I,
+ gl.RG16I,
+ gl.RG32I,
+ gl.RGB8I,
+ gl.RGB16I,
+ gl.RGB32I,
+ gl.RGBA8I,
+ gl.RGBA16I,
+ gl.RGBA32I,
+ ];
+
+ const unsignedIntTextureFormats = [
+ gl.R8UI,
+ gl.R16UI,
+ gl.R32UI,
+ gl.RG8UI,
+ gl.RG16UI,
+ gl.RG32UI,
+ gl.RGB8UI,
+ gl.RGB16UI,
+ gl.RGB32UI,
+ gl.RGBA8UI,
+ gl.RGB10_A2UI,
+ gl.RGBA16UI,
+ gl.RGBA32UI,
+ ];
+
+ const floatTextureFormats = Object.keys(textureInternalFormatInfo).map(function(v) {
+ return parseInt(v);
+ }).filter(function(format) {
+ return intTextureFormats.indexOf(format) < 0 &&
+ unsignedIntTextureFormats.indexOf(format) < 0 &&
+ depthTextureFormats.indexOf(format);
+ });
+
+ const expectedColorByInternalFormat = {};
+ expectedColorByInternalFormat[gl.SRGB8_ALPHA8] = [225, 188, 137, 255];
+
+ function clearFloat(gl) {
+ gl.clearBufferfv(gl.COLOR, 0, [0, 0, 0, 0]);
+ }
+
+ function clearInt(gl) {
+ gl.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
+ }
+
+ function clearUint(gl) {
+ gl.clearBufferuiv(gl.COLOR, 0, [0, 0, 0, 0]);
+ }
+
+
+ function checkData(data, expected, internalFormat, tolerance) {
+ const internalFormatInfo = textureInternalFormatInfo[internalFormat];
+ const validChannels = validChannelsByTextureFormat[internalFormatInfo.textureFormat];
+ if (!validChannels) {
+ testFailed('oops');
+ return;
+ }
+ for (let y = 0; y < texHeight; ++y) {
+ for (let x = 0; x < texWidth; ++x) {
+ for (let c = 0; c < validChannels.length; ++c) {
+ if (validChannels[c]) {
+ const offset = (y * texWidth + x) * 4 + c;
+ const pixel = data[offset];
+ const diff = Math.abs(pixel - expected[c]);
+ if (diff > tolerance) {
+ testFailed(`pixel ${x},${y} channel ${c} was ${pixel} expected ${expected[c]} +/- ${tolerance}`);
+ return;
+ }
+ }
+ }
+ }
+ }
+ testPassed(`data was ${expected.join(',')}`);
+ }
+
+ function checkFloat(gl, textureInfo, expected) {
+ const data = new Uint8Array(texWidth * texHeight * 4);
+ gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ const internalFormat = textureInfo.internalFormat;
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from readPixels with ${wtu.glEnumToString(gl, internalFormat)}`);
+ checkData(data, expected, internalFormat, 9);
+ }
+
+ function checkInt(gl, textureInfo, expected) {
+ const data = new Int32Array(texWidth * texHeight * 4);
+ gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA_INTEGER, gl.INT, data);
+ const internalFormat = textureInfo.internalFormat;
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from readPixels with ${wtu.glEnumToString(gl, internalFormat)}`);
+ checkData(data, expected, internalFormat, 0);
+ }
+
+ function checkUint(gl, textureInfo, expected) {
+ const data = new Uint32Array(texWidth * texHeight * 4);
+ gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA_INTEGER, gl.UNSIGNED_INT, data);
+ const internalFormat = textureInfo.internalFormat;
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from readPixels with ${wtu.glEnumToString(gl, internalFormat)}`);
+ checkData(data, expected, internalFormat, 0);
+ }
+
+ const expectedFloatColor = [.75 * 255 | 0, .5 * 255 | 0, .25 * 255 | 0, 1 * 255 | 0];
+ const floatTypes = [
+ { outType: 'vec4', outValue: 'vec4(.75, .5, .25, 1)', expected: expectedFloatColor, clear: clearFloat, check: checkFloat, target: gl.TEXTURE_2D, },
+ { outType: 'vec4', outValue: 'vec4(.75, .5, .25, 1)', expected: expectedFloatColor, clear: clearFloat, check: checkFloat, target: gl.TEXTURE_3D, },
+ { outType: 'vec4', outValue: 'vec4(.75, .5, .25, 1)', expected: expectedFloatColor, clear: clearFloat, check: checkFloat, target: gl.TEXTURE_2D_ARRAY, },
+ ];
+
+ const expectedIntColor = [1, 2, 4, 3];
+ const signedIntTypes = [
+ { outType: 'ivec4', outValue: 'ivec4(1, 2, 4, 3)', expected: expectedIntColor, clear: clearInt, check: checkInt, target: gl.TEXTURE_2D, },
+ { outType: 'ivec4', outValue: 'ivec4(1, 2, 4, 3)', expected: expectedIntColor, clear: clearInt, check: checkInt, target: gl.TEXTURE_3D, },
+ { outType: 'ivec4', outValue: 'ivec4(1, 2, 4, 3)', expected: expectedIntColor, clear: clearInt, check: checkInt, target: gl.TEXTURE_2D_ARRAY, },
+ ];
+
+ const expectedUintColor = [1, 2, 4, 3];
+ const unsignedIntTypes = [
+ { outType: 'uvec4', outValue: 'uvec4(1, 2, 4, 3)', expected: expectedUintColor, clear: clearUint, check: checkUint, target: gl.TEXTURE_2D, },
+ { outType: 'uvec4', outValue: 'uvec4(1, 2, 4, 3)', expected: expectedUintColor, clear: clearUint, check: checkUint, target: gl.TEXTURE_3D, },
+ { outType: 'uvec4', outValue: 'uvec4(1, 2, 4, 3)', expected: expectedUintColor, clear: clearUint, check: checkUint, target: gl.TEXTURE_2D_ARRAY, },
+ ];
+
+ /**
+ * Gets the number of bytes per element for a given internalFormat / type
+ * @param {number} internalFormat The internalFormat parameter from texImage2D etc..
+ * @param {number} type The type parameter for texImage2D etc..
+ * @return {number} the number of bytes per element for the given internalFormat, type combo
+ * @memberOf module:twgl/textures
+ */
+ function getBytesPerElementForInternalFormat(internalFormat, type) {
+ const info = textureInternalFormatInfo[internalFormat];
+ if (!info) {
+ throw "unknown internal format";
+ }
+ const bytesPerElement = info.bytesPerElementMap[type];
+ if (bytesPerElement === undefined) {
+ throw "unknown internal format";
+ }
+ return bytesPerElement;
+ }
+
+ function make2DTexture(gl, target, internalFormat, format, type) {
+ gl.texImage2D(target, 0, internalFormat, texWidth, texHeight, 0, format, type, null);
+ }
+
+ function make3DTexture(gl, target, internalFormat, format, type) {
+ gl.texImage3D(target, 0, internalFormat, texWidth, texHeight, texDepth, 0, format, type, null);
+ }
+
+ function attach2DTexture(gl, target, texture) {
+ const level = 0;
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, texture, level);
+ }
+
+ function attach3DTexture(gl, target, texture) {
+ const level = 0;
+ const slice = texDepth - 1;
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level, slice);
+ }
+
+ const targets = {};
+ targets[gl.TEXTURE_2D] = { make: make2DTexture, attach: attach2DTexture, },
+ targets[gl.TEXTURE_3D] = { make: make3DTexture, attach: attach3DTexture, },
+ targets[gl.TEXTURE_2D_ARRAY] = { make: make3DTexture, attach: attach3DTexture, },
+
+ debug("create textures");
+ Object.keys(targets).forEach(function(target) {
+ debug("");
+ target = parseInt(target);
+ debug(wtu.glEnumToString(gl, target))
+ const targetInfo = targets[target];
+ targetInfo.textures = [];
+ Object.keys(textureInternalFormatInfo).forEach(function(internalFormat) {
+ internalFormat = parseInt(internalFormat);
+ const isDepthFormat = depthTextureFormats.indexOf(internalFormat) >= 0;
+ if (isDepthFormat) {
+ return;
+ }
+ const info = textureInternalFormatInfo[internalFormat];
+ if (!info.colorRenderable) {
+ return;
+ }
+ const texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ targetInfo.make(gl, target, internalFormat, info.textureFormat, info.type[0]);
+ targetInfo.textures.push({
+ internalFormat: internalFormat,
+ texture: texture,
+ });
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from setup for ${wtu.glEnumToString(gl, target)} ${wtu.glEnumToString(gl, internalFormat)}`);
+ });
+ });
+
+ // set the canvas to a known color
+ const half = 127 / 255;
+ gl.clearColor(half, half, half, half);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.clearColor(0, 0, 0, 0);
+
+ const framebuffer = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ gl.viewport(0, 0, texWidth, texHeight);
+
+ const rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, texWidth, texHeight);
+
+ testTypes('float', floatTypes, floatTextureFormats);
+ testTypes('int', signedIntTypes, intTextureFormats);
+ testTypes('unsigned', unsignedIntTypes, unsignedIntTextureFormats);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ wtu.checkCanvas(gl, [127, 127, 127, 127], "canvas should be [127, 127, 127, 127]");
+
+ function testTypes(label, types, compatibleFormats) {
+ debug('');
+ types.forEach(function(typeInfo) {
+ debug(`\nchecking ${wtu.glEnumToString(gl, typeInfo.target)} with ${label} texture formats`);
+ const program = wtu.setupProgram(gl, ['vshader', makeFragmentShader(typeInfo)], [], console.log.bind(console));
+ if (!program) {
+ testFailed("Loading program failed");
+ return;
+ }
+ testPassed("Loading program succeeded");
+
+ const target = typeInfo.target;
+ const targetInfo = targets[target];
+ targetInfo.textures.filter(function(textureInfo) {
+ return compatibleFormats.indexOf(textureInfo.internalFormat) >= 0;
+ }).forEach(function(textureInfo) {
+ const internalFormat = textureInfo.internalFormat;
+ const desc = `${wtu.glEnumToString(gl, target)} ${wtu.glEnumToString(gl, internalFormat)}`;
+ const expected = expectedColorByInternalFormat[internalFormat] || typeInfo.expected;
+
+ debug('');
+ debug(desc);
+
+ targetInfo.attach(gl, target, textureInfo.texture);
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE, `for ${desc}`);
+ typeInfo.clear(gl);
+ if (wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from clear to ${desc}`)) {
+ return;
+ }
+ typeInfo.check(gl, textureInfo, [0, 0, 0, 0]);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ if (wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from render to ${desc}`)) {
+ return;
+ }
+ typeInfo.check(gl, textureInfo, expected);
+
+ typeInfo.clear(gl);
+ if (wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from clear to ${desc}`)) {
+ return;
+ }
+ typeInfo.check(gl, textureInfo, [0, 0, 0, 0]);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE, `for ${desc} with depth renderbuffer`);
+ gl.clearBufferfv(gl.DEPTH, 0, [1]);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from render to ${desc}`);
+
+ typeInfo.check(gl, textureInfo, expected);
+ });
+ });
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-changing-base-level.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-changing-base-level.html
new file mode 100644
index 0000000000..de462d6015
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-changing-base-level.html
@@ -0,0 +1,107 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL framebuffer using a non-square texture with a changing base level</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas" width="16" height="16"> </canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+// http://anglebug.com/2291
+
+var wtu = WebGLTestUtils;
+var gl;
+
+function testNonSquareFramebufferTextureWithChangingBaseLevel() {
+ var program = wtu.setupSimpleTextureProgram(gl);
+ wtu.setupUnitQuad(gl);
+
+ var width = 8;
+ var height = 4;
+
+ debug("");
+ debug("Text texture width " + width + " x height " + height);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ 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);
+
+ // Create all mipmap levels for the texture from level 0 to the 1x1 pixel level.
+ var level = 0;
+ var levelW = width;
+ var levelH = height;
+ gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, levelW, levelH, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ while (levelW > 1 || levelH > 1)
+ {
+ ++level;
+ levelW = Math.max(1, Math.floor(width / Math.pow(2, level)));
+ levelH = Math.max(1, Math.floor(height / Math.pow(2, level)));
+ gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, levelW, levelH, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ // Clear each level of the texture using an FBO. Change the base level to match the level used for the FBO on each iteration.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ level = 0;
+ levelW = width;
+ levelH = height;
+ while (levelW > 1 || levelH > 1)
+ {
+ var levelW = Math.floor(width / Math.pow(2, level));
+ var levelH = Math.floor(height / Math.pow(2, level));
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, level);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, level);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with texture should succeed.");
+ gl.clearColor(0, 1, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Clearing the texture level " + level + " to green should succeed.");
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 255, 0, 255], "should be green");
+ ++level;
+ }
+
+ debug("");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 0);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Drawing the texture to default framebuffer with base level 0 should succeed.");
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+}
+
+description();
+
+var canvas = document.getElementById("canvas");
+shouldBeNonNull("gl = wtu.create3DContext(canvas, undefined, 2)");
+
+testNonSquareFramebufferTextureWithChangingBaseLevel();
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-level1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-level1.html
new file mode 100644
index 0000000000..d5ac8cb1e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-level1.html
@@ -0,0 +1,64 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL framebuffer using texture level 1</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+
+function testFramebufferTextureWithNonZeroBaseLevel(level) {
+ if (level < 1) {
+ throw "This test is incorrect if level < 1";
+ }
+ var width = 32;
+ var height = 16;
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ 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.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 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, level);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, level);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with texture should succeed.");
+
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+}
+
+description("Test fbo completeness when using non level 0 texture images");
+
+var canvas = document.getElementById("canvas");
+shouldBeNonNull("gl = wtu.create3DContext(canvas, undefined, 2)");
+
+testFramebufferTextureWithNonZeroBaseLevel(1);
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-to-texture.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-to-texture.html
new file mode 100644
index 0000000000..926e14beab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-to-texture.html
@@ -0,0 +1,201 @@
+<!--
+Copyright (c) 2022 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL framebuffer to texture conformance 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>
+</head>
+<body>
+<canvas id="canvas"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test resolving and copying the framebuffer to a texture, and drawing the result.");
+debug('Reduced test case for <a href="http://anglebug.com/6972">http://anglebug.com/6972</a>');
+
+// Reproduces two behaviors:
+//
+// 1) The initial draw disappearing entirely from the default back
+// buffer. The current test case does not show this behavior
+// independently from the other, but a previous iteration, with the
+// textured quad scaled to half size and translated (-0.5, -0.5), did.
+//
+// 2) With Metal debug layers and load/store validation turned on on
+// Intel Macs, the transparent area of the texture prior to the bug
+// fix was magenta = undefined. Similar behavior would presumably
+// reproduce on M1 hardware without debug layers or validation.
+
+const size = 64;
+const halfSize = size / 2;
+const green = [ 0, 255, 0, 255 ];
+const transparent = [ 0, 0, 0, 0 ];
+
+let wtu = WebGLTestUtils;
+let canvas = document.getElementById("canvas");
+canvas.width = size;
+canvas.height = size;
+
+let gl = wtu.create3DContext("canvas", {
+ // Antialiasing is crucial for reproducing the bug.
+ antialias: true,
+ // Depth testing is not.
+ depth: false,
+}, 2);
+
+function allocateTexture(sz) {
+ let texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, sz, sz);
+ 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.bindTexture(gl.TEXTURE_2D, null);
+ return texture;
+}
+
+// Allocate destination texture
+let destTexture = allocateTexture(halfSize);
+
+// Set up half-size solid color quad in center
+let colorQuadVAO = gl.createVertexArray();
+gl.bindVertexArray(colorQuadVAO);
+let colorQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.5 });
+
+// Setup textured quad covering the entire renderable area
+let quadVAO = gl.createVertexArray();
+gl.bindVertexArray(quadVAO);
+let quadProgram = wtu.setupTexturedQuad(gl, 0, 1);
+gl.useProgram(quadProgram);
+let quadTexLoc = gl.getUniformLocation(quadProgram, "tex");
+gl.uniform1i(quadTexLoc, 0);
+
+gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+gl.activeTexture(gl.TEXTURE0); // To match quadTexLoc=0
+
+function runTest() {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.disable(gl.BLEND);
+ gl.bindVertexArray(colorQuadVAO);
+ gl.useProgram(colorQuadProgram);
+ wtu.drawUByteColorQuad(gl, [ 0, 255, 0, 255 ]);
+
+ gl.bindTexture(gl.TEXTURE_2D, destTexture);
+ // Copy the upper right corner of the framebuffer to the texture.
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, halfSize, halfSize, halfSize, halfSize);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.useProgram(quadProgram);
+ gl.enable(gl.BLEND);
+ gl.bindVertexArray(quadVAO);
+ gl.bindTexture(gl.TEXTURE_2D, destTexture);
+ // Magnify and blend this texture over the current framebuffer.
+ wtu.drawUnitQuad(gl);
+}
+
+function runUserDefinedFBOTest() {
+ let fbo1 = gl.createFramebuffer();
+ let fbo2 = gl.createFramebuffer();
+ let rb = gl.createRenderbuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo1);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, size, size);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [ gl.FRAMEBUFFER_COMPLETE ]);
+
+ let tex = allocateTexture(size, size);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [ gl.FRAMEBUFFER_COMPLETE ]);
+
+ // Same rendering steps as in the default-framebuffer test, with appropriate framebuffer blits interspersed.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo1);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.disable(gl.BLEND);
+ gl.bindVertexArray(colorQuadVAO);
+ gl.useProgram(colorQuadProgram);
+ wtu.drawUByteColorQuad(gl, [ 0, 255, 0, 255 ]);
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo1);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo2);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2);
+
+ gl.bindTexture(gl.TEXTURE_2D, destTexture);
+ // Copy the upper right corner of the framebuffer to the texture.
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, halfSize, halfSize, halfSize, halfSize);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo1);
+
+ gl.useProgram(quadProgram);
+ gl.enable(gl.BLEND);
+ gl.bindVertexArray(quadVAO);
+ gl.bindTexture(gl.TEXTURE_2D, destTexture);
+ // Magnify and blend this texture over the current framebuffer.
+ wtu.drawUnitQuad(gl);
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo1);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo2);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2);
+
+ // No longer easy to put these results on the canvas, because it's
+ // antialiased and we can't blitFramebuffer to it. Let's assume
+ // that if failures occur, they'll be straightforward to debug.
+}
+
+function checkRenderingResults(prefix) {
+ // Center quad should be rendered correctly.
+ wtu.checkCanvasRect(gl,
+ halfSize / 2 + 1, halfSize / 2 + 1,
+ halfSize - 2, halfSize - 2,
+ green,
+ prefix + ": center quad should be green");
+
+ // Overlapping lower-left quad should be green as well.
+ wtu.checkCanvasRect(gl,
+ 1, 1,
+ halfSize - 2, halfSize - 2,
+ green,
+ prefix + ": lower left quad should be green");
+
+ // Leftmost area above the lower-left quad should be transparent.
+ wtu.checkCanvasRect(gl,
+ 1, halfSize + 1,
+ halfSize / 2 - 2, halfSize / 2 - 2,
+ transparent,
+ prefix + ": leftmost area above lower left quad should be transparent");
+
+ // Bottommost area to the right of the lower-left quad should be transparent.
+ wtu.checkCanvasRect(gl,
+ halfSize + 1, 1,
+ halfSize / 2 - 2, halfSize / 2 - 2,
+ transparent,
+ prefix + ": bottommost area to the right of lower left quad should be transparent");
+}
+
+runTest();
+checkRenderingResults("default back buffer");
+
+runUserDefinedFBOTest();
+checkRenderingResults("user-defined framebuffer");
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at the end of the test.");
+
+finishTest();
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-unsupported.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-unsupported.html
new file mode 100644
index 0000000000..1780650ed6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-unsupported.html
@@ -0,0 +1,134 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL FRAMEBUFFER_UNSUPPORTED 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+var canvas = document.getElementById("canvas");
+
+function checkFramebuffer(expected) {
+ var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (expected.indexOf(actual) < 0) {
+ var msg = "checkFramebufferStatus expects [";
+ for (var index = 0; index < expected.length; ++index) {
+ msg += wtu.glEnumToString(gl, expected[index]);
+ if (index + 1 < expected.length)
+ msg += ", ";
+ }
+ msg += "], was " + wtu.glEnumToString(gl, actual);
+ testFailed(msg);
+ } else {
+ var msg = "checkFramebufferStatus got " + wtu.glEnumToString(gl, actual) +
+ " as expected";
+ testPassed(msg);
+ }
+}
+
+function testImageAttachedTwoPoints() {
+ debug("");
+ debug("Checking an image is attached to more than one color attachment in a framebuffer.");
+
+ var tex1 = gl.createTexture();
+ var tex2 = gl.createTexture();
+ var fb = gl.createFramebuffer();
+ gl.bindTexture(gl.TEXTURE_2D, tex1);
+ gl.texImage2D(gl.TEXTURE_2D,
+ 0, // level
+ gl.RGBA, // internalFormat
+ 1, // width
+ 1, // height
+ 0, // border
+ gl.RGBA, // format
+ gl.UNSIGNED_BYTE, // type
+ new Uint8Array(4)); // data
+ gl.bindTexture(gl.TEXTURE_2D, tex2);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Texture creation should succeed.");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex1, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex2, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, tex1, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_UNSUPPORTED]);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fb);
+ fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ var texCube = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCube);
+ for (var target = gl.TEXTURE_CUBE_MAP_POSITIVE_X; target < gl.TEXTURE_CUBE_MAP_POSITIVE_X + 6; target++) {
+ gl.texImage2D(target, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, texCube, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_CUBE_MAP_POSITIVE_X, texCube, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_UNSUPPORTED]);
+
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fb);
+ fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texImage3D(gl.TEXTURE_3D,
+ 0, // level
+ gl.RGBA, // internalFormat
+ 2, // width
+ 2, // height
+ 2, // depth
+ 0, // border
+ gl.RGBA, // format
+ gl.UNSIGNED_BYTE, // type
+ new Uint8Array(4 * 2 * 2 * 2)); // data
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, tex3d, 0, 1);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, tex3d, 0, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_UNSUPPORTED]);
+
+ // Clean up
+ gl.deleteTexture(tex1);
+ gl.deleteTexture(tex2);
+ gl.deleteTexture(texCube);
+ gl.deleteTexture(tex3d);
+ gl.deleteFramebuffer(fb);
+}
+
+description("This tests FRAMEBUFFER_UNSUPPORTED.");
+
+shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)");
+
+testImageAttachedTwoPoints();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html
new file mode 100644
index 0000000000..36f5f50a72
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html
@@ -0,0 +1,169 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>The Color Types of Fragment Shader's Outputs Should Match The Data Types of Color Buffers</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in highp vec4 aPosition;
+void main() {
+ gl_Position = aPosition;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 oColor;
+void main() {
+ oColor = vec4(1.0, 0.0, 0.0, 0.0);
+}
+</script>
+
+<script id="fshaderMRT" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 oColor[2];
+void main() {
+ oColor[0] = vec4(1.0, 0.0, 0.0, 0.0);
+}
+</script>
+
+<script id="fshaderRealMRT" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 oColor[2];
+void main() {
+ oColor[0] = vec4(1.0, 0.0, 0.0, 0.0);
+ oColor[1] = vec4(0.0, 1.0, 0.0, 0.0);
+}
+</script>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies that the color types of fragment shader's outputs should match color buffers' types.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var width = 8;
+var height = 8;
+var tex0;
+var tex1;
+var rb0;
+var rb1;
+var fbo = gl.createFramebuffer();
+var program0;
+var program1;
+var program2;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ init();
+
+ // COLOR_ATTACHMENT0 is fixed-point data, which can be converted to float.
+ // COLOR_ATTACHMENT1 is integer data. The fragment outputs are all float.
+ allocate_textures();
+ check_type_match();
+ allocate_renderbuffers();
+ check_type_match();
+}
+
+function check_type_match() {
+ gl.useProgram(program0);
+ rendering([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
+ rendering([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], gl.INVALID_OPERATION);
+
+ gl.useProgram(program1);
+ rendering([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
+ rendering([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], gl.INVALID_OPERATION);
+
+ gl.useProgram(program2);
+ rendering([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
+ rendering([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], gl.INVALID_OPERATION);
+}
+
+function init() {
+ program0 = wtu.setupProgram(gl, ['vshader', 'fshader'], ['aPosition'], [0]);
+ program1 = wtu.setupProgram(gl, ['vshader', 'fshaderMRT'], ['aPosition'], [0]);
+ program2 = wtu.setupProgram(gl, ['vshader', 'fshaderRealMRT'], ['aPosition'], [0]);
+ if (!program0 || !program1 || !program2) {
+ testFailed("Failed to set up program");
+ return;
+ }
+ testPassed("Succeed to set up program");
+
+ wtu.setupUnitQuad(gl, 0, 1);
+ gl.viewport(0, 0, width, height);
+}
+
+function allocate_textures() {
+ tex0 = gl.createTexture();
+ tex1 = gl.createTexture();
+ wtu.fillTexture(gl, tex0, width, height, [0xff, 0x0, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
+ wtu.fillTexture(gl, tex1, width, height, [0x0, 0xff, 0x0, 0xff], 0, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, gl.RGBA8UI);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex1, 0);
+}
+
+function allocate_renderbuffers() {
+ rb0 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, width, height);
+ rb1 = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8UI, width, height);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1);
+}
+
+function rendering(draw_buffers, error) {
+ gl.drawBuffers(draw_buffers);
+
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ }
+
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, error, "If color buffers' type mismatch the type of fragment shader's outputs, geneate INVALID_OPERATION. Otherwise, it should be NO_ERROR");
+}
+
+gl.bindTexture(gl.TEXTURE_2D, null);
+gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+gl.useProgram(null);
+gl.deleteTexture(tex0);
+gl.deleteTexture(tex1);
+gl.deleteRenderbuffer(rb0);
+gl.deleteRenderbuffer(rb1);
+gl.deleteFramebuffer(fbo);
+gl.deleteProgram(program0);
+gl.deleteProgram(program1);
+gl.deleteProgram(program2);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-arrays.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-arrays.html
new file mode 100644
index 0000000000..65009ea5b3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-arrays.html
@@ -0,0 +1,271 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Instanced Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<!-- Shaders for testing instanced draws -->
+<script id="outputVertexShader" type="x-shader/x-vertex">
+attribute vec4 aPosition;
+attribute vec2 aOffset;
+attribute vec4 aColor;
+varying vec4 vColor;
+void main() {
+ vColor = aColor;
+ gl_Position = aPosition + vec4(aOffset, 0.0, 0.0);
+}
+</script>
+
+<script id="outputFragmentShader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 vColor;
+void main() {
+ gl_FragColor = vColor;
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies the functionality of Instanced Arrays.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runDivisorTest();
+ runOutputTests();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runDivisorTest() {
+ debug("Testing VERTEX_ATTRIB_ARRAY_DIVISOR");
+
+ shouldBe("gl.VERTEX_ATTRIB_ARRAY_DIVISOR", "0x88FE");
+
+ var max_vertex_attribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+
+ for (var i = 0; i < max_vertex_attribs; ++i) {
+ var queried_value = gl.getVertexAttrib(i, gl.VERTEX_ATTRIB_ARRAY_DIVISOR);
+ if(queried_value == 0){
+ testPassed("Vertex attribute " + i + " must has a default divisor of 0");
+ }
+ else{
+ testFailed("Default divisor of vertex attribute " + i + " should be: 0, returned value was: " + queried_value);
+ }
+ }
+
+ gl.vertexAttribDivisor(max_vertex_attribs, 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "vertexAttribDivisor index set greater than or equal to MAX_VERTEX_ATTRIBS should be an invalid value");
+
+ gl.vertexAttribDivisor(max_vertex_attribs-1, 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "vertexAttribDivisor index set less than MAX_VERTEX_ATTRIBS should succeed");
+
+ var queried_value = gl.getVertexAttrib(max_vertex_attribs-1, gl.VERTEX_ATTRIB_ARRAY_DIVISOR);
+ if(queried_value == 2){
+ testPassed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR matches expecation");
+ }
+ else{
+ testFailed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR should be: 2, returned value was: " + queried_value);
+ }
+}
+
+function runOutputTests() {
+ var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
+ var instanceCount = 4;
+
+ debug("Testing various draws for valid built-in function behavior");
+
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+ gl.clearColor(0, 0, 0, 0);
+
+ var positionLoc = 0;
+ var offsetLoc = 2;
+ var colorLoc = 3;
+ var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['aPosition', 'aOffset', 'aColor'], [positionLoc, offsetLoc, colorLoc]);
+
+ var offsets = new Float32Array([
+ -1.0, 1.0,
+ 1.0, 1.0,
+ -1.0, -1.0,
+ 1.0, -1.0,
+ ]);
+ var offsetBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(offsetLoc);
+ gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(offsetLoc, 1);
+
+ var colors = new Float32Array([
+ 1.0, 0.0, 0.0, 1.0, // Red
+ 0.0, 1.0, 0.0, 1.0, // Green
+ 0.0, 0.0, 1.0, 1.0, // Blue
+ 1.0, 1.0, 0.0, 1.0, // Yellow
+ // extra data when colorLoc divisor is set back to 0
+ 1.0, 1.0, 0.0, 1.0, // Yellow
+ 1.0, 1.0, 0.0, 1.0, // Yellow
+ ]);
+ var colorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(colorLoc);
+ gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(colorLoc, 1);
+
+ // Draw 1: Draw Non-indexed instances
+ debug("Testing drawArraysInstanced");
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.setupUnitQuad(gl, 0);
+
+ // Test drawArraysInstanced error conditions
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
+ wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2, [0, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 255]);
+ wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
+
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, -1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstanced cannot have a primcount less than 0");
+
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, -1, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstanced cannot have a count less than 0");
+
+ gl.vertexAttribDivisor(positionLoc, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawArraysInstanced");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawArrays");
+ wtu.checkCanvas(gl, [0, 0, 0, 0], "Nothing should be drawn on the framebuffer when all attributes have non-zero divisors (not enough vertices per instance to form a triangle)");
+ gl.vertexAttribDivisor(positionLoc, 0);
+
+ gl.drawArraysInstanced(gl.POINTS, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with POINTS should succeed");
+ gl.drawArraysInstanced(gl.LINES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with LINES should succeed");
+ gl.drawArraysInstanced(gl.LINE_LIST, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with LINE_LIST should return succeed");
+ gl.drawArraysInstanced(gl.TRI_LIST, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced with TRI_LIST should succeed");
+
+ gl.drawArraysInstanced(desktopGL['QUAD_STRIP'], 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with QUAD_STRIP should return INVALID_ENUM");
+ gl.drawArraysInstanced(desktopGL['QUADS'], 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with QUADS should return INVALID_ENUM");
+ gl.drawArraysInstanced(desktopGL['POLYGON'], 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with POLYGON should return INVALID_ENUM");
+
+ debug("Testing drawArraysInstanced with param 'first' > 0");
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.setupQuad(gl, {
+ positionLocation: 0,
+ scale: 0.5
+ });
+ var offsetsHalf = new Float32Array([
+ -0.5, 0.5,
+ 0.5, 0.5,
+ -0.5, -0.5,
+ 0.5, -0.5
+ ]);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, offsetsHalf, gl.STATIC_DRAW);
+
+ gl.drawArraysInstanced(gl.TRIANGLES, 3, 3, instanceCount);
+ var w = Math.floor(0.25*canvas.width),
+ h = Math.floor(0.25*canvas.height);
+ wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 0, 0, 255]);
+ wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [0, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [0, 0, 255, 255]);
+ wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
+
+ debug("Testing drawArraysInstanced with attributes 'divisor' reset to 0");
+ debug("Correct rendering output: 4 yellow triangles");
+ debug("Possible incorrect rendering output: missing triangles, or triangles with different color at each vertex");
+ gl.vertexAttribDivisor(colorLoc, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArraysInstanced(gl.TRIANGLES, 3, 3, instanceCount);
+ wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [255, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
+ gl.vertexAttribDivisor(colorLoc, 1);
+
+ wtu.setupUnitQuad(gl, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
+
+ // Draw 2: Draw indexed instances
+ debug("Testing drawElementsInstanced");
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.setupIndexedQuad(gl, 1, 0);
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
+ wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2, [0, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 255]);
+ wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
+
+ // Test drawElementsInstanced error conditions
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, -1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstanced cannot have a primcount less than 0");
+
+ gl.drawElementsInstanced(gl.TRIANGLES, -1, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstanced cannot have a count less than 0");
+
+ gl.vertexAttribDivisor(positionLoc, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawElementsInstanced");
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "It's allowed for all vertex attributes to have non-zero divisors when calling drawElements");
+ wtu.checkCanvas(gl, [0, 0, 0, 0], "Nothing should be drawn on the framebuffer when all attributes have non-zero divisors (not enough vertices per instance to form a triangle)");
+ gl.vertexAttribDivisor(positionLoc, 0);
+
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with UNSIGNED_BYTE should succeed");
+
+ gl.drawElementsInstanced(gl.POINTS, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with POINTS should succeed");
+ gl.drawElementsInstanced(gl.LINES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with LINES should succeed");
+ gl.drawElementsInstanced(gl.LINE_LIST, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with LINE_LIST should return succeed");
+ gl.drawElementsInstanced(gl.TRI_LIST, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced with TRI_LIST should succeed");
+
+ gl.drawElementsInstanced(desktopGL['QUAD_STRIP'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstanced with QUAD_STRIP should return INVALID_ENUM");
+ gl.drawElementsInstanced(desktopGL['QUADS'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstanced with QUADS should return INVALID_ENUM");
+ gl.drawElementsInstanced(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstanced with POLYGON should return INVALID_ENUM");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-bug.html
new file mode 100644
index 0000000000..59f25096d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-bug.html
@@ -0,0 +1,254 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Instanced Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 128px; height: 128px;"> </canvas>
+<div id="console"></div>
+<script id="outputVertexShader" type="x-shader/x-vertex">#version 300 es
+in highp vec2 aPosition;
+in highp float aOffset;
+in highp float aColor;
+out mediump float vColor;
+void main() {
+ gl_Position = vec4(aPosition, 0.0, 1.0) + vec4(aOffset, 0.0, 0.0, 0.0);
+ vColor = aColor;
+}
+</script>
+
+<script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
+layout(location = 0) out mediump vec4 oColor;
+in mediump float vColor;
+void main() {
+ oColor = vec4(vColor, 0.0, 0.0, 1.0);
+}
+</script>
+
+<script>
+"use strict";
+description("This test verifies a bug related with instanced rendering on Mac AMD.");
+debug("http://crbug.com/645298");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+// The second and fourth test cases fail - it seems if the divisor doesn't change,
+// the next instanced draw call behaves incorrectly.
+// Also note that if we don't perform a readPixels (in wtu.checkCanvasRect), the bug
+// isn't triggered.
+var testCases = [
+ { instanceCount: 8, divisor: 4 },
+ { instanceCount: 6, divisor: 4 },
+ { instanceCount: 6, divisor: 3 },
+ { instanceCount: 8, divisor: 3 },
+];
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ runDrawArraysTest(testCases[ii].instanceCount, testCases[ii].divisor);
+ }
+
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ runDrawElementsTest(testCases[ii].instanceCount, testCases[ii].divisor);
+ }
+}
+
+function runDrawArraysTest(instanceCount, divisor) {
+ debug("");
+ debug("Testing drawArraysInstanced: instanceCount = " + instanceCount + ", divisor = " + divisor);
+
+ gl.viewport(0, 0, canvas.width, canvas.height);
+
+ var vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+
+ var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]);
+ var positionLoc = gl.getAttribLocation(program, "aPosition");
+ var offsetLoc = gl.getAttribLocation(program, "aOffset");
+ var colorLoc = gl.getAttribLocation(program, "aColor");
+ if (!program || positionLoc < 0 || offsetLoc < 0 || colorLoc < 0) {
+ testFailed("Set up program failed");
+ return;
+ }
+ testPassed("Set up program succeeded");
+
+ var scale = 1.0 / instanceCount;
+
+ gl.enableVertexAttribArray(positionLoc);
+ gl.vertexAttribDivisor(positionLoc, 0);
+ var positions = new Float32Array([
+ 1.0 * scale, 1.0,
+ -1.0 * scale, 1.0,
+ -1.0 * scale, -1.0,
+ 1.0 * scale, 1.0,
+ -1.0 * scale, -1.0,
+ 1.0 * scale, -1.0,
+ ]);
+ var positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
+
+ gl.enableVertexAttribArray(offsetLoc);
+ gl.vertexAttribDivisor(offsetLoc, 1);
+ var offsets = new Float32Array(instanceCount);
+ for (var ii = 0; ii < instanceCount; ++ii) {
+ offsets[ii] = scale * (1 - instanceCount + ii * 2);
+ }
+ var offsetBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(offsetLoc, 1, gl.FLOAT, false, 0, 0);
+
+ gl.enableVertexAttribArray(colorLoc);
+ gl.vertexAttribDivisor(colorLoc, divisor);
+ var colorCount = instanceCount / divisor;
+ if ((instanceCount % divisor) != 0)
+ colorCount++;
+ var colors = new Float32Array(colorCount);
+ for (var ii = 0; ii < colorCount; ++ii) {
+ colors[ii] = 1.0 / colorCount * (ii + 1);
+ }
+ var colorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(colorLoc, 1, gl.FLOAT, false, 0, 0);
+
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced should succeed");
+
+ var colorIndex = -1;
+ for (var ii = 0; ii < instanceCount; ++ii) {
+ if ((ii % divisor) == 0)
+ colorIndex++;
+ var refColor = [ Math.floor(colors[colorIndex] * 255), 0, 0, 255 ];
+ wtu.checkCanvasRect(gl, Math.floor(canvas.width / instanceCount * ii) + 1, 0, 1, canvas.height, refColor,
+ "instance " + ii + " should be " + refColor, 2);
+ }
+
+ gl.deleteBuffer(positionBuffer);
+ gl.deleteBuffer(offsetBuffer);
+ gl.deleteBuffer(colorBuffer);
+ gl.deleteProgram(program);
+ gl.deleteVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.useProgram(null);
+ gl.bindVertexArray(null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clean up should succeed");
+}
+
+function runDrawElementsTest(instanceCount, divisor) {
+ debug("");
+ debug("Testing drawElementsInstanced: instanceCount = " + instanceCount + ", divisor = " + divisor);
+
+ gl.viewport(0, 0, canvas.width, canvas.height);
+
+ var vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+
+ var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]);
+ var positionLoc = gl.getAttribLocation(program, "aPosition");
+ var offsetLoc = gl.getAttribLocation(program, "aOffset");
+ var colorLoc = gl.getAttribLocation(program, "aColor");
+ if (!program || positionLoc < 0 || offsetLoc < 0 || colorLoc < 0) {
+ testFailed("Set up program failed");
+ return;
+ }
+ testPassed("Set up program succeeded");
+
+ var scale = 1.0 / instanceCount;
+
+ gl.enableVertexAttribArray(positionLoc);
+ gl.vertexAttribDivisor(positionLoc, 0);
+ var positions = new Float32Array([
+ 1.0 * scale, 1.0,
+ -1.0 * scale, 1.0,
+ -1.0 * scale, -1.0,
+ 1.0 * scale, -1.0,
+ ]);
+ var positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
+
+ gl.enableVertexAttribArray(offsetLoc);
+ gl.vertexAttribDivisor(offsetLoc, 1);
+ var offsets = new Float32Array(instanceCount);
+ for (var ii = 0; ii < instanceCount; ++ii) {
+ offsets[ii] = scale * (1 - instanceCount + ii * 2);
+ }
+ var offsetBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(offsetLoc, 1, gl.FLOAT, false, 0, 0);
+
+ gl.enableVertexAttribArray(colorLoc);
+ gl.vertexAttribDivisor(colorLoc, divisor);
+ var colorCount = instanceCount / divisor;
+ if ((instanceCount % divisor) != 0)
+ colorCount++;
+ var colors = new Float32Array(colorCount);
+ for (var ii = 0; ii < colorCount; ++ii) {
+ colors[ii] = 1.0 / colorCount * (ii + 1);
+ }
+ var colorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(colorLoc, 1, gl.FLOAT, false, 0, 0);
+
+ var indexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ var indices = new Uint16Array([0, 1, 2, 0, 2, 3]);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced should succeed");
+
+ var colorIndex = -1;
+ for (var ii = 0; ii < instanceCount; ++ii) {
+ if ((ii % divisor) == 0)
+ colorIndex++;
+ var refColor = [ Math.floor(colors[colorIndex] * 255), 0, 0, 255 ];
+ wtu.checkCanvasRect(gl, Math.floor(canvas.width / instanceCount * ii) + 1, 0, 1, canvas.height, refColor,
+ "instance " + ii + " should be " + refColor, 2);
+ }
+
+ gl.deleteBuffer(positionBuffer);
+ gl.deleteBuffer(offsetBuffer);
+ gl.deleteBuffer(colorBuffer);
+ gl.deleteBuffer(indexBuffer);
+ gl.deleteProgram(program);
+ gl.deleteVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ gl.useProgram(null);
+ gl.bindVertexArray(null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clean up should succeed");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-large-divisor.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-large-divisor.html
new file mode 100644
index 0000000000..229649ee3c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-large-divisor.html
@@ -0,0 +1,145 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Instanced Arrays Conformance Tests - large vertex attrib divisors</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas"> </canvas>
+<div id="console"></div>
+<script id="outputVertexShader" type="x-shader/x-vertex">#version 300 es
+layout(location = 0) in vec2 a_position;
+layout(location = 1) in float a_positionOffset;
+layout(location = 2) in vec4 a_color;
+out vec4 v_color;
+void main()
+{
+ gl_Position = vec4(a_position.x * 0.05 + a_positionOffset, a_position.y * 0.05, 0.0, 1.0);
+ v_color = a_color;
+}
+</script>
+
+<script id="outputFragmentShader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+in vec4 v_color;
+out vec4 my_FragColor;
+void main()
+{
+ my_FragColor = v_color;
+}
+</script>
+
+<script>
+"use strict";
+description("Test switching vertex attrib divisor of one attribute between different large values");
+// This is a regression test for http://anglebug.com/2832
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+canvas.width = 256;
+canvas.height = 256;
+var gl = wtu.create3DContext(canvas, null, 2);
+
+var colorDivisor = 65536 * 2;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTest();
+}
+
+function runTest() {
+ var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"]);
+
+ gl.clearColor(0.0, 0.0, 1.0, 1.0);
+
+ wtu.setupIndexedQuadWithOptions(gl, {positionLocation: 0});
+
+ var offsetBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuf);
+ // Note that only the first two offsets below should be used for rendering.
+ // We add some extra ones to the buffer since it can reveal if a too small divisor is used on the WebGL backend.
+ var offsetData = [];
+ for (var i = 0; i < 4; ++i) {
+ offsetData.push(0.0 + i * 0.25);
+ }
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(offsetData), gl.DYNAMIC_DRAW);
+
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up vertex buffer should succeed");
+
+ var colorBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
+ // Red and green colors.
+ var colorData = new Float32Array([1.0, 0.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0]);
+ gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW);
+
+ gl.enableVertexAttribArray(2);
+ gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(2, colorDivisor);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setting up color buffer should succeed");
+
+ var divisorsToTry = [
+ 256,
+ 65536,
+ 65536 * 2
+ ];
+
+ for (var i = 0; i < divisorsToTry.length; ++i) {
+ runDrawElementsTest(divisorsToTry[i]);
+ }
+}
+
+function runDrawElementsTest(divisor) {
+ debug("Using divisor " + divisor);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.vertexAttribDivisor(1, divisor);
+
+ var instanceCount = divisor + 1;
+ var quadsRendered = Math.floor((instanceCount - 1) / divisor) + 1;
+
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Instanced draw should succeed");
+
+ for (var quadIndex = 0; quadIndex < quadsRendered + 1; ++quadIndex) {
+ var quadX = Math.floor((quadIndex / 8) * 256 + 128);
+ var quadY = 128;
+ if (quadIndex < quadsRendered) {
+ var quadColorIndex = Math.floor((quadIndex * divisor) / colorDivisor);
+ if (quadColorIndex == 0) {
+ wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [255, 0, 0, 255]);
+ } else {
+ wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [0, 255, 0, 255]);
+ }
+ } else {
+ wtu.checkCanvasRect(gl, quadX, quadY, 1, 1, [0, 0, 255, 255]);
+ }
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/line-rendering-quality.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/line-rendering-quality.html
new file mode 100644
index 0000000000..24442ea3c6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/line-rendering-quality.html
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<title>Line rendering quality test</title>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="testbed" width="256" height="256"></canvas>
+<canvas id="testbed2" width="256" height="256"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/line-rendering-quality.js"></script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-depth-resolve.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-depth-resolve.html
new file mode 100644
index 0000000000..14aeab4f87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-depth-resolve.html
@@ -0,0 +1,179 @@
+<!--
+Copyright (c) 2022 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL framebuffer to texture conformance 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>
+</head>
+<body>
+<canvas id="canvas"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test resolving multisample depth buffer");
+debug('Reduced test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=238118">https://bugs.webkit.org/show_bug.cgi?id=238118</a>');
+
+// Reproduces an inconistent behavior where if:
+// 1) You render into a multisampling frame buffer
+// 2) Geometry is drawn with DEPTH_TEST disabled and then enabled
+// 3) More than one frame is rendered via requestAnimationFrame
+
+const size = 64;
+const halfSize = size / 2;
+
+let wtu = WebGLTestUtils;
+let canvas = document.getElementById("canvas");
+canvas.width = size;
+canvas.height = size;
+
+let gl = wtu.create3DContext("canvas", {}, 2);
+
+function createTexture(res, format, bytes) {
+ let texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, res, res);
+ 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.bindTexture(gl.TEXTURE_2D, null);
+ return texture;
+}
+
+function createRenderBuffer(res, format, samples) {
+ let rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ if (samples > 1)
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, format, res, res);
+ else
+ gl.renderbufferStorage(gl.RENDERBUFFER, format, res, res);
+ return rb;
+}
+
+let yellowQuadVAO = gl.createVertexArray();
+gl.bindVertexArray(yellowQuadVAO);
+let yellowQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.75 });
+
+let blueQuadVAO = gl.createVertexArray();
+gl.bindVertexArray(blueQuadVAO);
+let blueQuadProgram = wtu.setupColorQuad(gl, 0, { scale: 0.5 });
+
+let fsVAO = gl.createVertexArray();
+gl.bindVertexArray(fsVAO);
+let fsProgram = wtu.setupTexturedQuad(gl, 0, 1);
+gl.useProgram(fsProgram);
+let fsTexLoc = gl.getUniformLocation(fsProgram, "tex");
+gl.uniform1i(fsTexLoc, 0);
+
+// An incorrect render can occur if...
+
+// 1) You use renderbufferStorageMultisample.
+const msaaSamples = 4;
+const colorRB = createRenderBuffer(size, gl.RGBA8, msaaSamples);
+const depthRB = createRenderBuffer(size, gl.DEPTH_COMPONENT16, msaaSamples);
+const resolveTex = createTexture(size, gl.RGBA8);
+
+let renderFBO = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, renderFBO);
+gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRB);
+gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
+
+let resolveFBO = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFBO);
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resolveTex, 0);
+gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+gl.disable(gl.CULL_FACE);
+gl.disable(gl.BLEND);
+
+var frameCount = 0;
+function runTest() {
+ // 2) Render from requestAnimationFrame, only starting with the 2nd frame.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderFBO);
+
+ // Clear background red
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
+
+ // 3) You disable gl.DEPTH_TEST
+ gl.disable(gl.DEPTH_TEST);
+ gl.depthMask(false);
+
+ gl.bindVertexArray(yellowQuadVAO);
+ gl.useProgram(yellowQuadProgram);
+ wtu.drawUByteColorQuad(gl, [ 255, 255, 0, 255 ]);
+
+ // 4) And re-enable gl.DEPTH_TEST
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthMask(true);
+
+ gl.bindVertexArray(blueQuadVAO);
+ gl.useProgram(blueQuadProgram);
+ wtu.drawUByteColorQuad(gl, [ 0, 0, 255, 255 ]);
+
+ // Resolve the multisample framebuffer to a texture
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, renderFBO);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFBO);
+ gl.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]);
+ gl.blitFramebuffer(0, 0, size, size,
+ 0, 0, size, size,
+ gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+
+ // Draw the resolved texture to the backbuffer
+ gl.bindTexture(gl.TEXTURE_2D, resolveTex);
+ gl.useProgram(fsProgram);
+ gl.bindVertexArray(fsVAO);
+ wtu.drawUnitQuad(gl);
+
+ // 5) The incorrect render can occur on the second rendered frame, called from
+ // requestAnimationFrame.
+ frameCount++;
+ if (frameCount == 2) {
+ checkRenderingResults("multisampling-depth-resolve");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at the end of the test.");
+ finishTest();
+ } else {
+ requestAnimationFrame(runTest);
+ }
+}
+
+requestAnimationFrame(runTest);
+
+function checkRenderingResults(prefix) {
+ // Outer color should be red
+ wtu.checkCanvasRect(gl,
+ 1, 1,
+ 2, 2,
+ [255, 0, 0, 255],
+ prefix + ": outer pixels should be red");
+
+ // Outer quad should be rendered yellow.
+ wtu.checkCanvasRect(gl,
+ 10, 10,
+ 2, 2,
+ [255, 255, 0, 255],
+ prefix + ": outer quad should be yellow");
+
+ // Center quad should be rendered blue.
+ wtu.checkCanvasRect(gl,
+ halfSize / 2 + 1, halfSize / 2 + 1,
+ 2, 2,
+ [0, 0, 255, 255],
+ prefix + ": center quad should be blue");
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html
new file mode 100644
index 0000000000..df7bce9b09
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html
@@ -0,0 +1,143 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL multisampling fragment shader evaluation</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+layout(location=0) in vec4 aPosition;
+out vec4 vPosition;
+void main()
+{
+ gl_Position = vec4(aPosition);
+ vPosition = aPosition;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+in vec4 vPosition;
+layout(location=0) out vec4 oColor;
+void main()
+{
+ if (vPosition.x < 0.0) {
+ oColor = vec4(1, 0, 0, 1);
+ } else if (vPosition.y < 0.0) {
+ oColor = vec4(0, 1, 0, 1);
+ } else {
+ oColor = vec4(0, 0, 1, 1);
+ }
+}
+</script>
+
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("Verify that fragment shader is evaluated only once per framebuffer pixel when multisampling is used.");
+
+// GLES 3.0.5 section 3.6.3. Polygon Multisample Rasterization:
+// "Polygon rasterization produces a fragment for each framebuffer pixel with one or more sample points that satisfy
+// the point sampling criteria described in section 3.6.1."
+
+debug("Regression test for <a href='http://crbug.com/682815'>http://crbug.com/682815</a>");
+
+function runTest(testParams) {
+ let canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ let gl = wtu.create3DContext(canvas, {antialias: false}, 2);
+
+ // Find the supported samples for a multisampled renderbuffer of the appropriate internal format.
+ let samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
+ if (!samples || !samples.length) {
+ testFailed("Could not query supported sample counts for required multisampling format " + testParams.internalformat);
+ return;
+ }
+
+ // Note that supported sample counts are required to be reported in descending order.
+ debug('Testing with sample count ' + samples[0]);
+ // Create a framebuffer with a multisampled renderbuffer with the maximum supported number of samples.
+ let rb = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl[testParams.internalformat], 1, 1);
+ let fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Rendering to a multisampled renderbuffer of format " + testParams.internalformat + " is required.");
+ return;
+ }
+
+ // Create a program that will choose between one of different possible colors in the fragment shader.
+ // It should be evaluated only once per framebuffer pixel, so only one of the colors will end up in the framebuffer.
+ // However, if the multisampling mode is incorrectly implemented by supersampling, the samples may have different
+ // colors.
+ let program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"]);
+
+ // Render one triangle using the program. The triangle needs to extend far outside the viewport on all sides, so
+ // that we can safely assume all samples fall inside the triangle. GLES 3.0.5:
+ // "The sample points associated with a pixel may be located inside or outside of the unit square that is considered to bound the pixel."
+ // Here we assume that sample points are less than 9999 pixels away from the pixel they are associated with.
+ let buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 10000, 30000,
+ -30000, -10000,
+ 10000, -10000]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ gl.blitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+
+ let readBuffer = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer);
+
+ // Check that the canvas is one of the colors that the fragment shader may generate, and not a blend of them.
+ let possibleColors = [
+ [255, 0, 0, 255],
+ [0, 255, 0, 255],
+ [0, 0, 255, 255]
+ ];
+ let anyColorMatched = false;
+ for (let i = 0; i < possibleColors.length; ++i) {
+ let colorMatched = true;
+ for (let j = 0; j < 4; ++j) {
+ if (Math.abs(readBuffer[j] - possibleColors[i][j]) > 2) {
+ colorMatched = false;
+ }
+ }
+ if (colorMatched) {
+ anyColorMatched = true;
+ }
+ }
+ if (!anyColorMatched) {
+ testFailed("Color in framebuffer was not one of the colors generated by the fragment shader: " + readBuffer);
+ } else {
+ testPassed("Color in framebuffer was one of the colors generated by the fragment shader: " + readBuffer);
+ }
+}
+
+runTest({internalformat: 'RGBA8'});
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html
new file mode 100644
index 0000000000..39bbb5e348
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html
@@ -0,0 +1,187 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<title>WebGL Out-of-Bounds Index Buffer Caused by CopyBufferSubData Conformance Test</title>
+</head>
+<body>
+<canvas id="canvas" width="8" height="8" style="width: 100px; height: 100px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vsCheckOutOfBounds" type="x-shader/x-vertex">
+ #define TEST_CASE_IN_BOUND 1
+ #define TEST_CASE_OUT_OF_BOUND 2
+
+ precision mediump float;
+ attribute vec2 position;
+ attribute vec4 vecRandom;
+ varying vec4 v_color;
+ uniform int u_testCase;
+
+ bool testFloatComponentAccurate(float component) {
+ return component == 0.2;
+ }
+ // Per the spec, each component can either contain existing contents
+ // of the buffer or 0.
+ bool testFloatComponent(float component) {
+ return (component == 0.2 || component == 0.0);
+ }
+ // The last component is additionally allowed to be 1.0.
+ bool testLastFloatComponent(float component) {
+ return testFloatComponent(component) || component == 1.0;
+ }
+
+ bool testData(vec4 data) {
+ if (u_testCase == TEST_CASE_IN_BOUND) {
+ return (testFloatComponentAccurate(data.x) &&
+ testFloatComponentAccurate(data.y) &&
+ testFloatComponentAccurate(data.z) &&
+ testFloatComponentAccurate(data.w));
+ } else if (u_testCase == TEST_CASE_OUT_OF_BOUND) {
+ return (testFloatComponent(data.x) &&
+ testFloatComponent(data.y) &&
+ testFloatComponent(data.z) &&
+ testLastFloatComponent(data.w));
+ }
+ return false;
+ }
+
+ void main() {
+ if (testData(vecRandom)) {
+ v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- We're good
+ } else {
+ v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value
+ }
+ gl_Position = vec4(position, 0.0, 1.0);
+ }
+</script>
+<script>
+"use strict";
+description("This test verifies that out-of-bounds index buffers caused by CopyBufferSubData behave according to spec.");
+
+// Ensure that drawElements flags either no error or INVALID_OPERATION. In the case of INVALID_OPERATION,
+// no canvas pixels can be touched. In the case of NO_ERROR, all written values must either be the
+// zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
+function verifyOutOfBoundsIndex(gl) {
+ var error = gl.getError();
+ if (error === gl.INVALID_OPERATION) {
+ testPassed("drawElements flagged INVALID_OPERATION, which is valid so long as all canvas pixels were not touched.");
+ wtu.checkCanvas(gl, [0, 0, 255, 255]);
+ } else if (error === gl.NO_ERROR) {
+ testPassed("drawElements flagged NO_ERROR, which is valid so long as all canvas pixels are green.");
+ wtu.checkCanvas(gl, [0, 255, 0, 255]);
+ } else {
+ testFailed("Invalid error flagged by drawElements. Should be INVALID_OPERATION or NO_ERROR");
+ }
+}
+
+// Create an element array buffer with a tri-strip that starts at startIndex and make
+// it the active element array buffer.
+function prepareElementArrayBuffer(gl, startIndex) {
+ var glElementArrayBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, glElementArrayBuffer);
+ var quadIndices = new Uint16Array(4);
+ for (var i = 0; i < quadIndices.length; i++) {
+ quadIndices[i] = startIndex + i;
+ }
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, quadIndices, gl.STATIC_DRAW);
+ return glElementArrayBuffer;
+}
+
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, {antialias: false}, 2);
+
+var numberOfQuads = 200;
+
+// Create a vertex buffer with 200 properly formed tri-strip quads. These quads will cover the canvas texture
+// such that every single pixel is touched by the fragment shader.
+var quadBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
+var quadPositions = new Float32Array(numberOfQuads * /*ComponentsPerQuad*/2 * /*VerticesPerQuad*/4);
+for (var i = 0; i < quadPositions.length; i += /*ComponentsPerQuad*/2 * /*VerticesPerQuad*/4) {
+ quadPositions[i+0] = -1.0; // upper left
+ quadPositions[i+1] = 1.0;
+ quadPositions[i+2] = 1.0; // upper right
+ quadPositions[i+3] = 1.0;
+ quadPositions[i+4] = -1.0; // lower left
+ quadPositions[i+5] = -1.0;
+ quadPositions[i+6] = 1.0; // lower right
+ quadPositions[i+7] = -1.0;
+}
+gl.bufferData(gl.ARRAY_BUFFER, quadPositions, gl.STATIC_DRAW);
+gl.enableVertexAttribArray(0);
+gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+// Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer will be
+// the one indexed off the end.
+var vertexBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+gl.bufferData(gl.ARRAY_BUFFER,
+ new Float32Array([0.2, 0.2, 0.2, 0.2,
+ 0.2, 0.2, 0.2, 0.2,
+ 0.2, 0.2, 0.2, 0.2,
+ 0.2, 0.2, 0.2, 0.2]),
+ gl.STATIC_DRAW);
+gl.enableVertexAttribArray(1);
+gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);
+
+// Setup the verification program.
+var program = wtu.setupProgram(gl, ["vsCheckOutOfBounds", wtu.simpleVertexColorFragmentShader], ["position", "vecRandom"]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Shader and buffer setup should generate no errors");
+var loc = gl.getUniformLocation(program, "u_testCase");
+shouldBeNonNull(loc);
+
+debug("");
+debug("Test -- Vertex indices are in bounds.");
+gl.uniform1i(loc, 1); // TEST_CASE_IN_BOUND == 1
+gl.clearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
+gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+var elementArrayBuffer = prepareElementArrayBuffer(gl, /*StartIndex*/0);
+gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_SHORT, /*offset*/0);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw call should generate no errors");
+wtu.checkCanvas(gl, [0, 255, 0, 255]);
+
+debug("");
+debug("Test -- Index off the end of the vertex buffer near the beginning of the out of bounds area.");
+gl.uniform1i(loc, 2); // TEST_CASE_OUT_OF_BOUND == 2
+gl.clearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
+gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+var outOfBoundsElementArrayBuffer = prepareElementArrayBuffer(gl, /*StartIndex*/4);
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, outOfBoundsElementArrayBuffer);
+gl.bindBuffer(gl.COPY_WRITE_BUFFER, elementArrayBuffer);
+gl.copyBufferSubData(gl.ELEMENT_ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 4 * Uint16Array.BYTES_PER_ELEMENT);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copyBufferSubData should generate no errors");
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
+gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_SHORT, /*offset*/0);
+verifyOutOfBoundsIndex(gl);
+
+debug("");
+debug("Test -- Index off the end of the vertex buffer near the end of the out of bounds area.")
+gl.uniform1i(loc, 2); // TEST_CASE_OUT_OF_BOUND == 2
+gl.clearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
+gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+outOfBoundsElementArrayBuffer = prepareElementArrayBuffer(gl, /*StartIndex*/numberOfQuads - 4);
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
+gl.bindBuffer(gl.COPY_READ_BUFFER, outOfBoundsElementArrayBuffer);
+gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ELEMENT_ARRAY_BUFFER, 0, 0, 4 * Uint16Array.BYTES_PER_ELEMENT);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copyBufferSubData should generate no errors");
+gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_SHORT, /*offset*/0);
+verifyOutOfBoundsIndex(gl);
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Running tests should generate no errors");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rasterizer-discard-and-implicit-clear.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rasterizer-discard-and-implicit-clear.html
new file mode 100644
index 0000000000..f605a25f26
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rasterizer-discard-and-implicit-clear.html
@@ -0,0 +1,149 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>RASTERIZER_DISCARD doesn't affect implicit clears</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+layout(location=0) in vec2 vPosition;
+uniform float xTranslation;
+void main(void) {
+ gl_Position = vec4(vPosition[0] + xTranslation, vPosition[1], 0.0, 1.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform vec4 color;
+out vec4 outColor;
+void main() {
+ outColor = color;
+}
+</script>
+</head>
+<body>
+<canvas id="example"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+description("Enabling RASTERIZER_DISCARD should not affect implicit clears");
+
+const wtu = WebGLTestUtils;
+const canvas = document.getElementById("example");
+const sz = canvas.width = canvas.height = 256;
+const gl = wtu.create3DContext(canvas, undefined, 2);
+const NUM_FRAMES = 15;
+let framesToGo = NUM_FRAMES;
+let xTranslationLoc;
+let colorLoc;
+const positionLocation = 0;
+const red = [ 1.0, 0.0, 0.0, 1.0 ];
+const green = [ 0.0, 1.0, 0.0, 1.0 ];
+const transparentBlackRender = [ 0, 0, 0, 0 ];
+const greenRender = [ 0, 255, 0, 255 ];
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+ finishTest();
+} else {
+ testPassed("WebGL context creation succeeded");
+ runDrawTest();
+}
+
+function runDrawTest() {
+ debug("Verify that draws with rasterizer discard enabled do not interfere with implicit clears");
+ let prog = wtu.loadProgramFromScript(gl, "vshader", "fshader");
+ gl.useProgram(prog);
+ xTranslationLoc = gl.getUniformLocation(prog, "xTranslation");
+ colorLoc = gl.getUniformLocation(prog, "color");
+ let leftRectBuffer = gl.createBuffer();
+ gl.enableVertexAttribArray(positionLocation);
+ gl.bindBuffer(gl.ARRAY_BUFFER, leftRectBuffer);
+ // Create a rectangle covering the left half of the viewport, in
+ // normalized device coordinates.
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ 0.0, 1.0,
+ -1.0, 1.0,
+ -1.0, -1.0,
+ 0.0, 1.0,
+ -1.0, -1.0,
+ 0.0, -1.0]), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
+ requestAnimationFrame(renderDrawTestFrame);
+}
+
+function renderDrawTestFrame() {
+ // Animation is required in order to expose this bug. When it
+ // occurs, the rectangle leaves trails behind it.
+ gl.uniform1f(xTranslationLoc, 0.0);
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.uniform4fv(colorLoc, red);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ // Animate the rectangle from the left to the right half of the viewport.
+ gl.uniform1f(xTranslationLoc, (NUM_FRAMES - framesToGo) / NUM_FRAMES);
+ // Draw the last frame with green so any (incorrect) trails are visibly red.
+ if (framesToGo == 0)
+ gl.uniform4fv(colorLoc, green);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ if (framesToGo-- == 0) {
+ // The left half of the canvas should be transparent black,
+ // which comes from the implicit clear just before drawing the
+ // rectangle without rasterizer discard enabled.
+ wtu.checkCanvasRect(gl, 0, 0, sz / 2, sz, transparentBlackRender, "left half of canvas should be clear", 3);
+ // The right half of the canvas should be solid green, from
+ // the last render of the translated rectangle.
+ wtu.checkCanvasRect(gl, sz / 2, 0, sz / 2, sz, greenRender, "right half of canvas should be green", 3);
+ runReadPixelsTest();
+ } else {
+ requestAnimationFrame(renderDrawTestFrame);
+ }
+}
+
+function runReadPixelsTest() {
+ debug("Verify that readPixels with rasterizer discard enabled receives implicitly cleared data");
+ framesToGo = NUM_FRAMES; // Reset state.
+ // Clear to transparent black.
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ // Start with rasterizer discard enabled.
+ gl.enable(gl.RASTERIZER_DISCARD);
+ requestAnimationFrame(renderReadPixelsTestFrame);
+}
+
+function renderReadPixelsTestFrame() {
+ // Rasterizer discard is enabled at the beginning of this test.
+
+ // The canvas should always contain transparent black at the beginning of the frame.
+ wtu.checkCanvasRect(gl, 0, 0, sz, sz, transparentBlackRender, undefined, 3);
+
+ gl.disable(gl.RASTERIZER_DISCARD);
+ // Clear to red.
+ gl.clearColor(1.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ // Enable rasterizer discard again.
+ gl.enable(gl.RASTERIZER_DISCARD);
+
+ if (--framesToGo == 0) {
+ finishTest();
+ } else {
+ requestAnimationFrame(renderReadPixelsTestFrame);
+ }
+}
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/read-draw-when-missing-image.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/read-draw-when-missing-image.html
new file mode 100644
index 0000000000..a9d8c74b9d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/read-draw-when-missing-image.html
@@ -0,0 +1,288 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Read or Draw when Attachment(s) Miss Image</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="8" height="8"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of reading/drawing when color attachment(s) miss image.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var tex_read = gl.createTexture();
+var tex_draw = gl.createTexture();
+var tex_depth = gl.createTexture();
+var tex_stencil = gl.createTexture();
+var fbo_read = gl.createFramebuffer();
+var fbo_draw = gl.createFramebuffer();
+var size = 8;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ // READ_FRAMEBUFFER has image at COLOR_ATTACHMENT0. READ_FRAMEBUFFER is framebuffer complete.
+ // Read from COLOR_ATTACHMENT1, which has no image attached.
+ init_read_fbo();
+ read();
+
+ // DRAW_FRAMEBUFFER has image at COLOR_ATTACHMENT0. DRAW_FRAMEBUFFER is framebuffer complete.
+ // Clear and draw COLOR_ATTACHMENT1 or COLOR_ATTACHMENT0 + COLOR_ATTACHMENT1 attaching point(s).
+ init_draw_fbo();
+ clear();
+ draw();
+
+ blit();
+}
+
+function init_read_fbo() {
+ gl.bindTexture(gl.TEXTURE_2D, tex_read);
+ wtu.fillTexture(gl, tex_read, size, size, [0x0, 0xff, 0xff, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA8);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
+ if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ } else {
+ testPassed("framebuffer complete!");
+ }
+}
+
+function init_draw_fbo() {
+ gl.bindTexture(gl.TEXTURE_2D, tex_draw);
+ wtu.fillTexture(gl, tex_draw, size, size, [0x0, 0xff, 0xff, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA8);
+ wtu.fillTexture(gl, tex_depth, size, size, [0x80], 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, gl.DEPTH_COMPONENT16);
+ wtu.fillTexture(gl, tex_stencil, size, size, [0x40], 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, gl.DEPTH24_STENCIL8);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_draw, 0);
+ if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("Framebuffer incomplete.");
+ return;
+ } else {
+ testPassed("framebuffer complete!");
+ }
+}
+
+function read() {
+ debug("");
+ debug("read from a color buffer which has no image attached");
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo_read);
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+
+ var data = new Uint8Array(size * size * 4);
+ gl.readPixels(0, 0, size, size, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
+
+ var copy_2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, copy_2d);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, size, size, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, size / 2, size / 2, 0, 0, size / 2, size / 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
+
+ var copy_3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, copy_3d);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, size, size, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, size / 2, size / 2, 0, 0, 0, size / 2, size / 2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when reading from a color buffer without image.");
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(copy_2d);
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.deleteTexture(copy_3d);
+}
+
+function checkTextureValue(fbo, buffer, value) {
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo);
+ gl.readBuffer(buffer);
+ wtu.checkCanvas(gl, value);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+}
+
+function clear() {
+ debug("");
+ debug("clear a color buffer which has no image attached");
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ var color = [0.0, 1.0, 0.0, 1.0];
+ gl.clearColor(color[0], color[1], color[2], color[3]);
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 255, 255]);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 should be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 0, 255]);
+
+ var data = new Float32Array(color);
+ gl.clearBufferfv(gl.COLOR, 1, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+}
+
+function draw() {
+ debug("");
+ debug("draw to a color buffer which has no image attached");
+
+ var program = wtu.setupSimpleColorProgram(gl, 0);
+ gl.uniform4f(gl.getUniformLocation(program, "u_color"), 1, 0, 0, 1);
+ wtu.setupUnitQuad(gl, 0);
+
+ // Call to drawArrays
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 0, 255]);
+
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ wtu.drawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 should be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [255, 0, 0, 255]);
+
+ // Call to drawElements
+ gl.uniform4f(gl.getUniformLocation(program, "u_color"), 1, 1, 0, 1);
+ wtu.setupIndexedQuad(gl, 1);
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ wtu.drawIndexedQuad(gl, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [255, 0, 0, 255]);
+
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ wtu.drawIndexedQuad(gl, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 should be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [255, 255, 0, 255]);
+}
+
+function blit() {
+ debug("");
+ debug("blit color buffer(s) which have no image attached");
+ // Some or all draw buffers have no image. Read buffer have image. It should be OK.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [255, 255, 0, 255]);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 in draw fbo should be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 255, 255]);
+
+ // Draw buffer(s) have no image. Read buffer have no image. It should be OK.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ gl.drawBuffers([gl.NONE, gl.COLOR_ATTACHMENT1]);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 255, 255]);
+
+ // Read buffer have no image. Some or all draw buffers have image. It should generate INVALID_OPERATION.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when read buffer misses image.");
+ // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 255, 255]);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.readBuffer(gl.COLOR_ATTACHMENT1);
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when read buffer misses image.");
+ // The image color at COLOR_ATTACHMENT0 in draw fbo should not be changed.
+ checkTextureValue(fbo_draw, gl.COLOR_ATTACHMENT0, [0, 255, 255, 255]);
+
+ // Depth buffer in read fbo has no image. It should generate INVALID_OPERATION if depth buffer in draw fbo has image.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, tex_depth, 0);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when depth buffer misses image.");
+
+ // Depth buffer in read fbo has no image. It should be OK if depth buffer in draw fbo has no image too.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, null, 0);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // Validate some other parameters as usual
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.DEPTH_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid filter");
+
+ // Stencil buffer in read fbo has no image. It should generate INVALID_OPERATION if stencil buffer in draw fbo has image.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, tex_stencil, 0);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.STENCIL_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should generate INVALID_OPERATION when stencil buffer misses image.");
+
+ // Stencil buffer in read fbo has no image. It should be OK if stencil buffer in draw fbo has no image too.
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, null, 0);
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.STENCIL_BUFFER_BIT, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no error.");
+ // Validate some other parameters as usual
+ gl.blitFramebuffer(0, 0, size, size, 0, 0, size, size, gl.STENCIL_BUFFER_BIT, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid filter");
+}
+
+gl.bindTexture(gl.TEXTURE_2D, null);
+gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+gl.deleteTexture(tex_read);
+gl.deleteTexture(tex_draw);
+gl.deleteTexture(tex_depth);
+gl.deleteTexture(tex_stencil);
+gl.deleteFramebuffer(fbo_read);
+gl.deleteFramebuffer(fbo_draw);
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rgb-format-support.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rgb-format-support.html
new file mode 100644
index 0000000000..46712ae68b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rgb-format-support.html
@@ -0,0 +1,111 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+description("Verify RGB/RGB8 textures and renderbuffers support");
+
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+function testRenderbuffer(width, height) {
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGB8, gl.SAMPLES);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from getInternalformatParameter()");
+
+ if (!samples || samples.length == 0) {
+ testFailed("getInternalformatParameter on RGB8 fails to return valid samples");
+ return;
+ }
+
+ for (var idx = 0; idx < samples.length + 2; ++idx) {
+ debug("");
+ var renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ var sampleCount = 0;
+ switch (idx) {
+ case samples.length:
+ sampleCount = 0;
+ break;
+ case samples.length + 1:
+ sampleCount = -1; // non multisampled
+ break;
+ default:
+ sampleCount = samples[idx];
+ }
+
+ if (sampleCount < 0) {
+ debug("test non-multisampled RGB8 renderbuffer");
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB8, 2, 2);
+ } else {
+ debug("test RGB8 renderbuffer with " + sampleCount + " samples");
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, sampleCount, gl.RGB8, width, height);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from renderbufferStorage{Multisample}");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("framebuffer with renderbuffer is incomplete");
+ } else {
+ testPassed("framebuffer with renderbuffer is complete");
+ }
+
+ gl.clearColor(1, 0, 1, 1);
+ gl.clear(gl.COLOR_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear()");
+ }
+}
+
+function testTexture(width, height) {
+ var formats = [ "RGB", "RGB8" ];
+ for (var idx = 0; idx < formats.length; ++idx) {
+ debug("");
+ debug("test texture format " + formats[idx]);
+ var internalformat = gl[formats[idx]];
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, internalformat, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from texture setup");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
+ testFailed("framebuffer with texture is incomplete");
+ } else {
+ testPassed("framebuffer with texture is complete");
+ }
+
+ gl.clearColor(1, 0, 1, 1);
+ gl.clear(gl.COLOR_BIT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from clear()");
+ }
+}
+
+if (!gl) {
+ testFailed('canvas.getContext() failed');
+} else {
+ testRenderbuffer(2, 2);
+ testTexture(2, 2);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/texture-switch-performance.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/texture-switch-performance.html
new file mode 100644
index 0000000000..da7a9e2f57
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/texture-switch-performance.html
@@ -0,0 +1,101 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Texture 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Ensures that switching the texture referenced by a sampler uniform performs reasonably well.");
+var wtu = WebGLTestUtils;
+var canvas = document.createElement('canvas');
+canvas.width = 32;
+canvas.height = 32;
+var gl = wtu.create3DContext(canvas, undefined, 2);
+if (!gl) {
+ testFailed("context does not exist");
+ finishTest();
+} else {
+ var program = wtu.setupTexturedQuad(gl);
+ var tex = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var tex2 = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var loc = gl.getUniformLocation(program, "tex");
+
+ var RUNTIME = 2000;
+ var THRESHOLD = 0.8;
+ var baseStartTime = 0;
+ var baseFrameCount = 0;
+ var testStartTime = 0;
+ var testFrameCount = 0;
+
+ baseStartTime = Date.now();
+ function drawBaseline() {
+ for (var i = 0; i < 400; ++i) {
+ gl.uniform1i(loc, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ gl.uniform1i(loc, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ ++baseFrameCount;
+
+ if (Date.now() - baseStartTime > RUNTIME) {
+ testStartTime = Date.now();
+ requestAnimationFrame(drawTest);
+ } else {
+ requestAnimationFrame(drawBaseline);
+ }
+ }
+
+ function drawTest() {
+ for (var i = 0; i < 400; ++i) {
+ gl.uniform1i(loc, 0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ gl.uniform1i(loc, 1);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ ++testFrameCount;
+
+ if (Date.now() - testStartTime > RUNTIME) {
+ var perfString = " - achieved " + testFrameCount + " frames in " + ((Date.now() - testStartTime) / 1000.0) +
+ " seconds (" + (testFrameCount / baseFrameCount).toFixed(2) + " times baseline performance)";
+ if (testFrameCount > baseFrameCount * THRESHOLD) {
+ testPassed("Texture switching did not significantly hurt performance" + perfString);
+ } else {
+ testFailed("Texture switching significantly hurt performance" + perfString);
+ }
+ console.log(testFrameCount);
+ finishTest();
+ } else {
+ requestAnimationFrame(drawTest);
+ }
+ }
+
+ requestAnimationFrame(drawBaseline);
+}
+var successfullyParsed = true;
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/uniform-block-buffer-size.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/uniform-block-buffer-size.html
new file mode 100644
index 0000000000..35cc5205d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/uniform-block-buffer-size.html
@@ -0,0 +1,228 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL UniformBlock Buffer Size Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id='vshader' type='x-shader/x-vertex'>#version 300 es
+layout(location=0) in vec3 p;
+void main()
+{
+ gl_Position = vec4(p.xyz, 1.0);
+}
+</script>
+<script id='fshader' type='x-shader/x-fragment'>#version 300 es
+precision mediump float;
+layout(location=0) out vec4 oColor;
+
+uniform UBOData {
+ float UBORed;
+ float UBOGreen;
+ float UBOBlue;
+};
+
+void main()
+{
+ oColor = vec4(UBORed, UBOGreen, UBOBlue, 1.0);
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies an active UniformBlock should be populated with a large enough buffer object");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runDrawArraysTests();
+ runDrawElementsTests();
+}
+
+function runDrawArraysTests() {
+ debug("");
+ debug("Testing drawArrays and drawArraysInstanced");
+
+ var instanceCount = 4;
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ if (!program) {
+ testFailed("Could not compile shader with uniform blocks without error");
+ return;
+ }
+
+ var blockIndex = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices = gl.getUniformIndices(program, ["UBORed", "UBOGreen", "UBOBlue"]);
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ var uboArray = new ArrayBuffer(blockSize);
+ var uboFloatView = new Float32Array(uboArray);
+ uboFloatView[uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBORed
+ uboFloatView[uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOGreen
+ uboFloatView[uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOBlue
+
+ var binding = 1;
+ gl.uniformBlockBinding(program, blockIndex, binding);
+
+ wtu.setupUnitQuad(gl);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up succeeded");
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArrays: UniformBlock is not backed by a buffer");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArraysInstanced: UniformBlock is not backed by a buffer");
+
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, buffer);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArrays: UniformBlock is backed by a buffer with no data store");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArraysInstanced: UniformBlock is backed by a buffer with no data store");
+
+ var arrayNotLargeEnough = new ArrayBuffer(blockSize - 1);
+ gl.bufferData(gl.UNIFORM_BUFFER, arrayNotLargeEnough, gl.DYNAMIC_DRAW);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArrays: UniformBlock not populated with a large enough buffer");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArraysInstanced: UniformBlock not populated with a large enough buffer");
+
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView, gl.DYNAMIC_DRAW);
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays: should be able to draw with sufficient data for UniformBlock");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstanced: should be able to draw with sufficient data for UniformBlock");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, binding, buffer, 0, blockSize -1);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArrays: bindBufferRange set size too small for UniformBlock");
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArraysInstanced: bindBufferRange set size too small for UniformBlock");
+}
+
+function runDrawElementsTests() {
+ debug("");
+ debug("Testing drawElements, drawRangeElements and drawElementsInstanced");
+
+ var instanceCount = 4;
+
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
+ if (!program) {
+ testFailed("Could not compile shader with uniform blocks without error");
+ return;
+ }
+
+ var blockIndex = gl.getUniformBlockIndex(program, "UBOData");
+ var blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ var uniformIndices = gl.getUniformIndices(program, ["UBORed", "UBOGreen", "UBOBlue"]);
+ var uniformOffsets = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_OFFSET);
+
+ if (uniformOffsets.length < 3) {
+ testFailed("Could not query uniform offsets");
+ return;
+ }
+
+ var uboArray = new ArrayBuffer(blockSize);
+ var uboFloatView = new Float32Array(uboArray);
+ uboFloatView[uniformOffsets[0] / Float32Array.BYTES_PER_ELEMENT] = 1.0; // UBORed
+ uboFloatView[uniformOffsets[1] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOGreen
+ uboFloatView[uniformOffsets[2] / Float32Array.BYTES_PER_ELEMENT] = 0.0; // UBOBlue
+
+ var binding = 1;
+ gl.uniformBlockBinding(program, blockIndex, binding);
+
+ wtu.setupIndexedQuad(gl, 1, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up succeeded");
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
+
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElements: UniformBlock is not backed by a buffer");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawRangeElements: UniformBlock is not backed by a buffer");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElementsInstanced: UniformBlock is not backed a buffer");
+
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, binding, buffer);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElements: UniformBlock is populated with a buffer with no data store");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawRangeElements: UniformBlock is populated with a buffer with no data store");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElementsInstanced: UniformBlock is populated with a buffer with no data store");
+
+ var arrayNotLargeEnough = new ArrayBuffer(blockSize - 1);
+ gl.bufferData(gl.UNIFORM_BUFFER, arrayNotLargeEnough, gl.DYNAMIC_DRAW);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElements: UniformBlock not populated with a large enough buffer");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawRangeElements: UniformBlock not populated with a large enough buffer");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElementsInstanced: UniformBlock not populated with a large enough buffer");
+
+ gl.bufferData(gl.UNIFORM_BUFFER, uboFloatView, gl.DYNAMIC_DRAW);
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements: should be able to draw with sufficient data for UniformBlock");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawRangeElements: should be able to draw with sufficient data for UniformBlock");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstanced: should be able to draw with sufficient data for UniformBlock");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "draw call should set canvas to red", 2);
+
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, binding, buffer, 0, blockSize -1);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElements: bindBufferRange set size too small for UniformBlock");
+ gl.drawRangeElements(gl.TRIANGLES, 0, 5, 6, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawRangeElements: bindBufferRange set size too small for UniformBlock");
+ gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElementsInstanced: bindBufferRange set size too small for UniformBlock");
+}
+
+debug("");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id-large-count.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id-large-count.html
new file mode 100644
index 0000000000..a68f5d911c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id-large-count.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 gl_VertexID Large Count Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!-- Shaders for testing instanced draws -->
+<script id="vs" type="text/plain">
+#version 300 es
+
+uniform ivec2 resolution;
+void main() {
+ ivec2 pixel = ivec2(
+ gl_VertexID % resolution.x,
+ gl_VertexID / resolution.x);
+ vec2 xy = (vec2(pixel) + 0.5) / vec2(resolution) * 2.0 - 1.0;
+
+ gl_Position = vec4(xy, 0, 1);
+ gl_PointSize = 1.0;
+}
+</script>
+<script id="fs" type="text/plain">
+#version 300 es
+precision mediump float;
+uniform vec4 color;
+out vec4 fragColor;
+void main() {
+ fragColor = color;
+}
+</script>
+
+<script>
+"use strict";
+description("Test gl_VertexID");
+
+debug("");
+
+const wtu = WebGLTestUtils;
+const canvas = document.createElement("canvas");
+const size = 2048;
+canvas.width = size;
+canvas.height = size;
+const gl = wtu.create3DContext(canvas, null, 2);
+
+// document.body.appendChild(gl.canvas);
+// gl.canvas.style.background = 'yellow';
+// gl.canvas.style.margin = '20px';
+// const ext = gl.getExtension('WEBGL_debug_renderer_info');
+// if (ext) {
+// debug(gl.getParameter(ext.UNMASKED_RENDERER_WEBGL));
+// }
+
+(function() {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+ testPassed("WebGL context exists");
+
+ const vs = document.getElementById("vs").innerHTML.trim();
+ const fs = document.getElementById("fs").innerHTML.trim();
+ const prog = wtu.loadProgram(gl, vs, fs);
+ gl.useProgram(prog);
+ const resolutionLoc = gl.getUniformLocation(prog, 'resolution');
+ const colorLoc = gl.getUniformLocation(prog, 'color');
+
+ // -
+
+ debug("");
+ debug("----------------");
+ debug("drawArrays");
+
+ const u8Color = c => c.map(v => v * 255 | 0);
+ const transparentBlack = [0, 0, 0, 0];
+ const red = [1, 0, 0, 1];
+ const green = [0, 1, 0, 1];
+ const blue = [0, 0, 1, 1];
+
+ const test = function(first, count, color) {
+ debug("");
+ debug(`drawArrays(first: ${first}, count: ${count})`);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.uniform4fv(colorLoc, color);
+ gl.uniform2i(resolutionLoc, size, size);
+ gl.drawArrays(gl.POINTS, first, count);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ const y = first / size;
+ const height = count / size;
+
+ // The shader draws 1 pixel points by looking at gl_VertexID
+ // as a 1D index into a 2D array. In other words
+ // row = gl_VertexID / width;
+ // col = gl_VertexID % width;
+ // Setting first to a value of rows * width (ie, y * size)
+ // lets us skip y rows when drawing so we then check that
+ // from y to height rows are the expected color and everything
+ // else is the cleared color.
+ wtu.checkCanvasRect(gl, 0, y, size, height, u8Color(color));
+ wtu.checkCanvasRect(gl, 0, 0, size, size - height, transparentBlack);
+ };
+
+ test(0, size * size, red);
+ test(size * size / 2, size * size / 2, green);
+ test(size * size / 4, size * size / 4 * 3, blue);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "There should be no remaining errors");
+})();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
+<!--
+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.
+-->
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id.html b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id.html
new file mode 100644
index 0000000000..ec4bd05ad4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 gl_VertexID Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<!-- Shaders for testing instanced draws -->
+<script id="vs" type="text/plain">
+#version 300 es
+flat out highp int vVertexID;
+
+void main() {
+ vVertexID = gl_VertexID;
+ gl_PointSize = 1.0;
+ gl_Position = vec4(0,0,0,1);
+}
+</script>
+<script id="fs" type="text/plain">
+#version 300 es
+flat in highp int vVertexID;
+out highp int oVertexID;
+void main() {
+ oVertexID = vVertexID;
+}
+</script>
+
+<script>
+"use strict";
+description("Test gl_VertexID");
+
+debug("");
+
+const wtu = WebGLTestUtils;
+const canvas = document.createElement("canvas");
+canvas.width = 1;
+canvas.height = 1;
+const gl = wtu.create3DContext(canvas, null, 2);
+
+(function() {
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+ testPassed("WebGL context exists");
+
+ const vs = document.getElementById("vs").innerHTML.trim();
+ const fs = document.getElementById("fs").innerHTML.trim();
+ const prog = wtu.loadProgram(gl, vs, fs);
+ gl.useProgram(prog);
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32I, 1, 1);
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after setup");
+
+ function shouldBeVal(prefix, expected, was) {
+ let text = prefix + "Should be " + expected;
+ let func = testPassed;
+ if (was != expected) {
+ text = text + ", was " + was;
+ func = testFailed;
+ }
+ func(text);
+ };
+
+ const readValData = new Int32Array(10000);
+ function ensureVal(prefix, expected) {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, gl.INT, readValData);
+ const was = readValData[0];
+ shouldBeVal(prefix, expected, was);
+ };
+
+ gl.clearBufferiv(gl.COLOR, 0, new Int32Array([42, 0, 0, 0]));
+ ensureVal("After clear", 42);
+
+ // -
+
+ debug("");
+ debug("----------------");
+ debug("drawArrays");
+
+ let test = function(first, count) {
+ debug("");
+ debug(`drawArrays(first: ${first}, count: ${count})`);
+ gl.drawArrays(gl.POINTS, first, count);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ ensureVal("", first+count-1);
+ };
+
+ test(0, 1);
+ test(1, 1);
+ test(10000, 1);
+ test(100000, 1);
+ test(1000000, 1);
+
+ test(0, 2);
+ test(1, 2);
+ test(10000, 2);
+ test(100000, 2);
+ test(1000000, 2);
+
+ const INT32_MAX = 0x7fffffff;
+
+ test = function(first, count) {
+ debug("");
+ debug(`drawArrays(first: ${first}, count: ${count})`);
+ gl.drawArrays(gl.POINTS, first, count);
+ if (!wtu.glErrorShouldBe(gl, [gl.NO_ERROR, gl.OUT_OF_MEMORY])) {
+ ensureVal("", first+count-1);
+ }
+ };
+
+ test(INT32_MAX-2, 1);
+ test(INT32_MAX-1, 1);
+ test(INT32_MAX, 1);
+
+ // -
+
+ debug("");
+ debug("----------------");
+ debug("drawElements");
+
+ const indexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ const indexData = new Uint16Array([1, 2, 5, 3, 10000]);
+ debug("indexData: " + indexData);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
+
+ test = function(first, count) {
+ debug("");
+ debug(`drawElements(first: ${first}, count: ${count})`);
+ gl.drawElements(gl.POINTS, count, gl.UNSIGNED_SHORT, first*2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ ensureVal("", indexData[first+count-1]);
+ };
+
+ for (let f = 0; f < indexData.length; ++f) {
+ for (let c = 1; f + c <= indexData.length; ++c) {
+ test(f, c);
+ }
+ }
+
+ // -
+
+ debug("");
+ debug("----------------");
+ debug("Via transform feedback");
+
+ gl.transformFeedbackVaryings(prog, ["vVertexID"], gl.INTERLEAVED_ATTRIBS);
+ wtu.linkProgram(gl, prog);
+ gl.useProgram(prog);
+
+ const tfBuffer = gl.createBuffer();
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*10000, gl.DYNAMIC_READ);
+
+ test = function(offset, count) {
+ debug("");
+ debug("drawArrays(" + offset + ", " + count + ")");
+ gl.beginTransformFeedback(gl.POINTS);
+ gl.drawArrays(gl.POINTS, offset, count);
+ gl.endTransformFeedback();
+ gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, readValData);
+ let ok = true;
+ for (let i = 0; i < readValData.length; i++) {
+ if (i >= count)
+ break;
+ const expected = offset + i;
+ const was = readValData[i];
+ if (was != expected) {
+ testFailed("[" + i + "] expected " + expected + ", was " + was);
+ ok = false;
+ break;
+ }
+ }
+ if (ok) {
+ testPassed("ok");
+ }
+ };
+
+ test(0, 1);
+ test(1, 1);
+ test(10000, 1);
+
+ test(0, 2);
+ test(1, 2);
+ test(10000, 2);
+
+ test(10000, 10000);
+
+ // -
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "There should be no remaining errors");
+})();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
+<!--
+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.
+-->
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/00_test_list.txt
new file mode 100644
index 0000000000..eeca822298
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/00_test_list.txt
@@ -0,0 +1,3 @@
+--min-version 2.0.1 multi-context-sampler-test.html
+samplers.html
+sampler-drawing-test.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/multi-context-sampler-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/multi-context-sampler-test.html
new file mode 100644
index 0000000000..05e0f20480
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/multi-context-sampler-test.html
@@ -0,0 +1,84 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Multi-Context Sampler 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>
+</head>
+<body>
+<canvas id="canvas_drawing" width="12" height="12"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Tests that samplers' state doesn't leak across contexts");
+debug("");
+debug('Regression test for <a href="http://crbug.com/713127">http://crbug.com/713127</a>');
+
+function runTest() {
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("canvas_drawing", undefined, 2);
+ var texture = null;
+ var color = [0, 255, 0, 255];
+
+ if (!gl) {
+ testFailed("WebGL context does not exist");
+ return;
+ }
+
+ testPassed("WebGL context exists");
+
+ wtu.setupTexturedQuad(gl);
+ texture = gl.createTexture();
+ // Create a texture bigger than 1x1 so that it would need mipmaps in
+ // order to be complete.
+ wtu.fillTexture(gl, texture, 2, 2, color, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA8);
+ // Set texture parameters so that this texture is complete.
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ // Set up a secondary context with a sampler bound to texture unit
+ // 0. This should not interfere with the primary context.
+ var altGL = wtu.create3DContext(undefined, undefined, 2);
+ if (!altGL) {
+ testFailed("Error creating secondary WebGL context");
+ return;
+ }
+
+ var sampler = altGL.createSampler();
+ // Note that the sampler's default TEXTURE_MIN_FILTER is
+ // NEAREST_MIPMAP_LINEAR.
+ altGL.bindSampler(0, sampler);
+ altGL.clearColor(1, 0, 0, 1);
+ altGL.clear(altGL.COLOR_BUFFER_BIT);
+ wtu.checkCanvasRect(altGL, 0, 0, 1, 1, [ 255, 0, 0, 255 ],
+ "should be red");
+
+ // Now switch back to the main context and draw the texture.
+ gl.clearColor(1, 1, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ wtu.drawUnitQuad(gl);
+ // The presence of the sampler on the other context should not
+ // have interfered with the completeness of the texture.
+ wtu.checkCanvasRect(gl, 0, 0, 1, 1, color,
+ "should be green");
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+runTest();
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/sampler-drawing-test.html b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/sampler-drawing-test.html
new file mode 100644
index 0000000000..ec6aa515ef
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/sampler-drawing-test.html
@@ -0,0 +1,124 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Sampler Drawing 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>
+</head>
+<body>
+<canvas id="canvas_drawing" width="12" height="12"></canvas>
+<canvas id="canvas_texture" width="2" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Tests drawing with sampler works as expected");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas_drawing", null, 2);
+var canvas_texture = null;
+var samplerParam = [
+ gl.REPEAT,
+ gl.CLAMP_TO_EDGE,
+ gl.MIRRORED_REPEAT,
+];
+var color = [200, 0, 254, 255];
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ wtu.setupTexturedQuadWithTexCoords(gl, [-2.5, -2.5], [3.5, 3.5]);
+
+ setupCanvasTexture();
+ for (var ii = 0; ii < samplerParam.length; ++ii) {
+ runDrawingTest(samplerParam[ii]);
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function setupCanvasTexture() {
+ canvas_texture = document.getElementById("canvas_texture");
+ var ctx2d = canvas_texture.getContext("2d");
+ ctx2d.fillStyle = "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + color[3] + ")";
+ ctx2d.fillRect(0, 0, 1, 1);
+}
+
+function runDrawingTest(param) {
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas_texture);
+
+ var sampler = gl.createSampler();
+ gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, param);
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_T, param);
+
+ gl.clearColor(1,1,1,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.bindSampler(0, sampler);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 6);
+
+ checkPixels(param);
+}
+
+function checkPixels(param) {
+ var buf = new Uint8Array(12 * 12 * 4);
+ gl.readPixels(0, 0, 12, 12, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var passed = true;
+ for (var yy = 0; yy < 12; ++yy) {
+ for (var xx = 0; xx < 12; ++xx) {
+ var ec = [0, 0, 0, 0];
+ switch (param) {
+ case gl.REPEAT:
+ if (xx % 2 == 1 && yy % 2 == 1) {
+ ec = color;
+ }
+ break;
+ case gl.CLAMP_TO_EDGE:
+ if (xx < 6 && yy < 6) {
+ ec = color;
+ }
+ break;
+ case gl.MIRRORED_REPEAT:
+ if (xx % 4 < 2 && yy % 4 < 2) {
+ ec = color;
+ }
+ break;
+ }
+ var off = (yy * 12 + xx) * 4;
+ if (buf[off + 0] != ec[0] || buf[off + 1] != ec[1] ||
+ buf[off + 2] != ec[2] || buf[off + 3] != ec[3]) {
+ var msg = 'at (' + xx + ', ' + yy + ') expected: ' +
+ ec[0] + ', ' + ec[1] + ', ' + ec[2] + ', ' + ec[3] + ' found: ' +
+ buf[off + 0] + ', ' + buf[off + 1] + ', ' + buf[off + 2] + ', ' + buf[off + 3];
+ testFailed(msg);
+ passed = false;
+ }
+ }
+ }
+ if (passed) {
+ testPassed("Drawing with wrap " + wtu.glEnumToString(gl, param) + " as expected");
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/samplers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/samplers.html
new file mode 100644
index 0000000000..e6fbc69011
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/samplers/samplers.html
@@ -0,0 +1,230 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Sampler Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+"use strict";
+description("This test verifies the functionality of the Sampler objects.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var s = null;
+var s1 = null;
+var s2 = null;
+var testCases = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runBindingTest();
+ runObjectTest();
+ runParameterTest();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function runBindingTest() {
+ debug("Testing binding enum");
+
+ shouldBe("gl.SAMPLER_BINDING", "0x8919");
+
+ // Default value is null
+ shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "SAMPLER_BINDING query should succeed");
+
+ debug("Testing binding a Sampler object");
+ s1 = gl.createSampler();
+ s2 = gl.createSampler();
+ gl.bindSampler(0, s1);
+ shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "s1");
+ gl.bindSampler(0, s2);
+ shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "s2");
+
+ // Bindings should not affect other units.
+ gl.bindSampler(1, s1);
+ shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "s2");
+ gl.activeTexture(gl.TEXTURE1);
+ shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "s1");
+ gl.activeTexture(gl.TEXTURE0);
+
+ // Should be able to bind a single sampler to multiple texture units.
+ gl.bindSampler(0, s1);
+ shouldBe("gl.getParameter(gl.SAMPLER_BINDING)", "s1");
+
+ // Deleting samplers should unbind them.
+ gl.deleteSampler(s1);
+ gl.deleteSampler(s2);
+ shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+ gl.activeTexture(gl.TEXTURE1);
+ shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+ gl.activeTexture(gl.TEXTURE0);
+
+ // Shouldn't be able to bind a deleted sampler.
+ gl.bindSampler(0, s2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted Sampler object");
+ gl.bindSampler(0, null);
+ shouldBeNull("gl.getParameter(gl.SAMPLER_BINDING)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runObjectTest() {
+ debug("Testing object creation");
+
+ s1 = gl.createSampler();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createSampler should not set an error");
+ shouldBeNonNull("s1");
+
+ // Expect true, even if never bound
+ shouldBeTrue("gl.isSampler(s1)");
+ gl.bindSampler(0, s1);
+ shouldBeTrue("gl.isSampler(s1)");
+ gl.bindSampler(0, null);
+ shouldBeTrue("gl.isSampler(s1)");
+ gl.deleteSampler(s1);
+ shouldBeFalse("gl.isSampler(s1)");
+
+ shouldBeFalse("gl.isSampler(null)");
+
+ s1 = null;
+}
+
+function runParameterTest() {
+ debug("Testing getSamplerParameter and samplerParameter[if]");
+
+ s = gl.createSampler();
+ gl.bindSampler(0, s);
+
+ debug("Checking default param for getSamplerParameter");
+
+ testCases = [
+ { pname: gl.TEXTURE_WRAP_S, defaultParam: gl.REPEAT },
+ { pname: gl.TEXTURE_WRAP_T, defaultParam: gl.REPEAT },
+ { pname: gl.TEXTURE_WRAP_R, defaultParam: gl.REPEAT },
+ { pname: gl.TEXTURE_MIN_FILTER, defaultParam: gl.NEAREST_MIPMAP_LINEAR },
+ { pname: gl.TEXTURE_MAG_FILTER, defaultParam: gl.LINEAR },
+ { pname: gl.TEXTURE_COMPARE_MODE, defaultParam: gl.NONE },
+ { pname: gl.TEXTURE_COMPARE_FUNC, defaultParam: gl.LEQUAL },
+ { pname: gl.TEXTURE_MIN_LOD, defaultParam: -1000 },
+ { pname: gl.TEXTURE_MAX_LOD, defaultParam: 1000 },
+ ];
+
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var pname = testCases[ii].pname;
+ var defaultParam = testCases[ii].defaultParam;
+ shouldBe("gl.getSamplerParameter(s, " + pname + ")", defaultParam.toString());
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+
+ debug("Checking valid pname and param for samplerParameteri");
+
+ testCases = [
+ { pname: gl.TEXTURE_WRAP_S, param: gl.REPEAT },
+ { pname: gl.TEXTURE_WRAP_S, param: gl.MIRRORED_REPEAT },
+ { pname: gl.TEXTURE_WRAP_S, param: gl.CLAMP_TO_EDGE },
+ { pname: gl.TEXTURE_WRAP_T, param: gl.REPEAT },
+ { pname: gl.TEXTURE_WRAP_T, param: gl.MIRRORED_REPEAT },
+ { pname: gl.TEXTURE_WRAP_T, param: gl.CLAMP_TO_EDGE },
+ { pname: gl.TEXTURE_WRAP_R, param: gl.REPEAT },
+ { pname: gl.TEXTURE_WRAP_R, param: gl.MIRRORED_REPEAT },
+ { pname: gl.TEXTURE_WRAP_R, param: gl.CLAMP_TO_EDGE },
+ { pname: gl.TEXTURE_MIN_FILTER, param: gl.NEAREST },
+ { pname: gl.TEXTURE_MIN_FILTER, param: gl.LINEAR },
+ { pname: gl.TEXTURE_MIN_FILTER, param: gl.NEAREST_MIPMAP_NEAREST },
+ { pname: gl.TEXTURE_MIN_FILTER, param: gl.NEAREST_MIPMAP_LINEAR },
+ { pname: gl.TEXTURE_MIN_FILTER, param: gl.LINEAR_MIPMAP_NEAREST },
+ { pname: gl.TEXTURE_MIN_FILTER, param: gl.LINEAR_MIPMAP_LINEAR },
+ { pname: gl.TEXTURE_MAG_FILTER, param: gl.NEAREST },
+ { pname: gl.TEXTURE_MAG_FILTER, param: gl.LINEAR },
+ { pname: gl.TEXTURE_COMPARE_MODE, param: gl.NONE },
+ { pname: gl.TEXTURE_COMPARE_MODE, param: gl.COMPARE_REF_TO_TEXTURE },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.LEQUAL },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.GEQUAL },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.LESS },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.GREATER },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.EQUAL },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.NOTEQUAL },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.ALWAYS },
+ { pname: gl.TEXTURE_COMPARE_FUNC, param: gl.NEVER },
+ ];
+
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var pname = testCases[ii].pname;
+ var param = testCases[ii].param;
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.samplerParameteri(s, " + pname + ", " + param + ")");
+ shouldBe("gl.getSamplerParameter(s, " + pname + ")", param);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+
+ debug("Checking valid pname and param for samplerParameterf");
+ testCases = [
+ { pname: gl.TEXTURE_MIN_LOD, param: -500 },
+ { pname: gl.TEXTURE_MIN_LOD, param: 0 },
+ { pname: gl.TEXTURE_MIN_LOD, param: 10.0 },
+ { pname: gl.TEXTURE_MAX_LOD, param: 500 },
+ { pname: gl.TEXTURE_MAX_LOD, param: 0 },
+ { pname: gl.TEXTURE_MAX_LOD, param: 10.0 },
+ ];
+
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var pname = testCases[ii].pname;
+ var param = testCases[ii].param;
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.samplerParameterf(s, " + pname + ", " + param + ")");
+ shouldBe("gl.getSamplerParameter(s, " + pname + ")", param.toString());
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+
+ debug("Checking invalid pname and param");
+
+ testCases = [
+ { pname: gl.TEXTURE_IMMUTABLE_FORMAT, param: null, expectedError: gl.INVALID_ENUM },
+ { pname: gl.TEXTURE_BASE_LEVEL, param: null, expectedError: gl.INVALID_ENUM },
+ { pname: gl.TEXTURE_MAX_LEVEL, param: null, expectedError: gl.INVALID_ENUM },
+ { pname: gl.TEXTURE_WRAP_S, param: 0x812D,/* GL_CLAMP_TO_BORDER */ expectedError: gl.INVALID_ENUM },
+ { pname: gl.TEXTURE_WRAP_T, param: 0x812D,/* GL_CLAMP_TO_BORDER */ expectedError: gl.INVALID_ENUM },
+ { pname: gl.TEXTURE_MAG_FILTER, param: gl.LINEAR_MIPMAP_NEAREST, expectedError: gl.INVALID_ENUM },
+ ];
+
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var pname = testCases[ii].pname;
+ var param = testCases[ii].param;
+ var expectedError = testCases[ii].expectedError;
+ if (param == null) {
+ wtu.shouldGenerateGLError(gl, expectedError, "gl.getSamplerParameter(s, " + pname + ")");
+ } else {
+ wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.getSamplerParameter(s, " + pname + ")");
+ }
+ wtu.shouldGenerateGLError(gl, expectedError, "gl.samplerParameteri(s, " + pname + ", " + param + ")");
+ wtu.shouldGenerateGLError(gl, expectedError, "gl.samplerParameterf(s, " + pname + ", " + param + ")");
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/state/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/state/00_test_list.txt
new file mode 100644
index 0000000000..5bbd184e4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/state/00_test_list.txt
@@ -0,0 +1,4 @@
+gl-enum-tests.html
+gl-get-calls.html
+gl-getstring.html
+gl-object-get-calls.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-enum-tests.html b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-enum-tests.html
new file mode 100644
index 0000000000..76ff4b5b5f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-enum-tests.html
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL gl enums Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/desktop-gl-constants.js"></script>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script src="../../js/test-eval.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/gl-enum-tests.js"></script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-get-calls.html b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-get-calls.html
new file mode 100644
index 0000000000..6f0991a9d2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-get-calls.html
@@ -0,0 +1,177 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL gl calls Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("This test ensures getParameter is working correct with WebGL 2 pnames");
+
+debug("");
+debug("Canvas.getContext");
+
+var minimumRequiredStencilMask = 0;
+var wtu = WebGLTestUtils;
+var context = wtu.create3DContext("canvas", null, 2);
+if (!context)
+ testFailed("context does not exist");
+else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Context contains getError");
+ if ("getError" in context)
+ testPassed("context contains getError");
+ else
+ testFailed("context does not contains getError");
+
+ debug("");
+ debug("Check default values");
+
+ shouldBe('context.getParameter(context.COPY_READ_BUFFER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.COPY_WRITE_BUFFER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.DRAW_BUFFER0)', 'context.BACK');
+ shouldBe('context.getParameter(context.DRAW_FRAMEBUFFER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.FRAGMENT_SHADER_DERIVATIVE_HINT)', 'context.DONT_CARE');
+ shouldBe('context.getParameter(context.PACK_ROW_LENGTH)', '0');
+ shouldBe('context.getParameter(context.PACK_SKIP_PIXELS)', '0');
+ shouldBe('context.getParameter(context.PACK_SKIP_ROWS)', '0');
+ shouldBe('context.getParameter(context.PIXEL_PACK_BUFFER_BINDING)', 'null');
+
+ shouldBe('context.getParameter(context.PIXEL_UNPACK_BUFFER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.RASTERIZER_DISCARD)', 'false');
+ shouldBe('context.getParameter(context.READ_BUFFER)', 'context.BACK');
+ shouldBe('context.getParameter(context.READ_FRAMEBUFFER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.SAMPLE_ALPHA_TO_COVERAGE)', 'false');
+ shouldBe('context.getParameter(context.SAMPLE_COVERAGE)', 'false');
+ shouldBe('context.getParameter(context.SAMPLER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.TEXTURE_BINDING_2D_ARRAY)', 'null');
+ shouldBe('context.getParameter(context.TEXTURE_BINDING_3D)', 'null');
+ shouldBe('context.getParameter(context.TRANSFORM_FEEDBACK_ACTIVE)', 'false');
+ shouldBe('context.getParameter(context.TRANSFORM_FEEDBACK_BINDING)', 'null');
+ shouldBe('context.getParameter(context.TRANSFORM_FEEDBACK_BUFFER_BINDING)', 'null');
+ shouldBe('context.getParameter(context.TRANSFORM_FEEDBACK_PAUSED)', 'false');
+ shouldBe('context.getParameter(context.UNIFORM_BUFFER_BINDING)', 'null');
+
+ shouldBe('context.getParameter(context.UNPACK_IMAGE_HEIGHT)', '0');
+ shouldBe('context.getParameter(context.UNPACK_ROW_LENGTH)', '0');
+ shouldBe('context.getParameter(context.UNPACK_SKIP_IMAGES)', '0');
+ shouldBe('context.getParameter(context.UNPACK_SKIP_PIXELS)', '0');
+ shouldBe('context.getParameter(context.UNPACK_SKIP_ROWS)', '0');
+ shouldBe('context.getParameter(context.VERTEX_ARRAY_BINDING)', 'null');
+
+ debug("");
+ debug("Check minimum values");
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_3D_TEXTURE_SIZE)', '256');
+ shouldBeType('context.getParameter(context.MAX_3D_TEXTURE_SIZE)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_ARRAY_TEXTURE_LAYERS)', '256');
+ shouldBeType('context.getParameter(context.MAX_ARRAY_TEXTURE_LAYERS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_CLIENT_WAIT_TIMEOUT_WEBGL)', '0');
+ shouldBeType('context.getParameter(context.MAX_CLIENT_WAIT_TIMEOUT_WEBGL)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_COLOR_ATTACHMENTS)', '4');
+ shouldBeType('context.getParameter(context.MAX_COLOR_ATTACHMENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_COMBINED_UNIFORM_BLOCKS)', '24');
+ shouldBeType('context.getParameter(context.MAX_COMBINED_UNIFORM_BLOCKS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_DRAW_BUFFERS)', '4');
+ shouldBeType('context.getParameter(context.MAX_DRAW_BUFFERS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_ELEMENT_INDEX)', '16777215'); // 2^24 - 1
+ shouldBeType('context.getParameter(context.MAX_ELEMENT_INDEX)', 'Number');
+
+ shouldBeType('context.getParameter(context.MAX_ELEMENTS_INDICES)', 'Number');
+ shouldBeType('context.getParameter(context.MAX_ELEMENTS_VERTICES)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS)', '60');
+ shouldBeType('context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_FRAGMENT_UNIFORM_BLOCKS)', '12');
+ shouldBeType('context.getParameter(context.MAX_FRAGMENT_INPUT_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_FRAGMENT_UNIFORM_COMPONENTS)', '896');
+ shouldBeType('context.getParameter(context.MAX_FRAGMENT_UNIFORM_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_PROGRAM_TEXEL_OFFSET)', '7');
+ shouldBeType('context.getParameter(context.MAX_PROGRAM_TEXEL_OFFSET)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_SAMPLES)', '4');
+ shouldBeType('context.getParameter(context.MAX_PROGRAM_TEXEL_OFFSET)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_SERVER_WAIT_TIMEOUT)', '0');
+ shouldBeType('context.getParameter(context.MAX_SERVER_WAIT_TIMEOUT)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_TEXTURE_LOD_BIAS)', '2.0');
+ shouldBeType('context.getParameter(context.MAX_TEXTURE_LOD_BIAS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)', '64');
+ shouldBeType('context.getParameter(context.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)', '4');
+ shouldBeType('context.getParameter(context.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)', '4');
+ shouldBeType('context.getParameter(context.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_UNIFORM_BLOCK_SIZE)', '16384');
+ shouldBeType('context.getParameter(context.MAX_UNIFORM_BLOCK_SIZE)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_UNIFORM_BUFFER_BINDINGS)', '24');
+ shouldBeType('context.getParameter(context.MAX_UNIFORM_BUFFER_BINDINGS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_VARYING_COMPONENTS)', '60');
+ shouldBeType('context.getParameter(context.MAX_VARYING_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_VERTEX_OUTPUT_COMPONENTS)', '64');
+ shouldBeType('context.getParameter(context.MAX_VERTEX_OUTPUT_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_VERTEX_UNIFORM_BLOCKS)', '12');
+ shouldBeType('context.getParameter(context.MAX_VERTEX_UNIFORM_BLOCKS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_VERTEX_UNIFORM_COMPONENTS)', '1024');
+ shouldBeType('context.getParameter(context.MAX_VERTEX_UNIFORM_COMPONENTS)', 'Number');
+
+ shouldBeLessThanOrEqual('context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET)', '-8');
+ shouldBeType('context.getParameter(context.MIN_PROGRAM_TEXEL_OFFSET)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.UNIFORM_BUFFER_OFFSET_ALIGNMENT)', '1');
+ shouldBeType('context.getParameter(context.UNIFORM_BUFFER_OFFSET_ALIGNMENT)', 'Number');
+
+ var minCombinedFragmentUniformComponents = context.getParameter(context.MAX_FRAGMENT_UNIFORM_BLOCKS) * context.getParameter(context.MAX_UNIFORM_BLOCK_SIZE) / 4 + context.getParameter(context.MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ var minCombinedVertexUniformComponents = context.getParameter(context.MAX_VERTEX_UNIFORM_BLOCKS) * context.getParameter(context.MAX_UNIFORM_BLOCK_SIZE) / 4 + context.getParameter(context.MAX_VERTEX_UNIFORM_COMPONENTS);
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS)', minCombinedFragmentUniformComponents + '');
+ shouldBeType('context.getParameter(context.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS)', 'Number');
+
+ shouldBeGreaterThanOrEqual('context.getParameter(context.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS)', minCombinedVertexUniformComponents + '');
+ shouldBeType('context.getParameter(context.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS)', 'Number');
+
+ shouldBe('context.getError()', 'context.NO_ERROR');
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-getstring.html b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-getstring.html
new file mode 100644
index 0000000000..2e494589eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-getstring.html
@@ -0,0 +1,60 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL gl.getParameter Strings Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("This test checks getParameter returns strings in the correct format");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", null, 2);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ checkPrefix("WebGL 2.0", "VERSION");
+ checkPrefix("WebGL GLSL ES 3.00", "SHADING_LANGUAGE_VERSION");
+ shouldBeNonNull("gl.getParameter(gl.VENDOR)");
+ shouldBeNonNull("gl.getParameter(gl.RENDERER)");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+}
+
+function checkPrefix(expected, enum_val) {
+ var s = gl.getParameter(gl[enum_val]);
+ if (s != null &&
+ s.length >= expected.length &&
+ s.substring(0, expected.length) == expected) {
+ testPassed("getParameter(gl." + enum_val + ") correctly started with " + expected);
+ } else {
+ testFailed("getParameter(gl." + enum_val + ") did not start with " + expected);
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-object-get-calls.html b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-object-get-calls.html
new file mode 100644
index 0000000000..62ed70d5bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-object-get-calls.html
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../js/tests/gl-object-get-calls.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/sync/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/sync/00_test_list.txt
new file mode 100644
index 0000000000..474af6c765
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/sync/00_test_list.txt
@@ -0,0 +1 @@
+sync-webgl-specific.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/sync/sync-webgl-specific.html b/dom/canvas/test/webgl-conf/checkout/conformance2/sync/sync-webgl-specific.html
new file mode 100644
index 0000000000..a9ec78e3be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/sync/sync-webgl-specific.html
@@ -0,0 +1,156 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 specific sync object behaviors</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+description("This test checks WebGL2 specific sync object behaviors");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas", null, 2);
+var sync = null;
+var pixel = new Uint8Array(4);
+
+if (!gl) {
+ testFailed("context does not exist");
+ finishTest();
+} else {
+ testPassed("context exists");
+
+ debug("");
+ shouldBe("gl.TIMEOUT_IGNORED", "-1");
+ shouldBe("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL", "0x9247");
+ var max = gl.getParameter(gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL);
+ debug("Querying gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ debug("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL returns " + max + "ns");
+ if (max < 0) {
+ testFailed("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL < 0");
+ } else if (max > 1000 * 1000 * 1000) {
+ // This is not demanded by the WebGL2 spec, but anything larger than 1000ms
+ // is bad idea and no implementation should allow it.
+ testFailed("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL should not exceed 1000ms");
+ } else {
+ testPassed("gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL returns a valid value");
+ }
+ sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ shouldBeNonNull("sync");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ gl.clientWaitSync(sync, 0, max);
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ gl.clientWaitSync(sync, 0, max + 1);
+ shouldBe("gl.getError()", "gl.INVALID_OPERATION");
+
+ requestAnimationFrame(runGetSyncParameterTest);
+}
+
+var numRetries = 20000;
+var iteration = 0;
+
+function syncWithGLServer() {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
+}
+
+function runGetSyncParameterTest() {
+ debug("");
+ debug("Verifying sync object isn't signaled too early");
+ sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ // Verify as best as possible that the implementation doesn't allow a sync
+ // object to become signaled until returning control to the event loop, by
+ // spin-looping for some time.
+ var iter = numRetries;
+ while (--iter > 0) {
+ syncWithGLServer();
+ if (gl.getSyncParameter(sync, gl.SYNC_STATUS) == gl.SIGNALED) {
+ testFailed("Sync object was signaled too early");
+ finishTest();
+ return;
+ }
+ }
+ testPassed("Sync object wasn't signaled too early");
+ iteration = numRetries;
+ requestAnimationFrame(finishSyncParameterTest);
+}
+
+
+function finishSyncParameterTest() {
+ if (--iteration == 0) {
+ testFailed("Sync object wasn't signaled in a reasonable timeframe (" + numRetries + " iterations)");
+ finishTest();
+ return;
+ }
+ var res = gl.getSyncParameter(sync, gl.SYNC_STATUS);
+ if (res == gl.SIGNALED) {
+ testPassed("Sync object was signaled");
+ requestAnimationFrame(runClientWaitSyncTest);
+ return;
+ }
+ // Try again.
+ syncWithGLServer();
+ requestAnimationFrame(finishSyncParameterTest);
+}
+
+function runClientWaitSyncTest() {
+ debug("");
+ debug("Verifying clientWaitSync doesn't complete too early");
+
+ sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ // Verify as best as possible that the implementation doesn't allow
+ // clientWaitSync to return CONDITION_SATISFIED or ALREADY_SIGNALED until
+ // returning control to the event loop, by spin-looping for some time.
+ var iter = numRetries;
+ while (--iter > 0) {
+ syncWithGLServer();
+ var res = gl.clientWaitSync(sync, 0, 0);
+ if (res == gl.CONDITION_SATISFIED || res == gl.ALREADY_SIGNALED) {
+ testFailed("clientWaitSync completed successfully too early");
+ finishTest();
+ return;
+ }
+ }
+ testPassed("clientWaitSync didn't complete successfully too early");
+ iteration = numRetries;
+ requestAnimationFrame(finishClientWaitSyncTest);
+}
+
+function finishClientWaitSyncTest() {
+ if (--iteration == 0) {
+ testFailed("clientWaitSync didn't complete in a reasonable timeframe (" + numRetries + " iterations)");
+ finishTest();
+ return;
+ }
+ var res = gl.clientWaitSync(sync, 0, 0);
+ if (res == gl.CONDITION_SATISFIED || res == gl.ALREADY_SIGNALED) {
+ testPassed("clientWaitSync completed successfully");
+ // This is the last test right now.
+ finishTest();
+ return;
+ }
+ // Try again.
+ syncWithGLServer();
+ requestAnimationFrame(finishClientWaitSyncTest);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/00_test_list.txt
new file mode 100644
index 0000000000..32867b54c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/00_test_list.txt
@@ -0,0 +1,14 @@
+misc/00_test_list.txt
+canvas/00_test_list.txt
+canvas_sub_rectangle/00_test_list.txt
+image/00_test_list.txt
+image_data/00_test_list.txt
+svg_image/00_test_list.txt
+video/00_test_list.txt
+webgl_canvas/00_test_list.txt
+image_bitmap_from_image_data/00_test_list.txt
+image_bitmap_from_image/00_test_list.txt
+image_bitmap_from_video/00_test_list.txt
+image_bitmap_from_canvas/00_test_list.txt
+image_bitmap_from_blob/00_test_list.txt
+image_bitmap_from_image_bitmap/00_test_list.txt
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..8c801c4c9a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..05f02544ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..36bd2e93d7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..46da6a2987
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..82f9b02997
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..7d22382c83
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..386ba29a39
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..c7a4277084
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..03e4239af3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..5aba67f310
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..514c6b9bac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..4fd44a8c02
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..a5a70f80df
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..36bc410800
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..973470922f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..f5876b7b44
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..fddec39e89
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..9dce82e56c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..39c2aea9d1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..d86acccec7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..8708171759
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..48fec819dd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..06563eae3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..487f31dba3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..1370103dfe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..4991fa6284
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..fb7ffa57eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..156de2a707
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..57ff4c5ffe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..60ef5bcf15
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..9aab72ff23
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..39137ef896
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..34f3c2e24d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..7bce656cf3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..4aef15a592
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..3e5f79e8ed
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..070e764f13
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..07e504ad01
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..1b296d9f0c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..b562f71549
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..0c0d824598
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..d5521e370c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..52f2344394
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..7a02c62556
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..1381c0a484
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..df3dfc0f8c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..e66ae71d97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..ccc3d13c44
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..9deeff0840
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..f16c2759f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..ede0abb981
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..7f87bcfdd2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..c503df8492
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..6f2286d00a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..1112ac8c2a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..2179eda930
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..7277738228
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..9308dffd3e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..2c5ad98f43
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..894c690426
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..d4703bdf95
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..31ee95ac9c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..a7581fa954
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..304f121ac1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c2fdcbbc55
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..5a5691b6d1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..aa8ca643f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..7e5e0bea87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..a1344af710
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..dd5bf39e70
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..46b5e3fe64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..f074cf6de5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..fc0a6b755d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..05a48a7981
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..60527987f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..7aec66910e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..dec1f81cc5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..7c6595b817
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..8ef399dcc8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..76c765b6fc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..b238b76243
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..c7e2b78cfc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..5ab513162e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..a27d31944c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..2ff8b6235f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..33ddf9b0c1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..742b207464
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..08619238ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..74aa42c9d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..ee376bd2b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..16cca51a01
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..f628182f39
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..e433920c07
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..d318d09de6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..54b43b1c89
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..b6f1956ec9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..98ef9407eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..1cf6990056
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..421a887106
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4b3f3d9e7c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..337c011bc4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..3d9c86cc82
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..5f64d6f88e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..e7b0478a5c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..6ede1146a7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..03ecaeb211
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..cde19ef1bf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..0068bf2495
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..c13290a670
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6202000171
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..2db57ea345
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..5d959f1ba6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..a32c6ff7c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..8291d7b7cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..1b2e3f3715
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..5f51df5cc5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..82b7010278
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..4ad053eb8a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..eb1e8d9987
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..27cbf617fa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..945337ff74
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..603f69522f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..90f4be79fc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..daee9a0c6d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..1efe3dcb22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..6e0b8def24
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..d7a95ab819
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..4783419363
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..9de09db382
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..6c0e65e573
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..e013f66d77
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..9e2ed794a8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..b06d2b155c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..87d5c9aade
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..9d09b5fb76
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..fd95a5dfc0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..6ea3292110
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..841d8fc61c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..4c199d2901
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..e2bd06e440
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..5ddcae6a40
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..f93e42c6c4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..0ea44bde5f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..624b3399bb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..90836ed8b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..9f260cf8e8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..e5baf2069e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..c77bc24ab4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..e1e35ea54c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..83023a85b9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..5b2a1e6a16
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..e988a7d5f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..6b64f9e217
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..32a8cb6d73
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..2ad6725924
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..60668ece42
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..a89cb3e39e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..5823a6944b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..f8516a6f19
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..61f186a309
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..a101504cca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..24f5db7540
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..4661fd0978
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..3702959597
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..62176ed6db
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..3955375f0f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..79f6939ff7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..db68f6c16e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..6b14cb7e2c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..654a310535
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..f76a52359e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..d8b1bfa3c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..7cb17eb625
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..8d06eaafd1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..4e0874924b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..d94582329d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..34819efa67
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..730754b09d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..433588f223
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..e45398f29a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..42c1f7779d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..0abcc546df
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..2ff03c17f2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..3f6591dfd5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..41529a4043
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..3d563318c6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..105bca0261
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..e52398c49f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..3f190c01c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..eed7125484
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..3dcbab2ef0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..dba17ff312
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..07c2bbc422
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..2e15aeb30d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..79afb795ad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..bbf137a8e5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..cf21cda985
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..4dff791e8d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..5940abde8b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..c96b864366
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..5b23b9e0a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..33ad6a49ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..62a0ccbb50
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c4ecaf62d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..aa052b6130
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..3261c23797
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..6c0f3c2689
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..9af1fa3532
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..a2ec49eca0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..272ea5e54e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..e832be3297
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..42079acf19
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..38e7234b71
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..c2243248ba
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..6c0106457f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..3c2e6c14f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..66c2a626e0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..519cf98b83
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..b40e839f2f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..0fc1149007
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..bae44d2cc8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..d0b2f47134
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..49261e54bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f4ede9024f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..01835049b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..ac54fb75ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..fcf008ed25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..b3081c52ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..77d3318623
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..a753121769
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..de58b2af94
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..5b08d77cd2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c83dc2a731
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..6e4e5a54d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4ccbe826a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..42736a2da2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..878757e353
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..978df556d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..5fa9f21a2c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..a1df113ca0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..066f900887
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..3987980699
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..4117593187
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..0155fde0b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..4a0d9cf1de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..16295386b4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..6aa5fafbd7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..a43ddbd38e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..7348e8185e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..e28076ac71
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..c01144c4eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..2e924d8e65
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..8287f00830
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..6d78d8843a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..6b1c6fbad1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..7afcaa0b3c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..0a5a97e90c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..0f4b97deef
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..34319b3e58
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..3f68db2d1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..f5fb2e1fbe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..d7fea8caad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..e823230325
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..ef59f2c15d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..f4711efefa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..dc5b703253
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..b78cb598a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..6fe341ee26
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..3801969d4b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..9b3f961133
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..0ecafe0628
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..da0644b6b7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..e92d04252d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..971df799c3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..2d20a8007f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..132326f467
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..c7ff8d75d1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..e68fe461be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..c467928207
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4f403c6f88
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..de04f033d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..85794f50a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..79f0f445fc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..a98f49d5db
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6b38cd13f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..64661eebea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..438ea17de9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..5fd088cfe7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..5f7c70d391
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..3600cdee52
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..96d7f72bbd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4c151a2412
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..117e4ba805
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..a0588dec51
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..23b56763b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..f4f85ca644
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..d891379473
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..3f4f4bf17f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..916df976de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..d9ee243502
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..025ce676f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..fadaf85708
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..bbc7d924ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..7a3c4da940
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..249c1b315f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..1368cf93d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..84d2ea6130
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..a5ad80eef5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..e0e2d02c84
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..79616a9193
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..37a1b86476
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..92016d3b78
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..6fde64957f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..ceec9bafdf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..2641f866fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..561d23bbd1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..8c39d4e1a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..202ffa2444
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..3e0efbfde2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..900d4ed33f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..9b650ec281
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..7184d79e1a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..0cad5e4f0c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..f8bbdb3477
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..97c8dc9e8d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..0f28e71e57
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..64b776c932
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..0ba53b4d5d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..23e7b04d9c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..fb2df020d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..9185dca389
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..f49947da4b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..03187ad3bb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..022ce5d83d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..31557d5e50
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..73b1b4f11d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..48713129f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..d207cb1bcd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..498e87b29f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..fbddf50be3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..a8c9362426
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..c673de8258
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..e4537fb278
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..ddb1aebf10
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..8c04fd16f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..70e9470c6b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..5120a28724
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..3122847542
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..d88a0d3646
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..1f6e19e66f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..efbcf1c6ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..6e26c12a5e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..a084604893
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..d89d37128e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..70b5526c29
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..3b948a54dd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..84bd197c87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..983abc6ee4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..26e7267d12
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4678fe2c76
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..735706afc5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..7c5dee4f66
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6e24630442
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..fe45185497
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..d41fd3a548
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..7a807854a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..594c7695d7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..d189da14c0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..fd0689a529
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..4589fb7b4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..25ca3f9038
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..c5f24faae0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..ee632f3d31
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c0f7a778da
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..95bd113972
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..d9d1b51cdd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..59035ca60d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..e018012ba3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..18c8b3cf15
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..988763acf2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..f94b3c8152
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4f95e95f30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..281ec20441
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..d5bf860b3f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..59434bbe03
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..ea79d07022
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..b5d02dfc79
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..91e79980f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..65b6e1dcb7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..e035ca3aec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..40f296d5ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..f0d51be51f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..0f8c9d75e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..cdb0e1e6d7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..e3cc424271
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..9373a6e00f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..886db8b75d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..c9639636bb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..e8ae94988b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..e18874689c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..e3f401eb0e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..3cadef2674
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..6b19d39105
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..150f516d06
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..09075ed879
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..e6a5546459
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..f3246700b5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..fa1bbabbbc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..09a91d39a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..8ee9563a76
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..e1cc853b0e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..fc30a91404
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..3c6b29ddad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..687a1e4c89
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..898b40c62a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..c1390729e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..dfbf46134b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..00387d08ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..9113d16c77
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..17af648224
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..d9f0fa5bf3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..75b910870b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..d85aed8e1e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..23f5727e6d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..41185647a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..a033877321
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..374fa01fc4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..b8880a4c86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..09af2b8a07
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..c79586f626
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..01b8fe5d34
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..b5e922c90d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..aff000cb63
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..f49e1396e4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..bab3796e3b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..4e908ce8b4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..0ed79ae542
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..765ef1358d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..231eebd539
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4f82923db3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..00874ae56b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..0318312b1c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..cd31e97ba2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..82437ce839
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..3da4de658d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..a3b6ac5e49
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..88745fa9ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..4f8e472b1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..236014e67d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6ab0d85749
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..bff07471f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..35fe3616f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..ec06ee79d8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..fc28bd70a0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..00ae72a33b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..8cdb57cbea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..e933f3bbb7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..d420ee0a00
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..3f5f4408fd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..c9e16e3cba
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..a39a3648e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..254e68c19e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..ca5d04ddbf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..d3de225f86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..8916044cd0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..e5603af9dc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..7753af57cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..b8b2ea4303
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..a9e07ea2ec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..0ef26a1c86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..d67446841e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..981be92d5b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..07334a9398
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..a370da8ad1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..e3685b2471
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..245868490d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..29308085c8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..c46f4b8e62
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..e9d897a88c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..5654b473e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..ba6e83d449
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..ff89676426
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..dacb34d122
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..f51420f051
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..cdc08d87e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..9ae36f898a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..b78e4903f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..fcb150ea1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..5191af5d61
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..94588d7c68
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..b235f006c7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..d6e1b4ad00
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..7a88d6b87b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..87211acd3f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..6c8de5ef23
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..5ec5cc699d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..e404eb534f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..e74b7eaedb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..17dd9a91bf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..a476294806
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..3201755760
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..43cb93d7f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..97bd18f654
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..8044b4c3fd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..98a8a0bc69
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..a0a68fbf28
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f559aeec41
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..5f8f3590d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..46c83fc72b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f1a32c833d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..105f2fa157
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..86e77ad110
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..4a8f2f6072
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..9d1167ddf3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..e8c0c8d0a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..5847430157
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..d7c22a5341
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..d698fc5031
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..3985828577
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..2154f6e1aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..a0d674fb73
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..5da6a5e8ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..1bdd88b7a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..1a76138a34
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..b72a8c6b82
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..1e044af0e5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..1fc7f7769d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..d9baa61e58
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..b70ae64f32
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..eecd272bc6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..db49a55a25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..cea155c856
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..49d949b5f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..9d94f89eb3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..c5225b8e7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..1235d2c6de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..04d386ffcb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..b216f0b7d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..42fc43a397
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..dfa84fd9fe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..364288dbd5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..d19eab640b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..6b2b06bb00
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..949d8e9005
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..b4456c29b5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..67741e9ab9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..04da85fd65
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..447a746f87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..7eafd3d2af
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..fbaadd6fbc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..26db1ed18a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4ea71275c3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..9d42d06a90
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..0572c094e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..db21b1378d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..cbdbc0f8f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..53d6ab3f74
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..690e06ca36
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..bb73c5066b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..5577516559
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..ba13ad89bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..ae4a929fb4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..e00359b1c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4f506c3387
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..62fb78b594
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..56c4abdb3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..66ee91fe80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..ed73f42f5d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..04d37ffc71
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..707223260e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..ded868fb64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..08b5d2c094
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..371a9271fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..c58c6b02b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..dbeb44121f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..ebdfcd1a0d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..8c432743ba
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..de290dd9a5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..580027631d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..ae5928c01d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..aff08d4ec4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..c848f27d1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..ca7ae2dc43
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..fe40d0e695
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..98c0e3d673
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..df3fd4cd80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..e1838bd156
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..d0b9eb02d2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..b104e93f83
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..b5b3d074e8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..b6d4eca749
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..4cf4c8dfb1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..17a117dd13
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..aff864a307
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..01eb72baa3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..20576dd927
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..8dc5e7607f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f36d054001
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..fa54481e8f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..1e909ca69c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..29d9cef86e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..16b3a480a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..dae9dab170
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..08a3408030
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..e70455bf5f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..a3b68544ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..a9326befcc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..7428cf0c2e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..ebdabf8909
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..1084c444ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..c1815a512e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..8a9e683380
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..7276d9ff93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..8aa7bd05b8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..8f607613cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..d77a9454f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..2f737ebb17
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..5d67d54beb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..0d90998a06
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..a781744957
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..925c197369
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..66641ccf85
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..87dd6d60a5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..94595222c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..dca4bef18b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..1db719eabc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..f0b4d1bbf8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..784834a12e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..9be67acf79
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..f053fa8ee7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..2484c4e5af
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..d3b0f4c42c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..83dcc33772
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..2f43bf07c6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..004bab7f8b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..358bfda906
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..1460586195
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..38e925c060
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..11d8b58244
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..6c68bb49aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c5bd77413a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..58770e5ec7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..b8ab3290ea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..24ce7f7f27
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..723577adcf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..7083a0545b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..86bb1fd8ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..2d98cd10c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..550727d1f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..34d2f6d304
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..39cb9ce30a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..2668d82c82
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r32f-red-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..d0c3f8c66a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..d1cc9d25c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..036b5ef9fe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..bb433ffb36
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..ec113d8b1f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..ec4f7edd2e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4aada97d3e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..39e95ada97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..b18ddf8b73
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..f1c9021eba
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..faf230d11b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..3e43e99d7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..993dd3bb3b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..8c95937ea5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..c27cf260d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..3bdff9c5a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..5c7d59967b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..be249149a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..808fb30d25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..eb03a0f38f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..9ad5fb2040
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..ad4cc39f68
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..7df80309f4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..a4573fa124
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..88f85ea36c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..e1f917d406
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..4ac2bc5e3f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..a52d387880
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/00_test_list.txt
new file mode 100644
index 0000000000..17f8312e58
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/00_test_list.txt
@@ -0,0 +1,40 @@
+--min-version 2.0.1 active-3d-texture-bug.html
+--min-version 2.0.1 angle-stuck-depth-textures.html
+canvas-remains-unchanged-after-used-in-webgl-texture.html
+--min-version 2.0.1 compressed-tex-from-pbo-crash.html
+--min-version 2.0.1 compressed-tex-image.html
+--min-version 2.0.1 copy-texture-cube-map-AMD-bug.html
+--min-version 2.0.1 copy-texture-cube-map-bug.html
+copy-texture-image.html
+copy-texture-image-luma-format.html
+--min-version 2.0.1 copy-texture-image-same-texture.html
+copy-texture-image-webgl-specific.html
+--min-version 2.0.1 generate-mipmap-with-large-base-level.html
+gl-get-tex-parameter.html
+--min-version 2.0.1 immutable-tex-render-feedback.html
+--min-version 2.0.1 integer-cubemap-texture-sampling.html
+--min-version 2.0.1 integer-cubemap-specification-order-bug.html
+mipmap-fbo.html
+--min-version 2.0.1 npot-video-sizing.html
+--min-version 2.0.1 tex-3d-mipmap-levels-intel-bug.html
+--min-version 2.0.1 origin-clean-conformance-offscreencanvas.html
+tex-3d-size-limit.html
+--min-version 2.0.1 tex-base-level-bug.html
+tex-image-and-sub-image-with-array-buffer-view-sub-source.html
+tex-image-with-bad-args.html
+tex-image-with-bad-args-from-dom-elements.html
+tex-image-with-different-data-source.html
+tex-input-validation.html
+tex-mipmap-levels.html
+tex-new-formats.html
+--min-version 2.0.1 tex-srgb-mipmap.html
+tex-storage-2d.html
+tex-storage-and-subimage-3d.html
+tex-storage-compressed-formats.html
+--min-version 2.0.1 tex-subimage3d-canvas-bug.html
+--min-version 2.0.1 tex-subimage3d-pixel-buffer-bug.html
+tex-unpack-params.html
+--min-version 2.0.1 tex-unpack-params-imagedata.html
+--min-version 2.0.1 tex-unpack-params-with-flip-y-and-premultiply-alpha.html
+texel-fetch-undefined.html
+texture-npot.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/active-3d-texture-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/active-3d-texture-bug.html
new file mode 100644
index 0000000000..fe86514dd2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/active-3d-texture-bug.html
@@ -0,0 +1,124 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Active TEXTURE1 Bug Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+precision mediump float;
+in vec4 a_position;
+in vec2 a_coord;
+out vec2 v_coord;
+void main() {
+ gl_Position = a_position;
+ v_coord = a_coord;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+in vec2 v_coord;
+uniform mediump sampler3D u_sampler;
+out vec4 o_color;
+void main () {
+ o_color = texture(u_sampler, vec3(v_coord, 0.0));
+}
+</script>
+<script>
+"use strict";
+description("Test for a MacOSX 10.12 with Intel GPUs driver crash bug activating TEXTURE1 for 3d texture");
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var samplerLoc;
+
+function render(textureUnit, width, height, expectedColor, msg) {
+ gl.uniform1i(samplerLoc, textureUnit);
+ wtu.setupUnitQuad(gl, 0, 1);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, msg);
+}
+
+function activeTextureTest() {
+ var texture = gl.createTexture();
+ var sampler = gl.createSampler();
+ var width = 64;
+ var height = 64;
+ var depth = 4;
+ var black = [0, 0, 0, 255];
+ var size = width * height * depth * 4;
+
+ var buf = new Uint8Array(size);
+ for (var i = 0; i < size; i += 4) {
+ buf[i + 0] = 0;
+ buf[i + 1] = 255;
+ buf[i + 2] = 0;
+ buf[i + 3] = 255;
+ }
+
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ['a_position', 'a_coord'], [0, 1]);
+ samplerLoc = gl.getUniformLocation(program, "u_sampler");
+
+ gl.viewport(0, 0, width, height);
+
+ gl.bindTexture(gl.TEXTURE_3D, texture);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ // texture is unbound from the default texture unit TEXTURE0,
+ // then a default black texture will be bound to TEXTURE0.
+ gl.bindTexture(gl.TEXTURE_3D, null);
+
+ // Active TEXTURE1 and 3d texture are necessary to reproduce the crash bug.
+ gl.activeTexture(gl.TEXTURE1);
+
+ gl.bindSampler(0, sampler);
+ gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.bindTexture(gl.TEXTURE_3D, texture);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ // Render using sampler
+ // When rendering from texture unit 0, the black texture will be drawn.
+ render(0, width, height, black, "Result pixels rendering from TEXTURE0 should be black");
+
+ gl.bindSampler(0, null);
+ gl.deleteSampler(sampler);
+
+ // Render using texture
+ // When rendering from texture unit 0, the black texture will be drawn.
+ // Crash happens when calling gl.drawArrays during this rendering.
+ render(0, width, height, black, "Result pixels rendering from TEXTURE0 should be black");
+
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.deleteTexture(texture);
+ gl.deleteProgram(program);
+}
+
+if (!gl) {
+ testFailed("Fail to get a WebGL2 context");
+} else {
+ testPassed("Created WebGL2 context successfully");
+ activeTextureTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/angle-stuck-depth-textures.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/angle-stuck-depth-textures.html
new file mode 100644
index 0000000000..17cb0ac916
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/angle-stuck-depth-textures.html
@@ -0,0 +1,197 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Textures Misc Tests: "Stuck" Depth Textures</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script id="draw-vs" type="x-shader/x-vertex">#version 100
+attribute vec3 vertex;
+void main () {
+ gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);
+}
+</script>
+<script id="draw-fs" type="x-shader/x-fragment">#version 100
+void main () {
+ gl_FragColor = vec4 (1.);
+}
+</script>
+
+<script id="blit-vs" type="x-shader/x-vertex">#version 100
+attribute vec2 vertex;
+varying vec2 position;
+void main () {
+ position = vertex * .5 + .5;
+ gl_Position = vec4(vertex, 0, 1);
+}
+</script>
+<script id="blit-fs" type="x-shader/x-fragment">#version 100
+precision mediump float;
+uniform sampler2D texture;
+varying vec2 position;
+void main () {
+ gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);
+}
+</script>
+
+</head>
+<body>
+<canvas id="example" width="128" height="128"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+description("This test covers an ANGLE bug where an AMD workaround would cause depth textures to stick. See http://anglebug.com/1664.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var WEBGL_depth_texture;
+
+var drawProgram, blitProgram, textureLoc;
+
+var quadVB;
+
+function drawQuad(depth) {
+ if (!quadVB) {
+ quadVB = gl.createBuffer()
+ }
+
+ var quadVerts = new Float32Array(3 * 6);
+ quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth;
+ quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth;
+ quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth;
+ quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth;
+ quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth;
+ quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, quadVB);
+ gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawQuad");
+}
+
+// Test based on dEQP-GLES3.functional.blit.depth_stencil.depth_24_stencil8_stencil_only
+function run_test() {
+
+ var colorTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, colorTex);
+ 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_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 128, 128, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ var depthTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, depthTex);
+ 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_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
+ var levels = Math.log2(128);
+ for (var mipLevel = 0; mipLevel <= levels; ++mipLevel)
+ {
+ var size = 128 >> mipLevel;
+ gl.texImage2D(gl.TEXTURE_2D, mipLevel, gl.DEPTH24_STENCIL8, size, size, 0, gl.DEPTH_STENCIL,
+ gl.UNSIGNED_INT_24_8, null);
+ }
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after init textures");
+
+ var framebuffer = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTex, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after init framebuffer");
+
+ gl.depthRange(0.0, 1.0);
+ gl.viewport(0, 0, 128, 128);
+ gl.clearColor(0, 0, 0, 1);
+
+ // Draw loop.
+ for (var frame = 0; frame < 4; ++frame)
+ {
+ // draw into FBO
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ gl.useProgram(drawProgram);
+ if (frame % 2 != 0) {
+ drawQuad(0.0);
+ } else {
+ drawQuad(1.0);
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ // blit FBO
+ gl.disable(gl.DEPTH_TEST);
+
+ gl.useProgram(blitProgram);
+ gl.uniform1i(textureLoc, 0);
+ gl.bindTexture(gl.TEXTURE_2D, depthTex);
+
+ drawQuad(0.5);
+
+ if (frame % 2 != 0) {
+ wtu.checkCanvasRect(gl, 0, 0, 128, 128, [0, 0, 0, 255],
+ "depth texture should be black on odd iterations");
+
+ } else {
+ wtu.checkCanvasRect(gl, 0, 0, 128, 128, [255, 255, 255, 255],
+ "depth texture should be white on even iterations");
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after draw");
+ }
+
+ gl.deleteTexture(colorTex);
+ gl.deleteTexture(depthTex);
+ gl.deleteFramebuffer(framebuffer);
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ drawProgram = wtu.setupProgram(gl, ["draw-vs", "draw-fs"], ["vertex"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after draw program initialization");
+ shouldBe('gl.getProgramParameter(drawProgram, gl.LINK_STATUS)', 'true');
+
+ blitProgram = wtu.setupProgram(gl, ["blit-vs", "blit-fs"], ["vertex"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after blit program initialization");
+ shouldBe('gl.getProgramParameter(blitProgram, gl.LINK_STATUS)', 'true');
+
+ textureLoc = gl.getUniformLocation(blitProgram, "texture")
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "query texture location");
+ shouldBeNonNull('textureLoc')
+
+ run_test();
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html
new file mode 100644
index 0000000000..5c81552793
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html
@@ -0,0 +1,73 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="c" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests canvas remains unchanged after it is used in webgl texutre');
+
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=446380'>Chromium Issue 446380</a>");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c", undefined, 2);
+
+function checkSourceCanvasImageData(imageDataBefore, imageDataAfter) {
+ if (imageDataBefore.length != imageDataAfter.length) {
+ testFailed("The size of image data in source canvas become different after it is used in webgl texture.");
+ return;
+ }
+ for (var i = 0; i < imageDataAfter.length; i++) {
+ if (imageDataBefore[i] != imageDataAfter[i]) {
+ testFailed("Pixel values in source canvas have changed after canvas used in webgl texture.");
+ return;
+ }
+ }
+ testPassed("Pixel values in source canvas remain unchanged after canvas used in webgl texture.");
+}
+
+function runTest(width, height) {
+ var canvas = document.createElement("canvas");
+ canvas.width = width;
+ canvas.height = height;
+ var ctx = canvas.getContext("2d");
+ ctx.fillStyle = "rgba(1, 63, 127, 1)";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ var refCanvas = document.createElement("canvas");
+ refCanvas.width = width;
+ refCanvas.height = height;
+ var refCtx = refCanvas.getContext("2d");
+ refCtx.fillStyle = "rgba(1, 63, 127, 1)";
+ refCtx.fillRect(0, 0, canvas.width, canvas.height);
+ // A refCanvas with same data as canvas is used to get original image data, since
+ // getImageData may change hardware accelerated status of canvas and we don't want to
+ // omit testing for hardware accelerated canvas.
+ var imageDataBefore = refCtx.getImageData(0, 0, refCanvas.width, refCanvas.height);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "TexImage2D should succeed");
+ checkSourceCanvasImageData(imageDataBefore, ctx.getImageData(0, 0, canvas.width, canvas.height));
+ gl.deleteTexture(tex);
+}
+
+runTest(2, 2);
+runTest(257, 257);
+
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-from-pbo-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-from-pbo-crash.html
new file mode 100644
index 0000000000..74444d32fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-from-pbo-crash.html
@@ -0,0 +1,44 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Regression test for compressedTex with PBO</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+
+// The following statement caused a crash in Chrome. See crbug.com/690335.
+// Because no PBO is bound, the last parameter is interprected as a pointer
+// to the client side data.
+gl.compressedTexImage2D(gl.TEXTURE_2D, 0, 0, 4, 4, 0, 8, 3);
+
+wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_VALUE, gl.INVALID_OPERATION],
+ "should not crash and generate a GL error");
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-image.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-image.html
new file mode 100644
index 0000000000..818d6e8dff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-image.html
@@ -0,0 +1,24 @@
+<!--
+Copyright (c) 2020 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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+const contextVersion = 2;
+</script>
+<script src="../../../js/tests/compressed-tex-image.js"></script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html
new file mode 100644
index 0000000000..008ac88459
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html
@@ -0,0 +1,104 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL copy into cube map texture conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+
+function runTest() {
+ var width = 16;
+ var height = 16;
+ var level = 0;
+ var cases = [
+ {
+ internalformat: "RGBA8",
+ format: "RGBA",
+ type: "UNSIGNED_BYTE",
+ data: new Uint8Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA8I",
+ format: "RGBA_INTEGER",
+ type: "BYTE",
+ data: new Int8Array(width * height * 4)
+ },
+ {
+ internalformat: "RGBA8UI",
+ format: "RGBA_INTEGER",
+ type: "UNSIGNED_BYTE",
+ data: new Uint8Array(width * height * 4)
+ }
+ ];
+ if (gl.getExtension("EXT_color_buffer_float")) {
+ cases.push({
+ internalformat: "RGBA32F",
+ format: "RGBA",
+ type: "FLOAT",
+ data: new Float32Array(width * height * 4)
+ });
+ }
+ cases.forEach(function(testcase) {
+ debug("");
+ debug("Testing internalformat: " + testcase.internalformat);
+
+ var internalformat = gl[testcase.internalformat];
+ var format = gl[testcase.format];
+ var type = gl[testcase.type];
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ var data = testcase.data;
+ gl.texImage2D(gl.TEXTURE_2D, level, internalformat, width, height, 0, format, type, data);
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, level);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup framebuffer with texture should succeed.");
+
+ var cubeTexture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTexture);
+
+ for (var face = gl.TEXTURE_CUBE_MAP_POSITIVE_X; face < gl.TEXTURE_CUBE_MAP_POSITIVE_X + 6; face++) {
+ gl.copyTexImage2D(face, level, internalformat, 0, 0, width, height, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "CopyTexImage2D should succeed.");
+ gl.copyTexSubImage2D(face, level, 0, 0, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "CopyTexSubImage2D should succeed.");
+ }
+
+ gl.deleteTexture(cubeTexture);
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+ });
+}
+
+description();
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=712117'>Chromium Issue 712117</a>");
+
+var canvas = document.getElementById("canvas");
+shouldBeNonNull("gl = wtu.create3DContext(canvas, undefined, 2)");
+
+runTest();
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-bug.html
new file mode 100644
index 0000000000..77a811cdaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-bug.html
@@ -0,0 +1,49 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL copy into cube map texture bug conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="1024" height="1024"></canvas>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+
+function runTest() {
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH,5);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 5, gl.RGBA, 75, 10, 2, 2, 0);
+ // Note that this bug only manifest with Chrome ASAN build on MacOSX with Intel drivers.
+ // At this point ASAN build will crash inside Intel driver code.
+ testPassed("Chrome ASAN build on MacOSX with Intel driver should have crashed at this point with this bug");
+}
+
+description();
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=892282'>Chromium Issue 892282</a>");
+
+var canvas = document.getElementById("canvas");
+shouldBeNonNull("gl = wtu.create3DContext(canvas, undefined, 2)");
+
+runTest();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-luma-format.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-luma-format.html
new file mode 100644
index 0000000000..249716deda
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-luma-format.html
@@ -0,0 +1,165 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL CopyTexSubImage Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64px" height="32px"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in highp vec4 a_position;
+in highp vec2 a_coord;
+out highp vec2 v_coord;
+void main(void) {
+ gl_Position = a_position;
+ v_coord = a_coord;
+}
+</script>
+<script id="fshader_luminance_alpha" type="x-shader/x-fragment">#version 300 es
+in highp vec2 v_coord;
+uniform highp sampler3D u_sampler0;
+out highp vec4 o_color0;
+void main (void) {
+ o_color0 = vec4(texture(u_sampler0,vec3(v_coord, 0)));
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the behavior of copTexSubImage3D with luminance textures.");
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+function copytexsubimage3D_luma_format() {
+
+ var testGroup = [
+ {
+ name: '3d_alpha',
+ format: gl.ALPHA,
+ width: 64,
+ height: 32,
+ depth: 2
+ },
+ {
+ name: '3d_luminance',
+ format: gl.LUMINANCE,
+ width: 64,
+ height: 32,
+ depth: 2
+ },
+ {
+ name: '3d_luminance_alpha',
+ format: gl.LUMINANCE_ALPHA,
+ width: 64,
+ height: 32,
+ depth: 2
+ }
+ ];
+
+ testGroup.forEach(function(testcase) {
+ debug("");
+ debug("Testing copytexsubimage3d_luma_format_" + testcase.name);
+
+ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ var layer = 0;
+ var width = testcase.width;
+ var height = testcase.height;
+ var depth = testcase.depth;
+ var msg;
+ var uint1 = new Uint8Array(width * height * 4);
+ for (var i = 0; i < uint1.length - 1; ++i) {
+ uint1[i + 1] = (uint1[i] + 10) % 255;
+ }
+
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint1);
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.bindTexture(gl.TEXTURE_3D, texture[1]);
+ setUpTexStatus();
+ gl.texImage3D(gl.TEXTURE_3D, 0, testcase.format, width, height, depth, 0, testcase.format, gl.UNSIGNED_BYTE, null);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer, 0, 0,width, height);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ var program = wtu.setupProgram(gl, ["vshader", "fshader_luminance_alpha"], ["a_position", "a_coord"]);
+ wtu.setupUnitQuad(gl, 0, 1);
+ wtu.drawUnitQuad(gl);
+
+ for (var y = 0; y < height; ++y) {
+ for (var x = 0; x < width; ++x) {
+ var cur = y * width * 4 + x * 4;
+ if (testcase.format == gl.ALPHA) {
+ wtu.checkCanvasRect(gl, x, y, 1, 1, [ 0, 0,
+ 0, uint1[cur + 3]], msg, [1, 1, 1, 1]);
+ } else if (testcase.format == gl.LUMINANCE) {
+ wtu.checkCanvasRect(gl, x, y, 1, 1, [uint1[cur], uint1[cur],
+ uint1[cur], 255], msg, [1, 1, 1, 1]);
+ } else { // gl.LUMINANCE_ALPHA
+ wtu.checkCanvasRect(gl, x, y, 1, 1, [uint1[cur], uint1[cur],
+ uint1[cur], uint1[cur + 3]], msg, [1, 1, 1, 1]);
+ }
+ }
+ }
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ gl.deleteProgram(program);
+ });
+}
+
+function setUpTexStatus() {
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
+ );
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
+ );
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
+ );
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
+ );
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE
+ );
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ copytexsubimage3D_luma_format();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-same-texture.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-same-texture.html
new file mode 100644
index 0000000000..c247cabc48
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-same-texture.html
@@ -0,0 +1,144 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL CopyTexImage from/to the same texture Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="64" height="64"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+// https://bugs.chromium.org/p/chromium/issues/detail?id=797235
+description("This test verifies CopyTexImage2D works if source/destination images belong to the same texture");
+debug("");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function checkFramebuffer(expected) {
+ var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (expected.indexOf(actual) < 0) {
+ var msg = "checkFramebufferStatus expects [";
+ for (var index = 0; index < expected.length; ++index) {
+ msg += wtu.glEnumToString(gl, expected[index]);
+ if (index + 1 < expected.length)
+ msg += ", ";
+ }
+ msg += "], was " + wtu.glEnumToString(gl, actual);
+ testFailed(msg);
+ } else {
+ var msg = "checkFramebufferStatus got " + wtu.glEnumToString(gl, actual) +
+ " as expected";
+ testPassed(msg);
+ }
+}
+
+function checkTextureLevelColor(texture, level, level_width, level_height, x, y, width, height, color) {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var color_renderable_tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, color_renderable_tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, level_width, level_height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, color_renderable_tex, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ var program = wtu.setupTexturedQuad(gl);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, level);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, level);
+ 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.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, x, y, width, height, color);
+
+ gl.deleteTexture(color_renderable_tex);
+ gl.deleteFramebuffer(fbo);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Check texture level color should generate no GL errors.");
+}
+
+function testChangeTargetTextureLevelSize() {
+ debug("");
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ var texture = gl.createTexture();
+ wtu.fillTexture(gl, texture, 64, 64, [255, 0, 0, 255], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA8);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 1);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ // fbo source texture is |texture| level 1, 32x32. Target is |texture| level 2, 64x64.
+ // Only one quarter of the target 64x64 will come from the source.
+ // Implementations may insert internal commands before copying over 32x32 in order to
+ // initialize undefined three quarters to 0 as WebGL spec requires. This will actually create
+ // a 64x64 image at level 2 and make the fbo incomplete, thus, the copying will fail.
+ gl.copyTexImage2D(gl.TEXTURE_2D, 2, gl.RGBA8, 0, 0, 64, 64, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copyTexImage2D should succeed.");
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]);
+
+ checkTextureLevelColor(texture, 2, 64, 64, 0, 0, 32, 32, [255, 0, 0, 255]);
+ checkTextureLevelColor(texture, 2, 64, 64, 0, 32, 64, 32, [0, 0, 0, 0]);
+ checkTextureLevelColor(texture, 2, 64, 64, 32, 32, 32, 32, [0, 0, 0, 0]);
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Test should generate no GL errors.");
+}
+
+function testChangeTargetTextureLevelFormat() {
+ debug("");
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ var texture = gl.createTexture();
+ wtu.fillTexture(gl, texture, 64, 64, [255, 0, 0, 255], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA8);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 1);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ // Using LUNIMANCE_ALPHA format may trigger implementations' emulation code path
+ // on desktop core profile GL, which might change level 2 image definition first
+ // and make the fbo incomplete, thus, the actual copying will fail.
+ gl.copyTexImage2D(gl.TEXTURE_2D, 2, gl.LUMINANCE_ALPHA, 0, 0, 16, 16, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copyTexImage2D should succeed.");
+ checkFramebuffer([gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]);
+
+ checkTextureLevelColor(texture, 2, 16, 16, 0, 0, 16, 16, [255, 255, 255, 255]);
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Test should generate no GL errors.");
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ testChangeTargetTextureLevelSize();
+ testChangeTargetTextureLevelFormat();
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-webgl-specific.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-webgl-specific.html
new file mode 100644
index 0000000000..ae969e0795
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-webgl-specific.html
@@ -0,0 +1,303 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL CopyTexImage Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="2" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of copyTexImage.");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function copytexsubimage3d_invalid_operation_feedbackloops() {
+ debug("");
+ debug("Testing copytexsubimage3d_invalid_operation_feedbackloops");
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, texture);
+ var uint8 = new Uint8Array(32);
+ var layer = 0;
+ var width = 2;
+ var height = 2;
+ var depth = 2;
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, layer);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "gl.INVALID_OPERATION is generated");
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+};
+
+function copytexsubimage3d_valid_operation_diff_level() {
+ debug("");
+ debug("Testing copytexsubimage3d_valid_operation_diff_level");
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, texture);
+ var uint8 = new Uint8Array(32);
+ var level1 = 0;
+ var level2 = 1;
+ var width = 2;
+ var height = 2;
+ var depth = 2;
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ gl.generateMipmap(gl.TEXTURE_3D);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level1, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, level2, 0, 0, 0, 0, 0, width/2, height/2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed.");
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+};
+
+function copytexsubimage3d_valid_operation_diff_layer() {
+ debug("");
+ debug("Testing copytexsubimage3d_valid_operation_diff_layer");
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, texture);
+ var uint8 = new Uint8Array(32);
+ var layer1 = 0;
+ var layer2 = 1;
+ var width = 2;
+ var height = 2;
+ var depth = 2;
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, layer1);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer2, 0, 0, width, height);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed.");
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+}
+
+function copytexsubimage3d_texture_wrongly_initialized() {
+ debug("");
+ debug("Testing copytexsubimage3d_texture_wrongly_initialized");
+ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ var layer = 0;
+ var width = 2;
+ var height = 2;
+ var depth = 2;
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ var uint = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.bindTexture(gl.TEXTURE_3D, texture[1]);
+ gl.texStorage3D(gl.TEXTURE_3D, 1, gl.RGBA8, width, height, depth);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, layer, 0, 0, width, height);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture[1], 0, layer);
+ var bytes = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, bytes);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixel should succeed.");
+ for (var x = 0; x < width * height * 4; x++) {
+ if (bytes[x] != uint[x]) {
+ testFailed("byte comparison failure, byte at "+ x + " was " + bytes[x] +
+ ", should be " + uint[x]);
+ break;
+ }
+ }
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+};
+
+function copytexsubimage3d_out_of_bounds_test_helper(xx, yy, copyWidth, copyHeight) {
+ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ var layer = 0;
+ var width = 2;
+ var height = 2;
+ var depth = 2;
+ var width2 = 4;
+ var height2 = 4;
+ var xoffset = 0;
+ var yoffset = 0;
+ var uint = new Uint8Array(width * height * 4);
+ for (var i = 0; i < uint.length; i++) {
+ uint[i] = 0x01;
+ }
+ var uint2 = new Uint8Array(width2 * height2 * depth * 4);
+ for (var i = 0; i < uint2.length; i++) {
+ uint2[i] = 0xFF;
+ }
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.bindTexture(gl.TEXTURE_3D, texture[1]);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width2, height2, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint2);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, xoffset, yoffset, layer, xx, yy, copyWidth, copyHeight);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "using copyTexSubImage3D: x = " + xx + ", y = " + yy + " width = " + copyWidth + ", height = " + copyHeight);
+
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture[1], 0, layer);
+ var bytes = new Uint8Array(width2 * height2 * 4);
+ gl.readPixels(0, 0, width2, height2, gl.RGBA, gl.UNSIGNED_BYTE, bytes);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixel should succeed.");
+
+ var sourceX = new Object();
+ var sourceY = new Object();
+ Clip(xx, copyWidth, width, sourceX);
+ Clip(yy, copyHeight, height, sourceY);
+ var destX = sourceX.start - xx + xoffset;
+ var rangeX = sourceX.range;
+ var destY = sourceY.start - yy + yoffset;
+ var rangeY = sourceY.range;
+ for (var y = 0; y < height2; y++) {
+ for (var x = 0; x < width2 * 4; x++) {
+ var current = y * height2 * 4 + x;
+ // pixels copied from read framebuffer should be 0x01
+ if (x >= destX * 4 && x < (destX + rangeX) * 4 && y >= destY && y < destY + rangeY) {
+ if (bytes[current] != 0x01) {
+ testFailed("byte comparison failure, byte at "+ (current) + " was " +
+ bytes[current] +", should be 1");
+ break;
+ }
+ // pixels out-of-bounds should be untouched
+ } else {
+ if (bytes[current] != 0xFF) {
+ testFailed("byte comparison failure, byte at "+ (current) + " was " +
+ bytes[current] + ", should be 255");
+ break;
+ }
+ }
+ }
+ // Test failed; abort
+ if (x < width2 * 4) {
+ break;
+ }
+ }
+ } else {
+ testFailed("framebuffer not complete");
+ }
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+}
+
+function copytexsubimage3d_out_of_bounds() {
+ debug("");
+ debug("Test pixels outside of read framebuffer for CopyTexSubImage3D");
+
+ for(var i=0; i < testlist.length; i++) {
+ copytexsubimage3d_out_of_bounds_test_helper(testlist[i][0], testlist[i][1], testlist[i][2], testlist[i][3]);
+ }
+};
+
+/**
+ * This array defines some copy areas for CopyTexSubImage3D.
+ * A copy area is defined by x coordinate, y coordinate, copyWidth and copyHeight.
+ * the source read framebuffer is (0, 0, 2, 2).
+ */
+var testlist = [
+ [-1, -1, 4, 4],
+
+ [0, 0, 3, 3],
+ [-1, -1, 3, 3],
+ [-1, 0, 3, 3],
+ [0, -1, 3, 3],
+
+ [0, 0, 2, 3],
+ [0, 0, 3, 2],
+ [-1, 0, 3, 2],
+ [0, -1, 2, 3],
+
+ [-2, -2, 3, 3],
+ [-2, 1, 3, 3],
+ [1, -2, 3, 3],
+ [1, 1, 3, 3],
+
+ [2 , 2 ,3, 3]
+];
+
+
+function Clip(start, range, sourceRange, target) {
+ if (start < 0) {
+ range += start;
+ start = 0;
+ }
+ var end = start + range;
+ if(end > sourceRange) {
+ range -= end - sourceRange;
+ }
+ target.start = start;
+ target.range = range;
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ copytexsubimage3d_invalid_operation_feedbackloops();
+ copytexsubimage3d_valid_operation_diff_level();
+ copytexsubimage3d_valid_operation_diff_layer();
+ copytexsubimage3d_texture_wrongly_initialized();
+ copytexsubimage3d_out_of_bounds();
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image.html
new file mode 100644
index 0000000000..3ffdf0a94f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image.html
@@ -0,0 +1,249 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL CopyTexImage Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="64" height="64"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description("This test verifies the functionality of copyTexImage2D.");
+debug("");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function checkFramebuffer(expected) {
+ var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (expected.indexOf(actual) < 0) {
+ var msg = "checkFramebufferStatus expects [";
+ for (var index = 0; index < expected.length; ++index) {
+ msg += wtu.glEnumToString(gl, expected[index]);
+ if (index + 1 < expected.length)
+ msg += ", ";
+ }
+ msg += "], was " + wtu.glEnumToString(gl, actual);
+ testFailed(msg);
+ } else {
+ var msg = "checkFramebufferStatus got " + wtu.glEnumToString(gl, actual) +
+ " as expected";
+ testPassed(msg);
+ }
+}
+
+var testInternalformat = function () {
+ var goodUnormFormats = [
+ "RGB",
+ "RGBA",
+ "LUMINANCE_ALPHA",
+ "LUMINANCE",
+ "ALPHA",
+ "R8",
+ "RG8",
+ "RGB8",
+ "RGBA8",
+ ];
+ var goodUnormFormatsWithUnmatchedComponentSizes = [
+ "RGB565",
+ "RGBA4",
+ "RGB5_A1",
+ "RGB10_A2",
+ ];
+ var goodSRGBFormats = [
+ "SRGB8",
+ "SRGB8_ALPHA8",
+ ];
+ var goodIntFormats = [
+ "R32I",
+ "RG32I",
+ "RGB32I",
+ "RGBA32I",
+ ];
+ var goodIntFormatsWithUnmatchedComponentSizes = [
+ "R8I",
+ "R16I",
+ "RG8I",
+ "RG16I",
+ "RGB8I",
+ "RGB16I",
+ "RGBA8I",
+ "RGBA16I",
+ ];
+ var goodUnsignedIntFormats = [
+ "R32UI",
+ "RG32UI",
+ "RGB32UI",
+ "RGBA32UI",
+ ];
+ var goodUnsignedIntFormatsWithUnmatchedComponentSizes = [
+ "R8UI",
+ "R16UI",
+ "RG8UI",
+ "RG16UI",
+ "RGB10_A2UI",
+ "RGB8UI",
+ "RGB16UI",
+ "RGBA8UI",
+ "RGBA16UI",
+ ];
+ const snormFormats = [
+ "R8_SNORM",
+ "RG8_SNORM",
+ "RGB8_SNORM",
+ "RGBA8_SNORM",
+ ];
+ const float16Formats = [
+ "R16F",
+ "RG16F",
+ "RGB16F",
+ "RGBA16F",
+ ];
+ const float32Formats = [
+ "R32F",
+ "RG32F",
+ "RGB32F",
+ "RGBA32F",
+ ];
+ const float11Formats = [
+ "R11F_G11F_B10F",
+ ];
+ const depthAndOrStencilFormats = [
+ "DEPTH_COMPONENT16",
+ "DEPTH_COMPONENT24",
+ "DEPTH_COMPONENT32F",
+ "DEPTH24_STENCIL8",
+ ];
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ function testFormat(internalformat, srcTexFormatsTypes, fboAttachmentType, expected, msg) {
+ var fbo = gl.createFramebuffer();
+ var srcTexture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, srcTexture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[srcTexFormatsTypes.internalformat], 64, 64, 0, srcTexFormatsTypes.format, srcTexFormatsTypes.type, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, fboAttachmentType, gl.TEXTURE_2D, srcTexture, 0);
+ checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl[internalformat], 0, 0, 64, 64, 0);
+ wtu.glErrorShouldBe(gl, expected, msg + srcTexFormatsTypes.internalformat + '=>' + internalformat);
+
+ gl.deleteTexture(srcTexture);
+ gl.deleteFramebuffer(fbo);
+ }
+
+ goodUnormFormats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
+ srcTexFormatsTypes = { internalformat: "RGBA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
+ });
+ goodUnormFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
+ "copyTexImage2D should fail for good internalformat with unmatched component sizes ");
+ });
+
+ goodSRGBFormats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "SRGB8_ALPHA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
+ });
+
+ goodIntFormats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA32I", format: gl.RGBA_INTEGER, type: gl.INT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
+ });
+ goodIntFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA32I", format: gl.RGBA_INTEGER, type: gl.INT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
+ "copyTexImage2D should fail for good internalformat with unmatched component sizes ");
+ });
+
+ goodUnsignedIntFormats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA32UI", format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
+ });
+ goodUnsignedIntFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA32UI", format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
+ "copyTexImage2D should fail for good internalformat with unmatched component sizes ");
+ });
+
+ snormFormats.forEach(function(internalformat) {
+ const srcTexFormatsTypes = { internalformat: "RGBA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "copyTexImage2D should fail for snorm internalformat ");
+ });
+
+ if (gl.getExtension("EXT_color_buffer_float")) {
+ float16Formats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA16F", format: gl.RGBA, type: gl.FLOAT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for float16 internalformat ");
+ });
+ float32Formats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA32F", format: gl.RGBA, type: gl.FLOAT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for float32 internalformat ");
+ });
+ float11Formats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "R11F_G11F_B10F", format: gl.RGB, type: gl.FLOAT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for R11F_G11F_B10F internalformat ");
+ });
+
+ float32Formats.concat(float11Formats).forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA16F", format: gl.RGBA, type: gl.FLOAT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
+ "copyTexImage2D should fail for non-float16 internalformat (unmatched component sizes) ");
+ });
+ float16Formats.concat(float11Formats).forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "RGBA32F", format: gl.RGBA, type: gl.FLOAT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
+ "copyTexImage2D should fail for non-float32 internalformat (unmatched component sizes) ");
+ });
+ float16Formats.concat(float32Formats).forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "R11F_G11F_B10F", format: gl.RGB, type: gl.FLOAT };
+ testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
+ "copyTexImage2D should fail for non-R11F_G11F_B10F internalformat (unmatched component sizes) ");
+ });
+ }
+
+ depthAndOrStencilFormats.forEach(function(internalformat) {
+ var srcTexFormatsTypes = { internalformat: "DEPTH24_STENCIL8", format: gl.DEPTH_STENCIL, type: gl.UNSIGNED_INT_24_8};
+ testFormat(internalformat, srcTexFormatsTypes, gl.DEPTH_STENCIL_ATTACHMENT,
+ [gl.INVALID_ENUM, gl.INVALID_OPERATION],
+ "copyTexImage2D should fail for depth internalformat ");
+ });
+
+ gl.deleteTexture(texture);
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ testInternalformat();
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/generate-mipmap-with-large-base-level.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/generate-mipmap-with-large-base-level.html
new file mode 100644
index 0000000000..010cc0f913
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/generate-mipmap-with-large-base-level.html
@@ -0,0 +1,56 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test if GenerateMipmap on immutable texture with large BASE_LEVEL triggers a crash</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("This is a regression test for crbug.com/913301");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", null, 2);
+gl.clearColor(0, 1, 0, 1);
+
+var targets = [gl.TEXTURE_2D, gl.TEXTURE_3D];
+for (var ii = 0; ii < targets.length; ++ii) {
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var target = targets[ii];
+ var tex = gl.createTexture();
+ gl.bindTexture(target, tex);
+ gl.texParameteri(target, gl.TEXTURE_BASE_LEVEL, 1416354905);
+ gl.texParameteri(target, gl.TEXTURE_MAX_LEVEL, 5);
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ if (target == gl.TEXTURE_2D)
+ gl.texStorage2D(target, 5, gl.R8, 32, 32);
+ else
+ gl.texStorage3D(target, 5, gl.R8, 32, 32, 32);
+ // Should not crash calling generateMipmap.
+ gl.generateMipmap(target);
+ gl.deleteTexture(tex);
+ // If crashed, readPixels() won't be able to work correctly.
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 5);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/gl-get-tex-parameter.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/gl-get-tex-parameter.html
new file mode 100644
index 0000000000..babe388d14
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/gl-get-tex-parameter.html
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL getTexParameter 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>
+</head>
+<body>
+<canvas id="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../../js/tests/gl-get-tex-parameter.js"></script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/immutable-tex-render-feedback.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/immutable-tex-render-feedback.html
new file mode 100644
index 0000000000..c94e359d64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/immutable-tex-render-feedback.html
@@ -0,0 +1,221 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Ensure sampling-feedback detection can allow certain immutable texture uses</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+const wtu = WebGLTestUtils;
+description();
+
+const gl = wtu.create3DContext(undefined, undefined, 2);
+
+function* range(a, b) {
+ a.required;
+ if (b === undefined) {
+ b = a;
+ a = 0;
+ }
+ for (let i = a; i < b; i += 1) {
+ yield i;
+ }
+}
+
+const VS = `\
+void main() {
+ gl_PointSize = 1.0;
+}
+`;
+
+const FS = `\
+uniform sampler2D u_tex0;
+void main() {
+ gl_FragColor = texture2D(u_tex0, vec2(0));
+}
+`;
+
+const prog = wtu.loadProgram(gl, VS, FS);
+gl.useProgram(prog);
+
+(() => {
+ const MIPS = 3;
+ const SIZE = 10;
+
+ const immutTex = gl.createTexture();
+ immutTex.name = "immutTex";
+ immutTex.immutable = true;
+ gl.bindTexture(gl.TEXTURE_2D, immutTex);
+ gl.texStorage2D(gl.TEXTURE_2D, MIPS, gl.RGBA8, SIZE, SIZE);
+
+ const mutTex = gl.createTexture();
+ mutTex.name = "mutTex";
+ mutTex.immutable = false;
+ gl.bindTexture(gl.TEXTURE_2D, mutTex);
+ for (const mip of range(MIPS)) {
+ const size = SIZE >> mip;
+ gl.texImage2D(gl.TEXTURE_2D, mip, gl.RGBA8, size, size, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ const MAG_FILTERS = [
+ 'LINEAR',
+ 'NEAREST',
+ ];
+ const MIN_FILTERS = [
+ ['LINEAR',false],
+ ['LINEAR_MIPMAP_LINEAR',true],
+ ['LINEAR_MIPMAP_NEAREST',true],
+ ['NEAREST',false],
+ ['NEAREST_MIPMAP_LINEAR',true],
+ ['NEAREST_MIPMAP_NEAREST',true],
+ ];
+
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+
+ debug(`
+ mips: ${MIPS}: [0,${MIPS-1}] (inclusive)
+ size: ${SIZE}`);
+ const texs = [
+ immutTex,
+ mutTex,
+ ];
+ for (const tex of texs) {
+ debug(`\
+
+ immutable: ${tex.immutable}`);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ for (const level_prime_base of range(MIPS+1)) { // `level_base` in GLES
+ // ES 3.0.6 p150
+ let _level_base = level_prime_base;
+ if (tex.immutable) {
+ _level_base = Math.min(_level_base, MIPS-1);
+ }
+ const level_base = _level_base;
+
+ for (let _level_prime_max of range(level_prime_base-1, MIPS+2)) { // `q` in GLES
+ if (_level_prime_max < 0) continue;
+ if (_level_prime_max == MIPS+1) {
+ _level_prime_max = 10000; // This is the default, after all!
+ }
+ const level_prime_max = _level_prime_max;
+
+ // ES 3.0.6 p150
+ let _level_max = level_prime_max;
+ if (tex.immutable) {
+ _level_max = Math.min(Math.max(level_base, level_prime_max), MIPS-1);
+ }
+ const level_max = _level_max;
+
+ const p = Math.floor(Math.log2(SIZE)) + level_base;
+ const q = Math.min(p, level_max);
+
+ debug(`\
+
+ level_prime_base/max: [${level_prime_base}, ${level_prime_max}] (inclusive)
+ level_base/max: [${level_base}, ${level_max}] (inclusive)
+ q: ${q}`);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL,
+ level_prime_base);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL,
+ level_prime_max);
+
+ const mipComplete = (q <= MIPS-1);
+
+ for (const [minFilter,useMips] of MIN_FILTERS) {
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
+ gl[minFilter]);
+
+ // ES3.0 p211
+ const srcMaxSampledMip = (useMips ? q : level_base);
+
+ // ES3.0 p160-161
+ const textureComplete = (srcMaxSampledMip <= MIPS-1) &&
+ (level_base <= level_max);
+
+ for (const magFilter of MAG_FILTERS) {
+ debug(`\
+
+ min: ${minFilter}, mag: ${magFilter}`);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,
+ gl[magFilter]);
+
+ for (const dstMip of range(0,MIPS+1)) {
+ debug(`
+ mip: ${dstMip}`);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, tex, dstMip);
+
+ // -
+
+ // ES3.0 p213-214
+ let fbComplete = true;
+
+ // * "The width and height of `image` are non-zero"
+ fbComplete &= (0 <= dstMip && dstMip <= MIPS-1);
+
+ if (!tex.immutable) { // "...does not name an immutable-format texture..."
+ // * "...the value of [level] must be in the range `[level_base, q]`"
+ fbComplete &= (level_base <= dstMip && dstMip <= q);
+
+ // * "...the value of [level] is not `level_base`, then the texture must be mipmap complete"
+ if (dstMip != level_base) {
+ fbComplete &= mipComplete;
+ }
+ }
+
+ // -
+
+ let expectError = 0;
+ let expectStatus = gl.FRAMEBUFFER_COMPLETE;
+
+ // ES3.0 p211
+ let samplingFeedback = (level_base <= dstMip && dstMip <= srcMaxSampledMip);
+ if (!textureComplete) {
+ // Incomplete textures are safe
+ samplingFeedback = false;
+ }
+ if (samplingFeedback) {
+ expectError = gl.INVALID_OPERATION;
+ }
+ if (!fbComplete) {
+ expectStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ expectError = gl.INVALID_FRAMEBUFFER_OPERATION;
+ }
+
+ // -
+
+ wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER,
+ expectStatus, `{immutable: ${tex.immutable}, level_prime_base/max: [${level_prime_base}, ${level_prime_max}], minFilter: ${minFilter}, dest: ${dstMip}}`);
+
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expectError, "after draw with texture");
+ }
+ }
+ }
+ }
+ }
+ }
+})();
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-specification-order-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-specification-order-bug.html
new file mode 100644
index 0000000000..99ee766227
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-specification-order-bug.html
@@ -0,0 +1,216 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Integer Cubemap Texture Specification Order Bug 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>
+</head>
+<body>
+<canvas id="example" width="128" height="128"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vs" type="x-shader/x-vertex">#version 300 es
+ precision highp float;
+ in vec4 a_position;
+ void main(){
+ gl_Position = a_position;
+ }
+</script>
+<script id="fs" type="x-shader/x-fragment">#version 300 es
+ precision highp float;
+ // This program samples both textures at varying Lod and exposes
+ // both of them, the regular on top, and the weird on the bottom.
+ // On the NVIDIA driver the top is both green and red while the bottom
+ // is only green. This is a driver bug because both textures should be
+ // exactly the same.
+ // I think that because of our level specification order weirdness, the
+ // driver gets confused as to which levels are complete and thinks only
+ // level 0 is complete. Then when sampling the texture it clamps the sampling
+ // to only level 0, resulting in green for all Lod values.
+ layout(location = 0) out vec4 fragColor;
+ uniform highp isamplerCube texRegular;
+ uniform highp isamplerCube texWeird;
+ void main() {
+ vec2 fragPos = gl_FragCoord.xy / vec2(128.0, 128.0);
+ float lod = (fragPos.x - 0.5) * 10.0 + 0.5;
+
+ ivec4 colorRegular = textureLod(texRegular, vec3(1.0, 0.0, 0.0), lod);
+ ivec4 colorWeird = textureLod(texWeird, vec3(1.0, 0.0, 0.0), lod);
+
+ if (fragPos.y > 0.51) {
+ fragColor = vec4(vec2(colorRegular.rg), 0.0, 1.0);
+ } else if (fragPos.y < 0.49){
+ fragColor = vec4(vec2(colorWeird.rg), 0.0, 1.0);
+ } else {
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ }
+</script>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+
+description("Test for a driver bug when specifying integer cubemaps in weird order");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function createTextureCube(layers, maxLevel) {
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
+
+ layers.forEach(function(layer) {
+ var level = layer.level;
+ var face = layer.face;
+ var color = layer.color;
+
+ var levelSize = 1 << (maxLevel - level);
+
+ var backingBuffer = new ArrayBuffer(levelSize * levelSize * 2);
+ new Int16Array(backingBuffer).fill(color);
+ gl.texImage2D(face + gl.TEXTURE_CUBE_MAP_POSITIVE_X, level, gl.RG8I, levelSize, levelSize, 0, gl.RG_INTEGER, gl.BYTE, new Int8Array(backingBuffer));
+ });
+
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ 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);
+
+ return texture;
+}
+
+function makePermutedLayers(layers, permutation) {
+ return permutation.map(i => layers[i]);
+}
+
+function test() {
+ var kMaxLevel = 4;
+ var kBlack = 0x0000;
+ var kGreen = 0x7F00;
+ var kRed = 0x007F;
+
+ // Create two integer cubemaps with green on level 0 and red on the others.
+
+ // The "regular" cube map is filled in a sensible manner.
+ var regularLayers = [];
+ for (var level = 0; level <= kMaxLevel; level ++) {
+ for (var face = 0; face < 6; face ++) {
+ if (level == 0) {
+ regularLayers.push({level: level, face: face, color: kGreen});
+ } else {
+ regularLayers.push({level: level, face: face, color: kRed});
+ }
+ }
+ }
+
+ // The "weird" cube map has all its >= 1 levels filled, then the first level,
+ // then the >= 1 levels again but for one face. This replicates what the
+ // Chromium command buffer "cubemap completeness" workaround is doing.
+ var weirdLayers = [];
+ for (var level = 1; level <= kMaxLevel; level ++) {
+ for (var face = 0; face < 5; face ++) {
+ weirdLayers.push({level: level, face: face, color: kBlack});
+ }
+ weirdLayers.push({level: level, face: 5, color: kRed});
+ }
+ for (var level = 0; level <= kMaxLevel; level ++) {
+ for (var face = 0; face < 6; face ++) {
+ if (level == 0) {
+ weirdLayers.push({level: level, face: face, color: kGreen});
+ } else {
+ if (face != 5) {
+ weirdLayers.push({level: level, face: face, color: kRed});
+ }
+ }
+ }
+ }
+
+ var regularTex = createTextureCube(regularLayers, kMaxLevel);
+
+ var sampleProgram = wtu.setupProgram(gl, ["vs", "fs"], ["a_position"]);
+ var regularLocation = gl.getUniformLocation(sampleProgram, "texRegular");
+ var weirdLocation = gl.getUniformLocation(sampleProgram, "texWeird");
+
+ wtu.setupQuad(gl, gl.getAttribLocation(sampleProgram, "a_position"));
+
+ gl.uniform1i(regularLocation, 0);
+ gl.uniform1i(weirdLocation, 1);
+
+ function testcase(layers1, casename) {
+ var tex1 = createTextureCube(layers1, kMaxLevel);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, regularTex);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex1);
+ // At this point both textures should be the same.
+ wtu.drawUnitQuad(gl);
+
+ gl.deleteTexture(tex1);
+
+ wtu.checkCanvasRect(gl, 96, 32, 1, 1, [255, 0, 0, 255], "should be green: " + casename);
+ wtu.checkCanvasRect(gl, 96, 96, 1, 1, [255, 0, 0, 255], "should be green: " + casename);
+ wtu.checkCanvasRect(gl, 32, 32, 1, 1, [0, 255, 0, 255], "should be red: " + casename);
+ wtu.checkCanvasRect(gl, 32, 96, 1, 1, [0, 255, 0, 255], "should be red: " + casename);
+ }
+
+ testcase(weirdLayers, "original");
+ const cases = [
+ [10,23,3,19,26,29,14,9,4,11,27,28,13,24,20,12,17,21,16,5,6,25,1,15,22,8,7,18,0,2],
+ [10,27,3,29,17,28,13,20,18,25,9,2,8,4,24,12,15,7,19,11,6,14,16,21,1,26,23,22,0,5],
+ [11,4,15,13,26,24,25,2,19,20,16,23,1,18,28,27,6,21,14,8,17,29,3,10,12,9,22,7,0,5],
+ [14,2,6,28,7,25,11,26,22,13,19,21,24,4,16,29,9,27,3,17,18,15,12,20,8,23,10,1,0,5],
+ [14,20,22,16,11,27,17,21,15,3,5,28,6,2,9,12,7,24,1,26,8,19,23,25,18,13,29,10,0,4],
+ [14,20,22,16,11,27,17,21,15,3,5,28,6,2,9,12,7,24,1,26,8,19,23,25,18,13,29,10,0,4],
+ [14,22,27,1,12,24,13,21,6,10,20,28,23,16,5,18,7,3,25,2,11,19,17,26,8,29,15,9,0,4],
+ [15,22,13,28,6,12,19,9,18,11,3,23,17,8,10,20,5,14,4,25,27,26,21,16,29,24,7,0,1,2],
+ [15,22,13,28,6,12,19,9,18,11,3,23,17,8,10,20,5,14,4,25,27,26,21,16,29,24,7,0,1,2],
+ [16,22,18,15,19,6,21,27,4,14,29,17,7,9,11,20,24,23,28,25,2,13,10,26,8,12,3,0,5,1],
+ [16,26,18,7,20,25,11,24,2,1,28,13,29,10,27,21,6,15,5,19,17,12,14,9,23,22,8,3,0,4],
+ [2,22,25,12,19,16,7,27,9,10,8,17,18,24,1,21,20,14,13,4,11,29,15,5,23,26,6,28,0,3],
+ [2,9,16,26,6,15,4,3,17,13,21,10,7,22,23,29,19,18,12,24,14,25,8,5,20,28,11,27,0,1],
+ [2,9,16,26,6,15,4,3,17,13,21,10,7,22,23,29,19,18,12,24,14,25,8,5,20,28,11,27,0,1],
+ [20,21,24,15,5,13,6,12,2,17,10,14,27,16,8,22,9,25,29,1,28,11,4,19,7,23,26,18,0,3],
+ [21,14,19,12,28,6,10,7,16,27,11,22,20,24,25,26,3,8,4,18,5,2,9,15,17,23,13,29,0,1],
+ [22,4,18,7,11,6,23,17,14,3,13,21,15,19,25,28,9,8,10,12,29,16,27,2,24,1,20,26,0,5],
+ [22,4,18,7,11,6,23,17,14,3,13,21,15,19,25,28,9,8,10,12,29,16,27,2,24,1,20,26,0,5],
+ [23,21,9,28,22,15,25,12,24,18,29,2,17,1,14,4,16,26,3,11,27,13,8,7,6,20,10,19,0,5],
+ [23,6,15,13,19,2,12,7,11,29,3,20,17,10,4,18,1,22,16,27,24,9,21,25,14,26,8,28,0,5],
+ [25,12,1,4,9,22,16,28,6,11,14,29,15,2,5,13,10,20,21,19,23,27,18,26,7,8,17,24,0,3],
+ [25,13,29,26,28,17,19,23,7,24,10,1,15,8,3,11,18,21,27,22,12,5,9,6,16,14,20,2,0,4],
+ [25,18,28,12,27,13,11,4,29,8,21,15,9,6,26,20,22,23,24,17,5,16,2,7,14,19,10,0,1,3],
+ [25,19,3,10,23,15,27,18,12,8,7,24,16,14,26,4,21,5,9,1,22,28,20,29,6,11,13,17,0,2],
+ [25,24,12,9,13,10,23,4,19,29,16,1,15,8,21,26,18,11,17,7,20,28,22,14,27,6,0,2,5,3],
+ [25,9,29,8,3,6,10,27,11,28,13,23,18,16,17,19,5,22,12,26,21,4,7,14,24,15,2,20,0,1],
+ [27,23,20,2,12,14,6,19,3,28,18,10,29,11,13,22,21,7,15,9,8,17,25,16,26,24,4,5,0,1],
+ [27,7,2,5,19,10,3,26,22,18,23,16,9,24,21,17,6,28,12,14,25,29,13,15,8,20,11,4,0,1],
+ [28,7,10,9,29,27,2,20,1,26,11,5,12,23,25,3,17,16,24,13,8,6,14,18,21,19,15,22,0,4],
+ [28,8,23,13,18,29,20,9,10,27,15,21,3,19,14,4,26,5,24,1,6,17,11,12,16,7,25,22,0,2],
+ [29,12,13,2,22,19,16,7,14,11,24,23,28,15,17,9,20,21,18,26,27,25,10,5,8,6,4,3,0,1],
+ [29,8,5,4,7,15,19,17,3,26,13,9,23,6,25,22,27,24,14,16,10,21,11,18,28,12,2,20,0,1],
+ [5,18,6,17,19,16,13,11,28,8,10,4,29,26,20,24,9,7,21,25,27,23,22,2,15,14,12,0,3,1],
+ [5,23,2,15,7,13,19,11,27,3,22,14,4,26,28,20,17,18,8,25,16,29,10,24,12,9,6,21,0,1],
+ [7,24,27,26,16,18,22,20,10,11,9,19,23,12,17,13,4,2,6,1,21,25,15,28,8,3,29,14,0,5],
+ ];
+ for (const c of cases) {
+ testcase(makePermutedLayers(regularLayers, c), "case " + c.toString());
+ }
+}
+
+test();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-texture-sampling.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-texture-sampling.html
new file mode 100644
index 0000000000..8ad4967608
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-texture-sampling.html
@@ -0,0 +1,169 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Integer Cubemap Texture Sampling Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="128" height="128"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+var tiu = TexImageUtils;
+
+description("Verify sampling works fine with integer cubemap textures");
+debug("https://github.com/KhronosGroup/WebGL/issues/1819");
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var testCases = [
+ { internalFormat: "R8UI", format: "RED_INTEGER", type: "UNSIGNED_BYTE" },
+ { internalFormat: "RG8UI", format: "RG_INTEGER", type: "UNSIGNED_BYTE" },
+ { internalFormat: "RGB8UI", format: "RGB_INTEGER", type: "UNSIGNED_BYTE" },
+ { internalFormat: "RGBA8UI", format: "RGBA_INTEGER", type: "UNSIGNED_BYTE" },
+];
+
+function setupData(internalFormat, size) {
+ var numComponents = 0;
+ switch (gl[internalFormat]) {
+ case gl.R8UI:
+ numComponents = 1;
+ break;
+ case gl.RG8UI:
+ numComponents = 2;
+ break;
+ case gl.RGB8UI:
+ numComponents = 3;
+ break;
+ case gl.RGBA8UI:
+ numComponents = 4;
+ break;
+ }
+ if (numComponents == 0) {
+ testFailed("This should never be reached");
+ return null;
+ }
+ var data = new Uint8Array(numComponents * size * size);
+ for (var ii = 0; ii < size * size; ++ii) {
+ // Set all pixels to RED.
+ data[ii * numComponents] = 255;
+ if (numComponents > 1)
+ data[ii * numComponents + 1] = 0;
+ if (numComponents > 2)
+ data[ii * numComponents + 2] = 0;
+ if (numComponents > 3)
+ data[ii * numComponents + 3] = 255;
+ }
+ return data;
+}
+
+function checkIntegerTextureValues(internalFormat, size) {
+ var buffer = new Uint32Array(4 * size * size);
+ gl.readPixels(0, 0, size, size, gl.RGBA_INTEGER, gl.UNSIGNED_INT, buffer);
+ for (var y = 0; y < size; ++y) {
+ for (var x = 0; x < size; ++x) {
+ var index = (y * size + x) * 4;
+ if (buffer[index] != 255 || buffer[index + 1] != 0 || buffer[index + 2] != 0) {
+ testFailed("At (" + x + ", " + y + "), expected 255,0,0,255, was " +
+ [buffer[index], buffer[index + 1], buffer[index + 2], buffer[index + 3]]);
+ return;
+ }
+ }
+ }
+ testPassed("All pixels are as expected");
+}
+
+function runOneTest(internalFormat, format, type, size) {
+ debug("");
+ debug("Testing internalformat = " + internalFormat + ", format = " + format + ", type = " + type + ", size = " + size);
+
+ gl.clearColor(1, 1, 0, 1);
+ gl.clearDepth(1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ 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.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ var targets = [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];
+ var data = setupData(internalFormat, size);
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.texImage2D(targets[tt], 0, gl[internalFormat], size, size, 0, gl[format], gl[type], data);
+ }
+
+ debug("1) Reading back texture data");
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, targets[tt], tex, 0);
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ checkIntegerTextureValues(internalFormat, size);
+ }
+ }
+ gl.deleteFramebuffer(fbo);
+
+ debug("2) Rendering with texture");
+ var program = tiu.setupTexturedQuadWithCubeMap(gl, internalFormat);
+ var loc = gl.getUniformLocation(program, "face");
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.uniform1i(loc, targets[tt]);
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl, [0, 255, 0, 255]);
+ wtu.checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, [255, 0, 0, 255], "Should be red");
+ }
+ gl.deleteProgram(program);
+ gl.deleteTexture(tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL errors");
+
+ var m = wtu.makeImageFromCanvas(gl.canvas);
+ document.getElementById("console").appendChild(m);
+ document.getElementById("console").appendChild(document.createElement("hr"));
+}
+
+function runTests() {
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 2);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 4);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 8);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 16);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 32);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 64);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 65);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 127);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 128);
+ runOneTest(testCases[ii].internalFormat, testCases[ii].format, testCases[ii].type, 129);
+ }
+}
+
+runTests();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/mipmap-fbo.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/mipmap-fbo.html
new file mode 100644
index 0000000000..cd48bb77c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/mipmap-fbo.html
@@ -0,0 +1,50 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test if mipmap incomplete textures can be used as FBO attachments</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var testIncompleteMipmapInFBO = function () {
+ // Create a texture that's not mipmap complete.
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ // Framebuffer should be incomplete for incomplete texture.
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 1);
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+}
+
+testIncompleteMipmapInFBO();
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/npot-video-sizing.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/npot-video-sizing.html
new file mode 100644
index 0000000000..3ce3917da3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/npot-video-sizing.html
@@ -0,0 +1,181 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = null;
+var textureLoc = null;
+var expectedVideoHeightLoc = null;
+var successfullyParsed = false;
+var resourcePath = "../../../resources/";
+// Test each format separately because many browsers implement each
+// differently. Some might be GPU accelerated, some might not. Etc...
+var videos = [
+ { src: resourcePath + "npot-video-1920x1080.mp4" ,
+ type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
+ // It was found that Firefox's videoHeight doesn't report the
+ // correct answer for this video resource, though the uploaded
+ // video texture is the correct size.
+ expectedHeight: 1080,
+ },
+ // Should port this to other formats. See tex-image-and-sub-image-2d-with-video.js.
+];
+var videoNdx = 0;
+var videoInfo;
+var video;
+
+initTestingHarness();
+
+var vertexShader = [
+ '#version 300 es',
+ 'in vec4 vPosition;',
+ 'in vec2 texCoord0;',
+ 'out vec2 texCoord;',
+ 'void main() {',
+ ' gl_Position = vPosition;',
+ ' texCoord = texCoord0;',
+ '}'].join('\n');
+
+// ESSL 3.00 and WebGL 2.0 are used in order to gain access to the
+// "textureSize" built-in function. This was the most reliable way to
+// verify the behavior of video-to-texture uploads.
+
+var fragmentShader = [
+ '#version 300 es',
+ 'precision mediump float;',
+ 'uniform mediump sampler2D tex;',
+ 'uniform int expectedVideoHeight;',
+ 'in vec2 texCoord;',
+ 'out vec4 fragData;',
+ 'void main() {',
+ ' if (textureSize(tex, 0).y == expectedVideoHeight) {',
+ ' fragData = vec4(0.0, 1.0, 0.0, 1.0);',
+ ' } else {',
+ ' fragData = vec4(1.0, 0.0, 0.0, 1.0);',
+ ' }',
+ '}'].join('\n');
+
+function init()
+{
+ description('Verify sizing of npot videos uploaded to textures');
+
+ debug('Verifies that the size of a texture, uploaded from a video, is exactly the expected size of the video.');
+ debug('Regression test for <a href="http://crbug.com/672895">http://crbug.com/672895</a>');
+
+ var canvas = document.getElementById("example");
+ gl = wtu.create3DContext(canvas, { preserveDrawingBuffer: true }, 2);
+ wtu.setupUnitQuad(gl);
+ var program = wtu.setupProgram(
+ gl,
+ [vertexShader, fragmentShader],
+ ['vPosition', 'texCoord0'],
+ [0, 1]);
+
+ if (!program) {
+ testFailed("Error creating program");
+ return;
+ }
+
+ gl.clearColor(0,0,0,1);
+ gl.clearDepth(1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ // Disable any writes to the alpha channel
+ gl.colorMask(1, 1, 1, 0);
+
+ textureLoc = gl.getUniformLocation(program, "tex");
+ expectedVideoHeightLoc = gl.getUniformLocation(
+ program, "expectedVideoHeight");
+
+ requestAnimationFrame(runNextVideo);
+}
+
+function runNextVideo() {
+ if (video) {
+ video.pause();
+ }
+
+ if (videoNdx == videos.length) {
+ finishTest();
+ return;
+ }
+
+ videoInfo = videos[videoNdx++];
+ debug("");
+ debug("testing: " + videoInfo.type);
+ video = document.createElement("video");
+ video.muted = true;
+ var canPlay = true;
+ if (!video.canPlayType) {
+ testFailed("video.canPlayType required method missing");
+ requestAnimationFrame(runNextVideo);
+ return;
+ }
+
+ if (!video.canPlayType(videoInfo.type).replace(/no/, '')) {
+ debug(videoInfo.type + " unsupported");
+ requestAnimationFrame(runNextVideo);
+ return;
+ };
+
+ document.body.appendChild(video);
+ video.style = "display:none;";
+ video.type = videoInfo.type;
+ video.src = videoInfo.src;
+ wtu.startPlayingAndWaitForVideo(video, runTest);
+}
+
+function runTest()
+{
+ var texture = gl.createTexture();
+ // Bind the texture to texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ // Set up texture parameters
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ 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);
+ // Set up pixel store parameters
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+ // Upload the video element into the texture
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, video);
+ // Point the uniform sampler to texture unit 0
+ gl.uniform1i(textureLoc, 0);
+ // Set up the expected video size
+ debug('video\'s expected height: ' + videoInfo.expectedHeight);
+ debug('video\'s reported width and height: ' + video.videoWidth + ' x ' + video.videoHeight);
+ // We only verify the height. Chrome was generating the wrong
+ // height for some video resources. As it stands, not all browsers
+ // match the video's width exactly.
+ gl.uniform1i(expectedVideoHeightLoc, videoInfo.expectedHeight);
+
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+
+ // Verify that the video texture's size was as expected
+ wtu.checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height,
+ [0, 255, 0, 255],
+ "Should be green -- that indicates the video texture's height was correct",
+ 1);
+
+ requestAnimationFrame(runNextVideo);
+}
+
+</script>
+</head>
+<body onload="init()">
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html
new file mode 100644
index 0000000000..2c6a118cc1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html
@@ -0,0 +1,146 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Origin Restrictions Conformance Tests for OffscreenCanvas</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas"></canvas>
+<img id="img" style="display:none;">
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+
+// Checks if function throws an exception.
+function causedException(func) {
+ var hadException = false;
+ try {
+ func();
+ } catch(e) {
+ hadException = true;
+ }
+ return hadException;
+}
+
+var defaultImgUrl = "https://get.webgl.org/conformance-resources/opengl_logo.jpg";
+var localImgUrl = "../../../resources/opengl_logo.jpg";
+
+var imgDomain;
+var pageDomain;
+
+function imageLoaded(img) {
+ description("This test ensures WebGL2 implementations for OffscreenCanvas follow proper same-origin restrictions.");
+
+ if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+ return;
+ }
+
+ assertMsg(img.width > 0 && img.height > 0, "img was loaded");
+ imgDomain = wtu.getBaseDomain(wtu.getHost(img.src));
+ pageDomain = wtu.getBaseDomain(window.location.host);
+ assertMsg(imgDomain != pageDomain,
+ "img domain (" + imgDomain + ") and page domain (" + pageDomain + ") are not the same.");
+
+ function makeTexImage2D(gl, src) {
+ return function() {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 10, 10, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexSubImage2D(gl, src) {
+ return function() {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 10, 10, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexImage3D(gl, src) {
+ return function() {
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 10, 10, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexSubImage3D(gl, src) {
+ return function() {
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 10, 10, 1, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeReadPixels(gl) {
+ return function() {
+ var buf = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ };
+ }
+
+ var offscreencanvas = new OffscreenCanvas(10, 10);
+ var gl = wtu.create3DContext(offscreencanvas, null, 2);
+
+ debug("");
+ debug("check that an attempt to upload an image from another origin throws an exception.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ assertMsg(causedException(makeTexImage2D(gl, img)),
+ "texImage2D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, img)),
+ "texSubImage2D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexImage3D(gl, img)),
+ "texImage3D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexSubImage3D(gl, img)),
+ "texSubImage3D with cross-origin image should throw exception.");
+
+
+ debug("check that readPixels continues to work against this offscreencanvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL2 canvas.");
+
+ debug("check that an attempt to upload a tainted canvas throws an exception.");
+ var canvas = document.getElementById("canvas");
+ var ctx2d = canvas.getContext("2d");
+ ctx2d.drawImage(img, 0, 0);
+ assertMsg(causedException(makeTexImage2D(gl, canvas)),
+ "texImage2D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, canvas)),
+ "texSubImage2D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexImage3D(gl, canvas)),
+ "texImage3D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexSubImage3D(gl, canvas)),
+ "texSubImage3D with NON origin clean canvas should throw exception.");
+
+ debug("check that readPixels continues to work against this offscreencanvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL2 canvas.");
+
+ // TODO: Should check video.
+ // TODO: Should check CORS support.
+
+ finishTest();
+}
+
+(async function() {
+ const img = document.getElementById('img');
+ try {
+ await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl), 1000);
+ } catch (e) {
+ testFailed(`Image setup failed (${e}).`);
+ finishTest();
+ return;
+ }
+ imageLoaded(img);
+})();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html
new file mode 100644
index 0000000000..594938c089
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html
@@ -0,0 +1,82 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 3D texture mipmap level conformance 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>
+</head>
+<body>
+<canvas id="example" width="2" height="2" style="width: 2px; height: 2px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader_texsize" type="x-shader/x-vertex">#version 300 es
+in vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader_texsize_3d" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform highp sampler3D tex;
+uniform int lod;
+uniform ivec3 texSize;
+out vec4 fragColor;
+void main()
+{
+ fragColor = (textureSize(tex, lod) == texSize ? vec4(255, 0, 0, 255) : vec4(0, 0, 0, 255));
+}
+</script>
+
+
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+// This test fails on Intel Mesa, see crbug.com/666384.
+(function() {
+ debug("");
+ debug("Test textureSize should work correctly with non-zero base level for texStorage3D");
+ var program = wtu.setupProgram(
+ gl, ['vshader_texsize', 'fshader_texsize_3d'], ['vPosition'], [0]);
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
+ gl.uniform1i(gl.getUniformLocation(program, "lod"), 1);
+ gl.uniform3i(gl.getUniformLocation(program, "texSize"), 8, 4, 2);
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MAG_FILTER) should succeed");
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MIN_FILTER) should succeed");
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_BASE_LEVEL, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
+ gl.texStorage3D(gl.TEXTURE_3D, 4, gl.RGBA8, 32, 16, 8);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage3D should succeed");
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should draw with [255, 0, 0, 255]");
+ gl.deleteTexture(tex3d);
+})();
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-size-limit.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-size-limit.html
new file mode 100644
index 0000000000..6c2fbc4fa9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-size-limit.html
@@ -0,0 +1,189 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL FramebufferTextureLayer 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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl;
+var canvas = document.getElementById("canvas");
+
+function numLevelsFromSize(size) {
+ var levels = 0;
+ while ((size >> levels) > 0) {
+ ++levels;
+ }
+ return levels;
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function test3DTextureDimensions() {
+ debug("");
+ debug("Checking 3D texture dimensions.");
+
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ var maxTexSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE);
+ var maxLevels = numLevelsFromSize(maxTexSize);
+
+ gl.texImage3D(gl.TEXTURE_3D,
+ 0, // level
+ gl.RGBA, // internalFormat
+ 1, // width
+ 1, // height
+ -1, // depth
+ 0, // border
+ gl.RGBA, // format
+ gl.UNSIGNED_BYTE, // type
+ null); // data
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "texImage3D should fail for dimension out of range.");
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, maxTexSize + 1, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "texImage3D should fail for dimension out of range.");
+
+ for (var i = 0; i < maxLevels; ++i) {
+ var level = maxLevels - i - 1;
+ var badSize = 1 << (i + 1);
+
+ gl.texImage3D(gl.TEXTURE_3D, level, gl.RGBA, badSize, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texImage3D should fail for dimension out of range.");
+ gl.texImage3D(gl.TEXTURE_3D, level, gl.RGBA, 2, badSize, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texImage3D should fail for dimension out of range.");
+ gl.texImage3D(gl.TEXTURE_3D, level, gl.RGBA, 2, 2, badSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texImage3D should fail for dimension out of range.");
+ }
+
+ // Probe to discover the max non-OOM level.
+ var numTestLevels = maxLevels;
+ while (true) {
+ gl.texImage3D(gl.TEXTURE_3D, numTestLevels-1, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ var err = gl.getError();
+ if (err == gl.OUT_OF_MEMORY) {
+ debug("Probe failed for level=" + (numTestLevels-1) + ", reducing...");
+ numTestLevels -= 1;
+ if (!numTestLevels) {
+ testFailed("Failed to allocate any levels");
+ return;
+ }
+ continue;
+ }
+ if (err) {
+ testFailed("Should not hit non-OOM errors during max level probing.");
+ return;
+ }
+ break;
+ }
+
+ for (var i = 0; i < numTestLevels; ++i) {
+ var level = numTestLevels - i - 1;
+ var size = 1 << i;
+
+ gl.texImage3D(gl.TEXTURE_3D, level, gl.RGBA, size, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed for level: " + level + " " + size + "x1x1.");
+ gl.texImage3D(gl.TEXTURE_3D, level, gl.RGBA, 1, size, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed for level: " + level + " 1x" + size + "x1.");
+ gl.texImage3D(gl.TEXTURE_3D, level, gl.RGBA, 1, 1, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed for level: " + level + " 1x1x" + size + ".");
+ }
+
+ // Clean up
+ gl.deleteTexture(tex3d);
+}
+
+function test3DTexturePixelSize() {
+ debug("");
+ debug("Checking pixel data array is big enough for request.");
+
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ var tests = [
+ {
+ internalformat: gl.RGBA,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ size: 4,
+ dataType: Uint8Array
+ },
+ {
+ internalformat: gl.R8,
+ format: gl.RED,
+ type: gl.UNSIGNED_BYTE,
+ size: 1,
+ dataType: Uint8Array
+ },
+ {
+ internalformat: gl.RGB565,
+ format: gl.RGB,
+ type: gl.UNSIGNED_SHORT_5_6_5,
+ size: 1,
+ dataType: Uint16Array
+ },
+ {
+ internalformat: gl.RGBA32I,
+ format: gl.RGBA_INTEGER,
+ type: gl.INT,
+ size: 4,
+ dataType: Int32Array
+ },
+ {
+ internalformat: gl.RGBA32F,
+ format: gl.RGBA,
+ type: gl.FLOAT,
+ size: 4,
+ dataType: Float32Array
+ },
+ ];
+
+ tests.forEach(function(test) {
+ debug("");
+ debug("Testing internalformat " + enumToString(test.internalformat)
+ + ", format " + enumToString(test.format)
+ + ", type " + enumToString(test.type));
+
+ var pixels = new test.dataType(256 * 256 * 4 * test.size);
+ gl.texImage3D(gl.TEXTURE_3D, 0, test.internalformat, 256, 256, 256, 0, test.format, test.type, pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "ArrayBufferView not big enough for request by texImage3D.");
+ gl.texImage3D(gl.TEXTURE_3D, 0, test.internalformat, 256, 256, 4, 0, test.format, test.type, pixels);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "ArrayBufferView big enough for request by texImage3D.");
+ pixels = new test.dataType(256 * 256 * 1 * test.size);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 256, 256, 2, test.format, test.type, pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "ArrayBufferView not big enough for request by texSubImage3D.");
+ });
+
+ gl.deleteTexture(tex3d);
+}
+
+description("This tests size limits of 3D textures.");
+
+shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)");
+
+test3DTextureDimensions();
+test3DTexturePixelSize();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-base-level-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-base-level-bug.html
new file mode 100644
index 0000000000..47f049fd8a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-base-level-bug.html
@@ -0,0 +1,76 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 texture base level bug conformance 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="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="2" height="2" style="width: 2px; height: 2px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext("example", undefined, 2);
+var tiu = TexImageUtils;
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+function runtest() {
+ debug("");
+ debug("This is a regression test for <a href='https://crbug.com/705865'>Chromium Issue 705865</a>");
+ var tex = gl.createTexture();
+ var program = tiu.setupTexturedQuad(gl, "RGBA");
+
+ // Test that filling partial levels is enough for mipmapping.
+ var width = 2;
+ var height = 2;
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ wtu.fillTexture(gl, tex, width, height, [255, 0, 0, 255], 2, gl.RGBA, gl.UNSIGNED_BYTE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 2);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Texture setup should succeed");
+
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should draw with [255, 0, 0, 255]");
+
+ width = 1;
+ height = 1;
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D should succeed");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should draw with [255, 0, 0, 255]");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,"checkCanvas should succeed");
+
+ gl.deleteTexture(tex);
+
+};
+
+runtest();
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html
new file mode 100644
index 0000000000..0abd2b5a3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html
@@ -0,0 +1,197 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="2" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Verifies tex{Sub}Image{2|3}D code paths taking partial ArrayBufferView');
+
+var wtu = WebGLTestUtils;
+var tiu = TexImageUtils;
+
+function createSource(width, height, depth, viewType, offset) {
+ var size = width * height * depth * 4; // RGBA
+ var buf = new window[viewType](size + offset);
+ for (var ii = 0; ii < size; ++ii) {
+ if (viewType == "Float32Array")
+ buf[ii + offset] = ii / 255.0;
+ else
+ buf[ii + offset] = ii;
+ }
+ return buf;
+}
+
+function comparePixels(ref, refOffset, data, tol) {
+ for (var ii = 0; ii < data.length; ++ii) {
+ // Skip alpha due to shader's handling of alpha values.
+ if (ii % 4 == 3)
+ continue;
+ var src = ref[ii + refOffset];
+ if (ref instanceof Float32Array)
+ src *= 255;
+ if (Math.abs(src - data[ii]) > tol) {
+ testFailed("Element " + ii + ": expected " + src + ", got " + data[ii]);
+ return;
+ }
+ }
+ return testPassed("texture data uploaded correctly");
+}
+
+function run2DTest(gl, test, width, height, srcOffset, tol) {
+ debug("");
+ debug("Tesing tex{Sub}Image2D with sub source: internalformat = " + test.internalformat +
+ ", format = " + test.format + ", type = " + test.type);
+
+ var program = tiu.setupTexturedQuad(gl, test.internalformat);
+ if (!program) {
+ testFailed("Failed to set up program");
+ return;
+ }
+
+ var buf = createSource(width, height, 1, test.viewType, srcOffset);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ 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.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0,
+ gl[test.format], gl[test.type], buf, srcOffset + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0,
+ gl[test.format], gl[test.type], buf, srcOffset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D succeeds with correct buffer and srcOffset");
+
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ var readBuf = new Uint8Array(width * height * 4);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+ var tol = 0.5;
+ comparePixels(buf, srcOffset, readBuf, tol);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0,
+ gl[test.format], gl[test.type], null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl[test.format], gl[test.type],
+ buf, srcOffset + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl[test.format], gl[test.type],
+ buf, srcOffset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D succeeds with correct buffer and srcOffset");
+
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+ comparePixels(buf, srcOffset, readBuf, tol);
+
+ gl.deleteTexture(texture);
+ gl.deleteProgram(program);
+}
+
+function run3DTest(gl, test, width, height, srcOffset, tol) {
+ debug("");
+ debug("Tesing tex{Sub}Image3D with sub source: internalformat = " + test.internalformat +
+ ", format = " + test.format + ", type = " + test.type);
+
+ var program = tiu.setupTexturedQuadWith3D(gl, test.internalformat);
+ if (!program) {
+ testFailed("Failed to set up program");
+ return;
+ }
+
+ var depth = 1;
+ var buf = createSource(width, height, depth, test.viewType, srcOffset);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, texture);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0,
+ gl[test.format], gl[test.type], buf, srcOffset + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0,
+ gl[test.format], gl[test.type], buf, srcOffset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D succeeds with correct buffer and srcOffset");
+
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ var readBuf = new Uint8Array(width * height * 4);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+ var tol = 0.5;
+ comparePixels(buf, srcOffset, readBuf, tol);
+
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0,
+ gl[test.format], gl[test.type], null);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl[test.format], gl[test.type],
+ buf, srcOffset + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl[test.format], gl[test.type],
+ buf, srcOffset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D succeeds with correct buffer and srcOffset");
+
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+ comparePixels(buf, srcOffset, readBuf, tol);
+
+ gl.deleteTexture(texture);
+ gl.deleteProgram(program);
+}
+
+var gl = wtu.create3DContext("example", undefined, 2);
+if (!gl) {
+ testFailed("Fail to get a WebGL context");
+} else {
+ var testCases = [
+ { internalformat: 'RGBA8', format: 'RGBA', type: 'UNSIGNED_BYTE',
+ viewType: 'Uint8Array', },
+ { internalformat: 'RGBA8I', format: 'RGBA_INTEGER', type: 'BYTE',
+ viewType: 'Int8Array', },
+ { internalformat: 'RGBA16UI', format: 'RGBA_INTEGER', type: 'UNSIGNED_SHORT',
+ viewType: 'Uint16Array', },
+ { internalformat: 'RGBA16I', format: 'RGBA_INTEGER', type: 'SHORT',
+ viewType: 'Int16Array', },
+ { internalformat: 'RGBA32UI', format: 'RGBA_INTEGER', type: 'UNSIGNED_INT',
+ viewType: 'Uint32Array', },
+ { internalformat: 'RGBA32I', format: 'RGBA_INTEGER', type: 'INT',
+ viewType: 'Int32Array', },
+ { internalformat: 'RGBA32F', format: 'RGBA', type: 'FLOAT',
+ viewType: 'Float32Array', },
+ ];
+
+ var srcOffset = 3;
+ var tol = 0.5;
+
+ for (var idx = 0; idx < testCases.length; ++idx) {
+ run2DTest(gl, testCases[idx], gl.drawingBufferWidth, gl.drawingBufferHeight, srcOffset, tol);
+ run3DTest(gl, testCases[idx], gl.drawingBufferWidth, gl.drawingBufferHeight, srcOffset, tol);
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html
new file mode 100644
index 0000000000..f1616e81d7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html
@@ -0,0 +1,128 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="c" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests texImage2D with invalid internalformat/format/type combinations from various dom elements');
+
+debug("<a href='https://www.khronos.org/registry/webgl/specs/latest/2.0/#TEXTURE_TYPES_FORMATS_FROM_DOM_ELEMENTS_TABLE'>Valid internalformat/format/type combinations</a>");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c", undefined, 2);
+
+var doTexImage = function(domElement) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, domElement);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_ENUM, gl.INVALID_OPERATION], "TexImage2D taking RGB10_A2UI/RGBA_INTEGER/UNSIGNED_INT_2_10_10_10_REV should fail");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RG8, gl.RG, gl.FLOAT, domElement);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "TexImage2D taking RG8/RG/FLOAT should fail");
+ gl.deleteTexture(tex);
+}
+
+var createCanvas2DContext = function(width, height) {
+ var canvas = document.createElement("canvas");
+ canvas.width = width;
+ canvas.height = height;
+ var ctx = canvas.getContext("2d");
+ ctx.fillRect(0, 0, width, height);
+ return ctx;
+};
+
+var testImage = function(test) {
+ debug("HTMLImageElement");
+ var img = wtu.makeImage(test.src, function() {
+ doTexImage(img);
+ setTimeout(runNextTest, 0);
+ });
+}
+
+var testVideo = function(test) {
+ debug("HTMLVideoElement (" + test.videoType + ")");
+ var video = wtu.makeVideo(test.src);
+ if(!video.canPlayType(test.videoType).replace(/no/, '')) {
+ debug(test.videoType + " unsupported");
+ setTimeout(runNextTest, 0);
+ return;
+ }
+ wtu.startPlayingAndWaitForVideo(video, function() {
+ doTexImage(video);
+ setTimeout(runNextTest, 0);
+ });
+}
+
+var testCanvas = function(test) {
+ var ctx = createCanvas2DContext(test.width, test.height);
+ debug("HTMLCanvasElement");
+ doTexImage(ctx.canvas);
+ setTimeout(runNextTest, 0);
+}
+
+var testImageData = function(test) {
+ var ctx = createCanvas2DContext(test.width, test.height);
+ var imageData = ctx.getImageData(0, 0, test.width, test.height);
+ debug("ImageData");
+ doTexImage(imageData);
+ setTimeout(runNextTest, 0);
+}
+
+var testImageBitmap = function(test) {
+ debug("ImageBitmap");
+ if(!window.createImageBitmap || !window.ImageBitmap) {
+ debug("ImageBitmap isn't supported");
+ setTimeout(runNextTest, 0);
+ return;
+ }
+ var ctx = createCanvas2DContext(test.width, test.height);
+ createImageBitmap(ctx.canvas, 0, 0, test.width, test.height).then(function(imageBitmap) {
+ doTexImage(imageBitmap);
+ setTimeout(runNextTest, 0);
+ }, function() {
+ debug("createImageBitmap was rejected");
+ setTimeout(runNextTest, 0);
+ });
+}
+
+var tests = [
+ { type: "canvas", width: 64, height: 64, run: testCanvas },
+ { type: "image", src: "../../../resources/red-green.png", run: testImage },
+ { type: "ImageBitmap",width: 64, height: 64, run: testImageBitmap },
+ { type: "ImageData", width: 64, height: 64, run: testImageData },
+ { type: "video", src: "../../../resources/red-green.mp4", videoType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', run: testVideo },
+ { type: "video", src: "../../../resources/red-green.bt601.vp9.webm", videoType: 'video/webm; codecs="vp9"', run: testVideo },
+ { type: "video", src: "../../../resources/red-green.webmvp8.webm", videoType: 'video/webm; codecs="vp8, vorbis"', run: testVideo },
+ { type: "video", src: "../../../resources/red-green.theora.ogv", videoType: 'video/ogg; codecs="theora, vorbis"', run: testVideo },
+];
+
+var testIndex = 0;
+var runNextTest = function() {
+ if (testIndex < tests.length) {
+ debug("");
+ var test = tests[testIndex];
+ ++testIndex;
+ test.run(test);
+ } else {
+ finishTest();
+ }
+};
+
+runNextTest();
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args.html
new file mode 100644
index 0000000000..514e5eebc1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args.html
@@ -0,0 +1,57 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="c" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests texImage2D with invalid internalformat/format/type combinations');
+debug("This includes a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=656889'>Chromium Issue 656889</a>");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("c", null, 2);
+var ext = null;
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+}
+
+var doTexImage = function(test) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, test.internalformat, 64, 64, 0, test.format, test.type, null);
+ wtu.glErrorShouldBe(gl, test.errors, "TexImage2D taking " + wtu.glEnumToString(gl, test.internalformat) + "/" +
+ wtu.glEnumToString(gl, test.format) + "/" + wtu.glEnumToString(gl, test.type));
+ gl.deleteTexture(tex);
+}
+
+var tests = [
+ { internalformat: gl.RGBA, format: gl.RGBA, type: gl.UNSIGNED_BYTE, errors: [gl.NO_ERROR] },
+ { internalformat: gl.RGBA, format: gl.RGBA, type: gl.FLOAT, errors: [gl.INVALID_OPERATION] },
+ { internalformat: gl.RGBA, format: gl.RGBA, type: gl.HALF_FLOAT, errors: [gl.INVALID_OPERATION] },
+ { internalformat: gl.LUMINANCE, format: gl.LUMINANCE, type: gl.FLOAT, errors: [gl.INVALID_OPERATION] },
+ { internalformat: gl.LUMINANCE_ALPHA, format: gl.LUMINANCE_ALPHA, type: gl.HALF_FLOAT, errors: [gl.INVALID_OPERATION] },
+ { internalformat: 0x822A /*GL_R16_EXT*/ , format: gl.RED, type: gl.UNSIGNED_SHORT, errors: [gl.INVALID_VALUE, gl.INVALID_OPERATION] },
+ { internalformat: gl.RED, format: gl.RED, type: gl.UNSIGNED_SHORT, errors: [gl.INVALID_VALUE, gl.INVALID_OPERATION] },
+];
+
+tests.forEach(doTexImage);
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-different-data-source.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-different-data-source.html
new file mode 100644
index 0000000000..0343f83786
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-different-data-source.html
@@ -0,0 +1,51 @@
+<!--
+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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="canvas1" width="16" height="16"></canvas>
+<canvas id="canvas2" width="16" height="16"></canvas>
+<canvas id="c" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests texImage2D with different data source');
+
+var wtu = WebGLTestUtils;
+var c = document.getElementById("c");
+var gl = wtu.create3DContext("canvas1", undefined, 2);
+var tex = gl.createTexture();
+
+// Do TexImage2D taking a canvas source first.
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "TexImage2D taking a canvas source should succeed");
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, 16, 16, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, null);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Teximage2D taking a null array buffer should succeed");
+gl.deleteTexture(tex);
+
+// Do TexImage2D taking an array buffer first.
+gl = wtu.create3DContext("canvas2", undefined, 2);
+tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, 16, 16, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, null);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Teximage2D taking a null array buffer should succeed");
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, c);
+wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_ENUM], "TexImage2D taking RGB10_A2UI internalformat and a canvas source should fail");
+gl.deleteTexture(tex);
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-input-validation.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-input-validation.html
new file mode 100644
index 0000000000..ec73e9e1d9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-input-validation.html
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 2;
+</script>
+<script src="../../../js/tests/tex-input-validation.js"></script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-mipmap-levels.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-mipmap-levels.html
new file mode 100644
index 0000000000..adf3d20d17
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-mipmap-levels.html
@@ -0,0 +1,225 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 texture mipmap level conformance 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>
+</head>
+<body>
+<canvas id="example" width="2" height="2" style="width: 2px; height: 2px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+uniform vec4 uMult;
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition * uMult;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D tex;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = texture2D(tex, texCoord);
+}
+</script>
+
+<script id="vshader_texsize" type="x-shader/x-vertex">#version 300 es
+in vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader_texsize_2d" type="x-shader/x-fragment">#version 300 es
+
+precision mediump float;
+uniform sampler2D tex;
+uniform int lod;
+uniform ivec2 texSize;
+out vec4 fragColor;
+void main()
+{
+ fragColor = (textureSize(tex, lod) == texSize ? vec4(255, 0, 0, 255) : vec4(0, 0, 0, 255));
+}
+</script>
+
+
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+(function() {
+ debug("");
+ debug("test mipmap level ranges");
+ var tex = gl.createTexture();
+ wtu.setupUnitQuad(gl, 0, 1);
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+ gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
+
+ var multLoc = gl.getUniformLocation(program, "uMult");
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+
+ // Test that filling partial levels is enough for mipmapping.
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ wtu.fillTexture(gl, tex, 8, 8, [255, 0, 0, 255], 2, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(8x8, level=2) should succeed");
+ wtu.fillTexture(gl, tex, 4, 4, [0, 255, 0, 255], 3, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(4x4, level=3) should succeed");
+ wtu.fillTexture(gl, tex, 2, 2, [0, 0, 255, 255], 4, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(2x2, level=4) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MAX_LEVEL) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MAG_FILTER) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MIN_FILTER) should succeed");
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
+ wtu.checkCanvas(gl, [0, 0, 255, 255], "filling partial levels: should draw with [0, 0, 255, 255]");
+
+ // Test that generateMipmap works with partial levels.
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "generateMipmap with partial levels: should draw with [255, 0, 0, 255]");
+ gl.deleteTexture(tex);
+
+ // Test incompleteless for partial levels.
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ wtu.fillTexture(gl, tex, 8, 8, [255, 0, 0, 255], 2, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(8x8, level=2) should succeed");
+ wtu.fillTexture(gl, tex, 4, 4, [255, 0, 0, 255], 3, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(4x4, level=3) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MAX_LEVEL) should succeed");
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
+ wtu.checkCanvas(gl, [0, 0, 0, 255], "incomplete texture should draw with [0, 0, 0, 255]");
+ gl.deleteTexture(tex);
+
+ // Test base level texture isn't specified.
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ wtu.fillTexture(gl, tex, 8, 8, [255, 0, 0, 255], 2, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(8x8, level=2) should succeed");
+ wtu.fillTexture(gl, tex, 4, 4, [255, 0, 0, 255], 3, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(4x4, level=3) should succeed");
+ wtu.fillTexture(gl, tex, 2, 2, [0, 0, 255, 255], 4, gl.RGBA, gl.UNSIGNED_BYTE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fillTexture(2x2, level=4) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail if base level texture is not specified");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 2);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
+ gl.deleteTexture(tex);
+
+ // Test 3D texture.
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texImage3D( gl.TEXTURE_3D, 0, gl.RGBA, 8, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(8 * 8 * 8 * 4));
+ gl.generateMipmap(gl.TEXTURE_3D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
+ gl.texSubImage3D(gl.TEXTURE_3D, 1, 0, 0, 0, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4 * 4 * 4 * 4));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D should succeed");
+ gl.deleteTexture(tex3d);
+
+ // Test 2D array texture.
+ var tex2dArray = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex2dArray);
+ gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 8, 8, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(8 * 8 * 4 * 4));
+ gl.generateMipmap(gl.TEXTURE_2D_ARRAY);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 1, 0, 0, 0, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4 * 4 * 4 * 4));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D should succeed");
+ gl.deleteTexture(tex2dArray);
+
+ // Test sized internal format should be both color-renderable and texture-filterable
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail for zero-size texture");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(8 * 8 * 4));
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8UI, 8, 8, 0, gl.RGBA_INTEGER, gl.UNSIGNED_BYTE, new Uint8Array(8 * 8 * 4));
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail for non-texture-filterable format");
+ if (gl.getExtension('EXT_color_buffer_float')) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 8, 8, 0, gl.RGBA, gl.FLOAT, new Float32Array(8 * 8 * 4));
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail for float texture");
+ }
+ if (gl.getExtension('EXT_color_buffer_float') && gl.getExtension('OES_texture_float_linear')) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 0, 0, 0, gl.RGBA, gl.FLOAT, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail for zero-size texture");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 8, 8, 0, gl.RGBA, gl.FLOAT, new Float32Array(8 * 8 * 4));
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
+ }
+ gl.deleteTexture(tex);
+
+ // Test textureSize should work correctly with non-zero base level for texStorage2D
+ var program = wtu.setupProgram(
+ gl, ['vshader_texsize', 'fshader_texsize_2d'], ['vPosition'], [0]);
+
+ gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
+ gl.uniform1i(gl.getUniformLocation(program, "lod"), 1);
+ gl.uniform2i(gl.getUniformLocation(program, "texSize"), 7, 4);
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MAG_FILTER) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MIN_FILTER) should succeed");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_BASE_LEVEL) should succeed");
+ gl.texStorage2D(gl.TEXTURE_2D, 4, gl.RGBA8, 31, 17);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage2D should succeed");
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "non-zero base level texStorage2D: should draw with [255, 0, 0, 255]");
+ gl.deleteTexture(tex);
+
+})();
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-new-formats.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-new-formats.html
new file mode 100644
index 0000000000..df10edb4d3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-new-formats.html
@@ -0,0 +1,565 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Conformance test for WebGL2 texture image formats specification</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+
+
+<script>
+"use strict";
+description("This test verifies that texture image specification entry points " +
+ "accept new formats introduced in WebGL2, and accept sized internalformats.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var vao = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTexFormatsTest();
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function runTexFormatsTest()
+{
+ // texFormats is Table 3.2 and Table 3.3 from the OpenGL ES 3.0.4 spec.
+ var texFormats = [
+ {
+ sizedformat: "RGBA8",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGB5_A1",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGBA4",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "SRGB8_ALPHA8",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGBA8_SNORM",
+ unsizedformat: "RGBA",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "RGBA4",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_SHORT_4_4_4_4",
+ },
+ {
+ sizedformat: "RGB5_A1",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_SHORT_5_5_5_1",
+ },
+ {
+ sizedformat: "RGB10_A2",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_INT_2_10_10_10_REV",
+ },
+ {
+ sizedformat: "RGB5_A1",
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_INT_2_10_10_10_REV",
+ },
+ {
+ sizedformat: "RGBA16F",
+ unsizedformat: "RGBA",
+ type: "HALF_FLOAT",
+ },
+ {
+ sizedformat: "RGBA32F",
+ unsizedformat: "RGBA",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RGBA16F",
+ unsizedformat: "RGBA",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RGBA8UI",
+ unsizedformat: "RGBA_INTEGER",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGBA8I",
+ unsizedformat: "RGBA_INTEGER",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "RGBA16UI",
+ unsizedformat: "RGBA_INTEGER",
+ type: "UNSIGNED_SHORT",
+ },
+ {
+ sizedformat: "RGBA16I",
+ unsizedformat: "RGBA_INTEGER",
+ type: "SHORT",
+ },
+ {
+ sizedformat: "RGBA32UI",
+ unsizedformat: "RGBA_INTEGER",
+ type: "UNSIGNED_INT",
+ },
+ {
+ sizedformat: "RGBA32I",
+ unsizedformat: "RGBA_INTEGER",
+ type: "INT",
+ },
+ {
+ sizedformat: "RGB10_A2UI",
+ unsizedformat: "RGBA_INTEGER",
+ type: "UNSIGNED_INT_2_10_10_10_REV",
+ },
+ {
+ sizedformat: "RGB8",
+ unsizedformat: "RGB",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGB565",
+ unsizedformat: "RGB",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "SRGB8",
+ unsizedformat: "RGB",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGB8_SNORM",
+ unsizedformat: "RGB",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "RGB565",
+ unsizedformat: "RGB",
+ type: "UNSIGNED_SHORT_5_6_5",
+ },
+ {
+ sizedformat: "R11F_G11F_B10F",
+ unsizedformat: "RGB",
+ type: "UNSIGNED_INT_10F_11F_11F_REV",
+ },
+ {
+ sizedformat: "RGB9_E5",
+ unsizedformat: "RGB",
+ type: "UNSIGNED_INT_5_9_9_9_REV",
+ },
+ {
+ sizedformat: "RGB16F",
+ unsizedformat: "RGB",
+ type: "HALF_FLOAT",
+ },
+ {
+ sizedformat: "R11F_G11F_B10F",
+ unsizedformat: "RGB",
+ type: "HALF_FLOAT",
+ },
+ {
+ sizedformat: "RGB9_E5",
+ unsizedformat: "RGB",
+ type: "HALF_FLOAT",
+ },
+ {
+ sizedformat: "RGB32F",
+ unsizedformat: "RGB",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RGB16F",
+ unsizedformat: "RGB",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "R11F_G11F_B10F",
+ unsizedformat: "RGB",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RGB9_E5",
+ unsizedformat: "RGB",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RGB8UI",
+ unsizedformat: "RGB_INTEGER",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RGB8I",
+ unsizedformat: "RGB_INTEGER",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "RGB16UI",
+ unsizedformat: "RGB_INTEGER",
+ type: "UNSIGNED_SHORT",
+ },
+ {
+ sizedformat: "RGB16I",
+ unsizedformat: "RGB_INTEGER",
+ type: "SHORT",
+ },
+ {
+ sizedformat: "RGB32UI",
+ unsizedformat: "RGB_INTEGER",
+ type: "UNSIGNED_INT",
+ },
+ {
+ sizedformat: "RGB32I",
+ unsizedformat: "RGB_INTEGER",
+ type: "INT",
+ },
+ {
+ sizedformat: "RG8",
+ unsizedformat: "RG",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RG8_SNORM",
+ unsizedformat: "RG",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "RG16F",
+ unsizedformat: "RG",
+ type: "HALF_FLOAT",
+ },
+ {
+ sizedformat: "RG32F",
+ unsizedformat: "RG",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RG16F",
+ unsizedformat: "RG",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "RG8UI",
+ unsizedformat: "RG_INTEGER",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "RG8I",
+ unsizedformat: "RG_INTEGER",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "RG16UI",
+ unsizedformat: "RG_INTEGER",
+ type: "UNSIGNED_SHORT",
+ },
+ {
+ sizedformat: "RG16I",
+ unsizedformat: "RG_INTEGER",
+ type: "SHORT",
+ },
+ {
+ sizedformat: "RG32UI",
+ unsizedformat: "RG_INTEGER",
+ type: "UNSIGNED_INT",
+ },
+ {
+ sizedformat: "RG32I",
+ unsizedformat: "RG_INTEGER",
+ type: "INT",
+ },
+ {
+ sizedformat: "R8",
+ unsizedformat: "RED",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "R8_SNORM",
+ unsizedformat: "RED",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "R16F",
+ unsizedformat: "RED",
+ type: "HALF_FLOAT",
+ },
+ {
+ sizedformat: "R32F",
+ unsizedformat: "RED",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "R16F",
+ unsizedformat: "RED",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "R8UI",
+ unsizedformat: "RED_INTEGER",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: "R8I",
+ unsizedformat: "RED_INTEGER",
+ type: "BYTE",
+ },
+ {
+ sizedformat: "R16UI",
+ unsizedformat: "RED_INTEGER",
+ type: "UNSIGNED_SHORT",
+ },
+ {
+ sizedformat: "R16I",
+ unsizedformat: "RED_INTEGER",
+ type: "SHORT",
+ },
+ {
+ sizedformat: "R32UI",
+ unsizedformat: "RED_INTEGER",
+ type: "UNSIGNED_INT",
+ },
+ {
+ sizedformat: "R32I",
+ unsizedformat: "RED_INTEGER",
+ type: "INT",
+ },
+ {
+ sizedformat: "DEPTH_COMPONENT16",
+ unsizedformat: "DEPTH_COMPONENT",
+ type: "UNSIGNED_SHORT",
+ },
+ {
+ sizedformat: "DEPTH_COMPONENT24",
+ unsizedformat: "DEPTH_COMPONENT",
+ type: "UNSIGNED_INT",
+ },
+ {
+ sizedformat: "DEPTH_COMPONENT16",
+ unsizedformat: "DEPTH_COMPONENT",
+ type: "UNSIGNED_INT",
+ },
+ {
+ sizedformat: "DEPTH_COMPONENT32F",
+ unsizedformat: "DEPTH_COMPONENT",
+ type: "FLOAT",
+ },
+ {
+ sizedformat: "DEPTH24_STENCIL8",
+ unsizedformat: "DEPTH_STENCIL",
+ type: "UNSIGNED_INT_24_8",
+ },
+ // No good typed array type for this format, just allow this format when pixel is null.
+ {
+ sizedformat: "DEPTH32F_STENCIL8",
+ unsizedformat: "DEPTH_STENCIL",
+ type: "FLOAT_32_UNSIGNED_INT_24_8_REV",
+ },
+ // internalFormat of texImage2D may be unsized format according Table 3.3 in OpenGL ES 3.0.4 spec.
+ {
+ sizedformat: undefined,
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_SHORT_4_4_4_4",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "RGBA",
+ type: "UNSIGNED_SHORT_5_5_5_1",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "RGB",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "RGB",
+ type: "UNSIGNED_SHORT_5_6_5",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "LUMINANCE_ALPHA",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "LUMINANCE",
+ type: "UNSIGNED_BYTE",
+ },
+ {
+ sizedformat: undefined,
+ unsizedformat: "ALPHA",
+ type: "UNSIGNED_BYTE",
+ },
+ ];
+
+ texFormats.forEach(function(texformat){
+ debug("");
+ debug("Testing sized format " + texformat.sizedformat
+ + ", unsized format " + texformat.unsizedformat
+ + ", type " + texformat.type);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ var sizedformat = gl[texformat.sizedformat];
+ var unsizedformat = gl[texformat.unsizedformat];
+ var type = gl[texformat.type];
+
+ // prepare some good data to feed texImage2D and friends for this type
+ var data;
+ switch(type) {
+ case gl.UNSIGNED_BYTE:
+ data = new Uint8Array(4);
+ break;
+ case gl.BYTE:
+ data = new Int8Array(4);
+ break;
+ case gl.UNSIGNED_SHORT:
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ case gl.UNSIGNED_SHORT_5_6_5:
+ case gl.HALF_FLOAT:
+ data = new Uint16Array(4);
+ break;
+ case gl.SHORT:
+ data = new Int16Array(4);
+ break;
+ case gl.UNSIGNED_INT:
+ case gl.UNSIGNED_INT_5_9_9_9_REV:
+ case gl.UNSIGNED_INT_10F_11F_11F_REV:
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ case gl.UNSIGNED_INT_24_8:
+ data = new Uint32Array(4);
+ break;
+ case gl.INT:
+ data = new Int32Array(4);
+ break;
+ case gl.FLOAT:
+ data = new Float32Array(4);
+ break;
+ case gl.FLOAT_32_UNSIGNED_INT_24_8_REV:
+ data = null;
+ }
+
+ // prepare some bad data that doesn't fit this type
+ var baddata = (data instanceof Float32Array)
+ ? new Uint8Array(4)
+ : new Float32Array(4);
+
+ // test texImage2D with unsized internalformat
+ if (!sizedformat) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, unsizedformat, 1, 1, 0, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D should succeed with unsized internalformat");
+ gl.texImage2D(gl.TEXTURE_2D, 0, unsizedformat, 1, 1, 0, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D should fail with unsized internalformat and data of wrong type");
+ } else {
+ // test texImage2D with sized internalformat
+ gl.texImage2D(gl.TEXTURE_2D, 0, sizedformat, 1, 1, 0, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D should succeed with sized internalformat");
+ gl.texImage2D(gl.TEXTURE_2D, 0, sizedformat, 1, 1, 0, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D should fail with sized internalformat and data of wrong type");
+ }
+
+ // test texSubImage2D
+ if (gl.FLOAT_32_UNSIGNED_INT_24_8_REV != type) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D should fail with data of wrong type");
+ }
+
+ // test texStorage2D
+ if (sizedformat) {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, sizedformat, 1, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage2D should succeed");
+ if (gl.FLOAT_32_UNSIGNED_INT_24_8_REV != type) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable-format texture");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D should fail on immutable-format texture with data of wrong type");
+ }
+ }
+
+ // Test a 3D texture.
+ // Formats containing a depth component can't be used for 3D textures.
+ var isdepthformat =
+ unsizedformat == gl.DEPTH_COMPONENT ||
+ unsizedformat == gl.DEPTH_STENCIL;
+ if (!isdepthformat) {
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+
+ // test texImage3D with unsized internalformat
+ if (!sizedformat) {
+ gl.texImage3D(gl.TEXTURE_3D, 0, unsizedformat, 1, 1, 1, 0, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed with unsized internalformat");
+ gl.texImage3D(gl.TEXTURE_3D, 0, unsizedformat, 1, 1, 1, 0, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D should fail with unsized internalformat and data of wrong type");
+ } else {
+ // test texImage3D with sized internalformat
+ gl.texImage3D(gl.TEXTURE_3D, 0, sizedformat, 1, 1, 1, 0, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D should succeed with sized internalformat");
+ gl.texImage3D(gl.TEXTURE_3D, 0, sizedformat, 1, 1, 1, 0, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D should fail with sized internalformat and data of wrong type");
+ }
+
+ // test texSubImage3D
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D should succeed");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D should fail with data of wrong type");
+
+ if (sizedformat) {
+ gl.texStorage3D(gl.TEXTURE_3D, 1, sizedformat, 1, 1, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage3D should succeed");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, unsizedformat, type, data);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D should succeed on immutable-format texture");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, unsizedformat, type, baddata);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D should fail on immutable-format texture with data of wrong type");
+ }
+ }
+ });
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-srgb-mipmap.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-srgb-mipmap.html
new file mode 100644
index 0000000000..9764987d8d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-srgb-mipmap.html
@@ -0,0 +1,220 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL texture mipmap conformance 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>
+</head>
+<body>
+<canvas id="example" width="4" height="4" style="width: 16px; height: 16px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D tex;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = texture2D(tex, texCoord);
+}
+</script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas, undefined, 2);
+
+description("Test srgb emulation for generateMipmap.");
+function generateMipmap()
+{
+ debug("Generate mipmaps for sRGB texture");
+
+ wtu.setupUnitQuad(gl, 0, 1);
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var colors = {
+ blank: [0, 0, 0, 0],
+ srgba: [0, 63, 127, 255],
+ };
+
+ var texLoc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(texLoc, 0);
+
+ var width = 128;
+ var height = 128;
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+
+ var srgbTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, srgbTex);
+ // Set full texture as srgba color first.
+ wtu.fillTexture(gl, srgbTex, width, height, colors['srgba'], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.SRGB8_ALPHA8);
+ // Set up-left region of the texture as red color.
+ // In order to make sure bi-linear interpolation operates on different colors, red region
+ // is 1 pixel smaller than a quarter of the full texture on each side.
+ var redWidth = width / 2 - 1;
+ var redHeight = height / 2 - 1;
+ var buf = new Uint8Array(redWidth * redHeight * 4);
+ for (var i = 0; i < redWidth * redHeight; i++) {
+ buf[4 * i + 0] = 255;
+ buf[4 * i + 1] = 0;
+ buf[4 * i + 2] = 0;
+ buf[4 * i + 3] = 255;
+ }
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, redWidth, redHeight, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
+
+ // Decode the srgba texture to a linear texture which will be used as reference.
+ var linearTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, linearTex);
+ wtu.fillTexture(gl, linearTex, width, height, wtu.sRGBToLinear(colors['srgba']), 0, gl.RGBA, gl.UNSIGNED_BYTE);
+ // Set up-left region of the texture as red color.
+ // In order to make sure bi-linear interpolation operates on different colors, red region
+ // is 1 pixel smaller than a quarter of the full texture on each side.
+ for (var i = 0; i < redWidth * redHeight; i++) {
+ buf[4 * i + 0] = 255;
+ buf[4 * i + 1] = 0;
+ buf[4 * i + 2] = 0;
+ buf[4 * i + 3] = 255;
+ }
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, redWidth, redHeight, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
+
+ // Change canvas to a small size.
+ width = 64;
+ height = 64;
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+
+ // Draw with srgb texture and linear texture respectively.
+ gl.bindTexture(gl.TEXTURE_2D, srgbTex);
+ wtu.clearAndDrawUnitQuad(gl);
+ var result = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, result);
+ gl.bindTexture(gl.TEXTURE_2D, linearTex);
+ wtu.clearAndDrawUnitQuad(gl);
+ var reference = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, reference);
+
+ gl.deleteTexture(srgbTex);
+ gl.deleteTexture(linearTex);
+
+ var tolerance = 7;
+ var diff = new Uint8Array(width * height * 4);
+ var failed = wtu.comparePixels(result, reference, tolerance, diff);
+ if (failed) {
+ testFailed("Generate wrong mipmaps for sRGB texture.");
+ wtu.displayImageDiff(result, reference, diff, width, height);
+ } else {
+ testPassed("Generate correct mipmaps for sRGB texture.");
+ }
+}
+
+function generateMipmap_immutableTexture()
+{
+ debug("Generate mipmaps for immutable texture.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, Math.log2(canvas.width), gl.SRGB8_ALPHA8, canvas.width, canvas.height);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "GenerateMipmap should succeed.");
+
+ gl.deleteTexture(tex);
+}
+
+function generateMipmap_widthHeightNotEqual()
+{
+ debug("Generate mipmaps when width and height are not equal.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, 64, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "GenerateMipmap should succeed.");
+
+ gl.deleteTexture(tex);
+}
+
+function generateMipmap_maxLevelLessThanFullMipmapLevel()
+{
+ debug("Generate mipmaps when maxLevel is less than full mipmap level.");
+
+ wtu.setupUnitQuad(gl, 0, 1);
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
+
+ var colors = [0, 63, 127, 255];
+
+ var texLoc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(texLoc, 0);
+
+ var width = 16;
+ var height = 16;
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+
+ var srgbTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, srgbTex);
+ wtu.fillTexture(gl, srgbTex, width, height, colors, 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.SRGB8_ALPHA8);
+
+ // Set max level, check if the max level mipmap is generated.
+ var max_level = 3;
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, max_level);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
+
+ width >>= max_level;
+ height >>= max_level;
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+
+ gl.bindTexture(gl.TEXTURE_2D, srgbTex);
+ wtu.clearAndDrawUnitQuad(gl);
+
+ var reference = wtu.sRGBToLinear(colors);
+ var msg;
+ wtu.checkCanvasRect(gl, 0, 0, width, height, reference, msg, [1,1,1,1]);
+
+ gl.deleteTexture(srgbTex);
+}
+
+generateMipmap();
+generateMipmap_immutableTexture();
+generateMipmap_widthHeightNotEqual();
+generateMipmap_maxLevelLessThanFullMipmapLevel();
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html
new file mode 100644
index 0000000000..34bff4d3a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html
@@ -0,0 +1,290 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>texStorage2D conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+
+
+<script>
+"use strict";
+description("This test verifies the functionality of texStorage2D.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var vao = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTexStorage2DTest();
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function runTexStorage2DTest()
+{
+ var texStorage2DTestCases = [
+ {
+ target: gl.TEXTURE_2D,
+ mipmap: false,
+ sizedformat: gl.RGBA8,
+ unsizedformat: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ alpha: true,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_2D,
+ mipmap: true,
+ sizedformat: gl.R11F_G11F_B10F,
+ unsizedformat: gl.RGB,
+ type: gl.UNSIGNED_INT_10F_11F_11F_REV,
+ alpha: false,
+ // Red is unsigned floating point with 5 exponent bits followed by 6 mantissa bits.
+ // The effective value is 2^(exponent - 15) * (1 + mantissa / 64)
+ // See OpenGL ES 3.0.3 spec, section 2.1.3
+ // Here we want to encode the value 1.0, which we achieve with a zero mantissa
+ // and an exponent of 15.
+ redpixel: new Uint32Array([15<<6]),
+ },
+ {
+ target: gl.TEXTURE_2D,
+ mipmap: true,
+ sizedformat: gl.RGBA32F,
+ unsizedformat: gl.RGBA,
+ type: gl.FLOAT,
+ alpha: true,
+ redpixel: new Float32Array([1, 0, 0, 0]),
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: true,
+ sizedformat: gl.RGBA8,
+ unsizedformat: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ alpha: true,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: false,
+ sizedformat: gl.RGB8,
+ unsizedformat: gl.RGB,
+ type: gl.UNSIGNED_BYTE,
+ alpha: false,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: true,
+ sizedformat: gl.RGB10_A2UI,
+ unsizedformat: gl.UNSIGNED_INT_2_10_10_10_REV, // type enum, bad as format
+ },
+ {
+ target: gl.TEXTURE_CUBE_MAP,
+ mipmap: false,
+ sizedformat: gl.R11F_G11F_B10F,
+ unsizedformat: gl.RGB,
+ }
+ ];
+
+ texStorage2DTestCases.forEach(function(testcase){
+ var target = testcase.target;
+ var imageTargets;
+
+ if (target == gl.TEXTURE_2D) {
+ imageTargets = [ gl.TEXTURE_2D ];
+ } else {
+ imageTargets = [ 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 ];
+ }
+
+ var tex = gl.createTexture();
+ gl.bindTexture(target, tex);
+ var texsize = 4;
+ var levels = testcase.mipmap
+ ? Math.floor(Math.log(texsize) / Math.log(2)) + 1
+ : 1;
+
+ debug("");
+ debug("Testing texStorage2D with target " + enumToString(target) + ", " +
+ (testcase.mipmap ? "mipmap" : "no mipmap") + ", " +
+ "internalformat: " + enumToString(testcase.sizedformat));
+
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ 0, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero width");
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero height");
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, -texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for negative height");
+ gl.texStorage2D(target, 0, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage2D should fail for zero levels");
+ gl.texStorage2D(target,
+ Math.ceil(Math.log(texsize) / Math.log(2)) + 2,
+ testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage2D should fail for too many levels");
+ gl.texStorage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, levels, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage2D should fail for bad target TEXTURE_CUBE_MAP_NEGATIVE_X");
+
+ gl.bindTexture(target, null);
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage2D should fail when no texture is bound");
+ gl.bindTexture(target, tex);
+
+ // texStorage2D should only accept sized internalformats
+ gl.texStorage2D(target, levels, testcase.unsizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage2D should fail for bad internalformat " + enumToString(testcase.unsizedformat));
+
+ // OK, now let's finally do the successfull texStorage2D call
+ gl.texStorage2D(target, levels, testcase.sizedformat,
+ texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage2D should succeed with a good sized internalformat");
+
+ // check TEXTURE_IMMUTABLE_FORMAT
+ var immutable = gl.getTexParameter(target, gl.TEXTURE_IMMUTABLE_FORMAT);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getTexParameter should succeed with TEXTURE_IMMUTABLE_FORMAT");
+ assertMsg(immutable != 0, "getTexParameter with TEXTURE_IMMUTABLE_FORMAT should not return 0");
+
+ // check operations disallowed on immutable texture
+ gl.texImage2D(imageTargets[0], 0, gl.RGBA, texsize, texsize, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D should fail on immutable texture");
+ var s3tc = gl.getExtension("WEBGL_compressed_texture_s3tc");
+ // FIXME - should eventually use a compressed format that's core in WebGL2, but
+ // I wanted something that I can run in Firefox today, which doesn't support the new formats yet.
+ if (s3tc) {
+ gl.compressedTexImage2D(imageTargets[0], 0, s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ texsize, texsize, 0,
+ new Uint8Array(texsize * texsize));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "compressedTexImage2D should fail on immutable texture");
+ }
+ gl.copyTexImage2D(imageTargets[0], 0, gl.RGBA, 0, 0, texsize, texsize, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "copyTexImage2D should fail on immutable texture");
+
+ if ('redpixel' in testcase) {
+ // At this point, the texture images have only been defined by
+ // texStorage2D, which per spec should be equivalent to having
+ // defined texture images with null data, which should sample as RGBA 0,0,0,0.
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER,
+ testcase.mipmap ? gl.NEAREST_MIPMAP_NEAREST : gl.NEAREST);
+ if (testcase.type == gl.FLOAT) {
+ gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ // Now upload some red texture data
+ var s = texsize;
+ var pixels;
+ if (testcase.redpixel instanceof Uint8Array) {
+ pixels = new Uint8Array(texsize * texsize * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Uint16Array) {
+ pixels = new Uint16Array(texsize * texsize * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Uint32Array) {
+ pixels = new Uint32Array(texsize * texsize * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Float32Array) {
+ pixels = new Float32Array(texsize * texsize * testcase.redpixel.length);
+ }
+ for (var i = 0; i < texsize * texsize; i++) {
+ for (var j = 0; j < testcase.redpixel.length; j++) {
+ pixels[i * testcase.redpixel.length + j] = testcase.redpixel[j];
+ }
+ }
+
+ if (target == gl.TEXTURE_2D) {
+ wtu.setupTexturedQuad(gl);
+ } else if (target == gl.TEXTURE_CUBE_MAP) {
+ wtu.setupTexturedQuadWithCubeMap(gl);
+ }
+
+ wtu.clearAndDrawUnitQuad(gl);
+ var alpha = testcase.alpha ? 0 : 255;
+ wtu.checkCanvas(gl, [0, 0, 0, alpha], "texture should sample as uninitialized texture after texStorage2D");
+
+ if (target == gl.TEXTURE_2D) {
+ for (var l = 0; l < levels; l++) {
+ gl.texSubImage2D(gl.TEXTURE_2D,
+ l, 0, 0,
+ s, s,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable texture as long as the format is compatible");
+ s /= 2;
+ }
+ } else if (target == gl.TEXTURE_CUBE_MAP) {
+ for (var l = 0; l < levels; l++) {
+ for (var f = 0; f < 6; f++) {
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f,
+ l, 0, 0,
+ s, s,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed on immutable texture as long as the format is compatible");
+ }
+ s /= 2;
+ }
+ }
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [255, 0, 0, alpha], "texture should sample as red after uploading red pixels with texSubImage2D");
+ }
+ });
+
+ debug("");
+ debug("Test non-square images:");
+ const levels = 4;
+ const maxSize = 1 << (levels-1);
+
+ function expectOk(x,y) {
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, levels, gl.RGBA8, x, y);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "texStorage2D should succeed with size [" + ([x,y].join(', ')) + "].");
+ gl.deleteTexture(tex);
+ }
+ expectOk(maxSize, maxSize);
+ expectOk(maxSize, 1);
+ expectOk( 1, maxSize);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-and-subimage-3d.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-and-subimage-3d.html
new file mode 100644
index 0000000000..c81fcffb4e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-and-subimage-3d.html
@@ -0,0 +1,242 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>texStorage3D and texSubImage3D conformance 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+
+
+<script>
+"use strict";
+description("This test verifies the functionality of texStorage3D and texSubImage3D.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var vao = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runTexStorageAndSubImage3DTest();
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function runTexStorageAndSubImage3DTest()
+{
+ var texStorage3DTestCases = [
+ {
+ target: gl.TEXTURE_3D,
+ mipmap: false,
+ sizedformat: gl.RGBA8,
+ unsizedformat: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ alpha: true,
+ redpixel: new Uint8Array([0xff, 0x00, 0x00, 0x00]),
+ },
+ {
+ target: gl.TEXTURE_3D,
+ mipmap: true,
+ sizedformat: gl.R11F_G11F_B10F,
+ unsizedformat: gl.RGB,
+ type: gl.UNSIGNED_INT_10F_11F_11F_REV,
+ alpha: false,
+ // Red is unsigned floating point with 5 exponent bits followed by 6 mantissa bits.
+ // The effective value is 2^(exponent - 15) * (1 + mantissa / 64)
+ // See OpenGL ES 3.0.3 spec, section 2.1.3
+ // Here we want to encode the value 1.0, which we achieve with a zero mantissa
+ // and an exponent of 15.
+ redpixel: new Uint32Array([15<<6]),
+ },
+ {
+ target: gl.TEXTURE_3D,
+ mipmap: true,
+ sizedformat: gl.RGBA32F,
+ unsizedformat: gl.RGBA,
+ type: gl.FLOAT,
+ alpha: true,
+ redpixel: new Float32Array([1, 0, 0, 0]),
+ },
+ ];
+
+ texStorage3DTestCases.forEach(function(testcase){
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex);
+ var texsize = 4;
+ var levels = testcase.mipmap
+ ? Math.floor(Math.log(texsize) / Math.log(2)) + 1
+ : 1;
+
+ debug("");
+ debug("Testing texStorage3D with " +
+ (testcase.mipmap ? "mipmap" : "no mipmap") + ", " +
+ "internalformat: " + enumToString(testcase.sizedformat));
+
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ 0, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero width");
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ texsize, 0, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero height");
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ texsize, texsize, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero depth");
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ texsize, -texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for negative height");
+ gl.texStorage3D(gl.TEXTURE_3D, 0, testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texStorage3D should fail for zero levels");
+ if (testcase.mipmap) {
+ gl.texStorage3D(gl.TEXTURE_3D,
+ levels + 1,
+ testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage3D should fail for too many levels");
+ }
+ gl.texStorage3D(gl.TEXTURE_2D,
+ levels,
+ testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage3D should fail for target TEXTURE_2D");
+ gl.texStorage3D(gl.TEXTURE_CUBE_MAP,
+ levels,
+ testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage3D should fail for target TEXTURE_CUBE_MAP");
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage3D should fail when no texture is bound");
+ gl.bindTexture(gl.TEXTURE_3D, tex);
+
+ // texStorage3D should only accept sized internalformats
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.unsizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "texStorage3D should fail for bad internalformat " + enumToString(testcase.unsizedformat));
+
+ var pixels;
+ var number_of_pixels = texsize * texsize * texsize;
+ if (testcase.redpixel instanceof Uint8Array) {
+ pixels = new Uint8Array(number_of_pixels * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Uint16Array) {
+ pixels = new Uint16Array(number_of_pixels * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Uint32Array) {
+ pixels = new Uint32Array(number_of_pixels * testcase.redpixel.length);
+ } else if (testcase.redpixel instanceof Float32Array) {
+ pixels = new Float32Array(number_of_pixels * testcase.redpixel.length);
+ }
+ for (var i = 0; i < number_of_pixels; i++) {
+ for (var j = 0; j < testcase.redpixel.length; j++) {
+ pixels[i * testcase.redpixel.length + j] = testcase.redpixel[j];
+ }
+ }
+
+ gl.texSubImage3D(gl.TEXTURE_2D,
+ 0, 0, 0, 0,
+ texsize, texsize, texsize,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
+ "texSubImage3D should generate INVALID_ENUM if passed TEXTURE_2D target");
+ gl.texSubImage3D(gl.TEXTURE_3D,
+ 0, 0, 0, 0,
+ texsize, texsize, texsize,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "texSubImage3D should fail if texStorage3D has not succeeded");
+
+ // OK, now let's finally do the successfull texStorage3D call
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage3D should succeed with a good sized internalformat");
+
+ // Subsequent texStorage3D calls should fail, even identical ones.
+ gl.texStorage3D(gl.TEXTURE_3D, levels, testcase.sizedformat,
+ texsize, texsize, texsize);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texStorage3D should fail on immutable-format texture");
+
+ var s = texsize;
+ for (var l = 0; l < levels; l++) {
+ gl.texSubImage3D(gl.TEXTURE_3D,
+ l, 0, 0, 0,
+ s, s, s,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ s /= 2;
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D should succeed on immutable texture as long as the format is compatible");
+ }
+ gl.texSubImage3D(gl.TEXTURE_3D,
+ levels, 0, 0, 0,
+ texsize, texsize, texsize,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D should fail for too-high level");
+ gl.texSubImage3D(gl.TEXTURE_3D,
+ 0, 1, 0, 0,
+ texsize, texsize, texsize,
+ testcase.unsizedformat, testcase.type,
+ pixels);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texSubImage3D should fail for dimension out of range");
+ });
+
+ debug("");
+ debug("Test non-square images:");
+ const levels = 4;
+ const maxSize = 1 << (levels-1);
+
+ function expectOk(target, x,y,z, err) {
+ debug("(target=" + target + ", size=[" + ([x,y,z].join(', ')) + "])");
+ const tex = gl.createTexture();
+ gl.bindTexture(gl[target], tex);
+ gl.texStorage3D(gl[target], levels+1, gl.RGBA8, x, y, z);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "levels=levels+1");
+
+ gl.texStorage3D(gl[target], levels, gl.RGBA8, x, y, z);
+ wtu.glErrorShouldBe(gl, gl[err], "levels=levels");
+ gl.deleteTexture(tex);
+ }
+ expectOk("TEXTURE_3D", maxSize, maxSize, maxSize, "NO_ERROR");
+ expectOk("TEXTURE_3D", maxSize, maxSize, 1, "NO_ERROR");
+ expectOk("TEXTURE_3D", maxSize, 1, maxSize, "NO_ERROR");
+ expectOk("TEXTURE_3D", maxSize, 1, 1, "NO_ERROR");
+ expectOk("TEXTURE_3D", 1, maxSize, maxSize, "NO_ERROR");
+ expectOk("TEXTURE_3D", 1, maxSize, 1, "NO_ERROR");
+ expectOk("TEXTURE_3D", 1, 1, maxSize, "NO_ERROR");
+
+ expectOk("TEXTURE_2D_ARRAY", maxSize, maxSize, 10, "NO_ERROR");
+ expectOk("TEXTURE_2D_ARRAY", maxSize, 1, 10, "NO_ERROR");
+ expectOk("TEXTURE_2D_ARRAY", 1, maxSize, 10, "NO_ERROR");
+ expectOk("TEXTURE_2D_ARRAY", 1, 1, 10, "INVALID_OPERATION");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-compressed-formats.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-compressed-formats.html
new file mode 100644
index 0000000000..e154631ead
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-compressed-formats.html
@@ -0,0 +1,136 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Conformance test for WebGL2 texStorage2D and texStorage3D with compressed format</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" width="64" height="64"> </canvas>
+<div id="console"></div>
+
+
+<script>
+"use strict";
+description("This test verifies that texStorage2D and texStorage3D " +
+ "accept compressed internalformats.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+// Either of these extensions should be available on all WebGL 2.0 contexts
+const WEBGL_compressed_texture_etc = gl.getExtension("WEBGL_compressed_texture_etc");
+const WEBGL_compressed_texture_s3tc = gl.getExtension("WEBGL_compressed_texture_s3tc");
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ if (WEBGL_compressed_texture_etc) {
+ debug("Testing WEBGL_compressed_texture_etc formats");
+
+ // These compressed formats are in Table 3.19 from the OpenGL ES 3.0.4 spec.
+ runTexCompressedFormatsTest([
+ WEBGL_compressed_texture_etc.COMPRESSED_R11_EAC,
+ WEBGL_compressed_texture_etc.COMPRESSED_SIGNED_R11_EAC,
+ WEBGL_compressed_texture_etc.COMPRESSED_RG11_EAC,
+ WEBGL_compressed_texture_etc.COMPRESSED_SIGNED_RG11_EAC,
+ WEBGL_compressed_texture_etc.COMPRESSED_RGB8_ETC2,
+ WEBGL_compressed_texture_etc.COMPRESSED_SRGB8_ETC2,
+ WEBGL_compressed_texture_etc.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ WEBGL_compressed_texture_etc.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ WEBGL_compressed_texture_etc.COMPRESSED_RGBA8_ETC2_EAC,
+ WEBGL_compressed_texture_etc.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+ ]);
+ } else {
+ testPassed("No WEBGL_compressed_texture_etc support -- this is legal");
+ }
+
+ if (WEBGL_compressed_texture_s3tc) {
+ debug("Testing WEBGL_compressed_texture_s3tc formats");
+
+ runTexCompressedFormatsTest([
+ WEBGL_compressed_texture_s3tc.COMPRESSED_RGB_S3TC_DXT1_EXT,
+ WEBGL_compressed_texture_s3tc.COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ WEBGL_compressed_texture_s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ WEBGL_compressed_texture_s3tc.COMPRESSED_RGBA_S3TC_DXT5_EXT,
+ ]);
+ } else {
+ testPassed("No WEBGL_compressed_texture_s3tc support -- this is legal");
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function enumToString(value) {
+ return wtu.glEnumToString(gl, value);
+}
+
+function runTexCompressedFormatsTest(texCompressedFormats)
+{
+ wtu.setupUnitQuad(gl);
+
+ gl.useProgram(wtu.setupSimpleTextureProgramESSL300(gl, undefined, undefined,
+ `#version 300 es
+ precision mediump float;
+ uniform mediump sampler2DArray tex;
+ in vec2 texCoord;
+ out vec4 out_color;
+ void main() {
+ out_color = texture(tex, vec3(texCoord, 0));
+ }`
+ ));
+
+ texCompressedFormats.forEach(function(internalformat){
+ // Test a 2D texture.
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, internalformat, 4, 4);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "texStorage2D should succeed for " + enumToString(internalformat));
+ gl.deleteTexture(tex);
+
+ // GLES 3.0.4 p147: + EXT_texture_compression_s3tc:
+ // If internalformat is an ETC2/EAC/DXT1/DXT3/DXT5
+ // format, CompressedTexImage3D will generate an INVALID_OPERATION error if
+ // target is not TEXTURE_2D_ARRAY.
+
+ // Test the 3D texture targets.
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texStorage3D(gl.TEXTURE_3D, 1, internalformat, 4, 4, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "texStorage3D(TEXTURE_3D) should fail for " + enumToString(internalformat));
+ gl.deleteTexture(tex3d);
+
+ var tex2dArr = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex2dArr);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, internalformat, 4, 4, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "texStorage3D(TEXTURE_2D_ARRAY) should succeed for " + enumToString(internalformat));
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing unit quad from empty texture");
+ gl.deleteTexture(tex2dArr);
+ });
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-canvas-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-canvas-bug.html
new file mode 100644
index 0000000000..2c2d021d5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-canvas-bug.html
@@ -0,0 +1,56 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test bug of TexSubImage3D with canvas</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="2" height="2" style="width: 2px; height: 2px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description(document.title);
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=859400'>Chromium Issue 859400</a>");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+function runTest() {
+ var ctx = document.createElement('canvas').getContext("2d");
+ var maxTexSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
+ var width = Math.ceil(Math.sqrt(maxTexSize));
+ var height = width;
+ var depth = width + 1;
+ ctx.canvas.width = width;
+ // Set canvas height to a value larger than MAX_TEXTURE_SIZE.
+ // This triggers a validation bug in Chrome.
+ ctx.canvas.height = height * depth;
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from TexStorage3D.");
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, depth,
+ gl.RGBA, gl.UNSIGNED_BYTE, ctx.canvas);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from TexSubImage3D.");
+}
+
+runTest();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html
new file mode 100644
index 0000000000..181a4819fe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html
@@ -0,0 +1,90 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test bug of TexSubImage3D with pixel buffer</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="example" width="2" height="2" style="width: 2px; height: 2px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader_texsize" type="x-shader/x-vertex">#version 300 es
+in vec4 vPosition;
+void main()
+{
+ gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader_texsize_3d" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform highp sampler3D tex;
+uniform int lod;
+uniform ivec3 texSize;
+out vec4 fragColor;
+void main()
+{
+ fragColor = (textureSize(tex, lod) == texSize ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 0.0, 0.0, 1.0));
+}
+</script>
+
+
+<script>
+"use strict";
+description(document.title);
+debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=666384'>Chromium Issue 666384</a>");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+function runTest() {
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ var program = wtu.setupProgram(
+ gl, ['vshader_texsize', 'fshader_texsize_3d'], ['vPosition'], [0]);
+
+ var width = 32;
+ var height = 16;
+ var depth = 8;
+ gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
+ gl.uniform1i(gl.getUniformLocation(program, "lod"), 2);
+ gl.uniform3i(gl.getUniformLocation(program, "texSize"), 8, 4, 2);
+ var tex3d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex3d);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MIN_FILTER) should succeed");
+ gl.texStorage3D(gl.TEXTURE_3D, 4, gl.RGBA8, width, height, depth);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage3D should succeed");
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, new Uint8Array(width * height * depth * 4), gl.DYNAMIC_DRAW);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Update texture data with texSubImage3D from pixel buffer should succeed");
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should draw with [255, 0, 0, 255]");
+ gl.deleteTexture(tex3d);
+ gl.deleteBuffer(buffer);
+}
+
+runTest();
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-imagedata.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-imagedata.html
new file mode 100644
index 0000000000..d6c0765bbe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-imagedata.html
@@ -0,0 +1,126 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 TexImage3D from ImageData with unpack params tests.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+let actual;
+
+description("TexImage3D from ImageData with unpack params");
+
+debug("TexImage3D from ImageData with UNPACK_IMAGE_HEIGHT set (crbug.com/804123)");
+
+// framebuffer for readback
+const fbo = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+function makeTestData(size, start) {
+ const data = new Uint8ClampedArray(size);
+ for (let i = 0; i < size; ++i) {
+ data[i] = (start + i) % 256;
+ }
+ return data;
+}
+
+// source data
+//
+// dstWidth = 4
+// <-->
+// xxxx ^ ^ ^ ^
+// xxxx | | |
+// xxxx | | |
+// xxxx | | v dstHeight = 4
+// ---- | |
+// ---- | |
+// ---- | v unpackImageHeight = 7
+// xxxx | |
+// xxxx |
+// xxxx |
+// xxxx |
+// ---- |
+// ---- |
+// ---- |
+// xxxx | |
+// xxxx |
+// xxxx |
+// xxxx |
+// ---- |
+// ---- |
+// ---- |
+// xxxx | v dstDepth = 4
+// xxxx |
+// xxxx |
+// xxxx v srcHeight = 25
+// <-->
+// srcWidth = 4
+const unpackImageHeight = 7;
+const dstWidth = 4;
+const dstHeight = 4;
+const dstDepth = 4;
+const srcWidth = dstWidth;
+const srcHeight = (dstDepth - 1) * unpackImageHeight + dstHeight;
+const srcSize = srcWidth * srcHeight;
+const sizeofR8 = 1;
+const sizeofRGBA8 = 4;
+const imageData = new ImageData(makeTestData(srcSize * sizeofRGBA8, 1), srcWidth, srcHeight);
+const texture = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_3D, texture);
+
+debug("");
+// upload
+gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 2);
+gl.texImage3D(gl.TEXTURE_3D, 0, gl.R8, 1, 1, 1, 0, gl.RED, gl.UNSIGNED_BYTE, imageData);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "small upload");
+// check
+actual = new Uint8Array(sizeofRGBA8);
+gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, 0);
+if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, actual);
+ shouldBeTrue(`areArraysEqual(actual, [1, 0, 0, 255])`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+} else {
+ debug("framebuffer incomplete: skipped");
+}
+
+debug("");
+// upload
+gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight);
+gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, dstWidth, dstHeight, dstDepth, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, imageData);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "larger upload");
+// check
+actual = new Uint8Array(dstWidth * dstHeight * sizeofRGBA8);
+let expected;
+for (let z = 0; z < dstDepth; ++z) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, z);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+ gl.readPixels(0, 0, dstWidth, dstHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
+ debug(`for z = ${z}:`);
+ expected = makeTestData(dstWidth * dstHeight * sizeofRGBA8,
+ 1 + z * dstWidth * unpackImageHeight * sizeofRGBA8);
+ shouldBeTrue('areArraysEqual(actual, expected)');
+}
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+gl.deleteTexture(texture);
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html
new file mode 100644
index 0000000000..b80b01c69a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html
@@ -0,0 +1,499 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 texture unpack parameters with FLIP_Y / PREMULTIPLY_ALPHA conformance 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>
+</head>
+<body>
+<canvas id="example" width="4" height="4"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+var __verbose__ = false;
+
+// Some drivers (for example, NVIDIA Linux) incorrectly require padding for
+// the last row. The below flag is only for testing convenience. Browsers should
+// work around the bug.
+var __apply_alignment_workaround__ = false;
+
+function setupArrayBuffer(size, initData) {
+ var array = new Uint8Array(size);
+ if (initData) {
+ for (var ii = 0; ii < size; ++ii) {
+ array[ii] = ii % 255;
+ }
+ }
+ return array;
+}
+
+function calculatePaddingBytes(bytesPerPixel, alignment, width) {
+ var padding = 0;
+ switch (alignment) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ padding = (bytesPerPixel * width) % alignment;
+ if (padding > 0)
+ padding = alignment - padding;
+ return padding;
+ default:
+ testFailed("should not reach here");
+ return;
+ }
+}
+
+function computeImageSizes2D(width, height, testCase) {
+ // Assume RGBA8/UNSIGNED_BYTE
+ var bytesPerPixel = 4;
+ var actualWidth = testCase.rowLength == 0 ? width : testCase.rowLength;
+ var padding = calculatePaddingBytes(bytesPerPixel, testCase.alignment, actualWidth);
+ var bytesPerRow = actualWidth * bytesPerPixel + padding;
+ var bytesLastRow = bytesPerPixel * width;
+ var size = bytesPerRow * (height - 1) + bytesLastRow;
+ var skipSize = 0;
+ if (testCase.skipPixels > 0)
+ skipSize += bytesPerPixel * testCase.skipPixels;
+ if (testCase.skipRows > 0)
+ skipSize += bytesPerRow * testCase.skipRows;
+ return {size: size,
+ bytesPerRow: bytesPerRow,
+ bytesLastRow: bytesLastRow,
+ padding: padding,
+ skipSize: skipSize,
+ totalSize: size + skipSize};
+}
+
+function copyData(srcData, srcIndex, dstData, dstIndex, size, premultiply_alpha) {
+ for (var ii = 0; ii < size / 4; ++ii) {
+ var factor = 1.0;
+ if (premultiply_alpha)
+ factor = srcData[srcIndex + ii * 4 + 3] / 255.0;
+ dstData[dstIndex + ii * 4] = srcData[srcIndex + ii * 4] * factor;
+ dstData[dstIndex + ii * 4 + 1] = srcData[srcIndex + ii * 4 + 1] * factor;
+ dstData[dstIndex + ii * 4 + 2] = srcData[srcIndex + ii * 4 + 2] * factor;
+ dstData[dstIndex + ii * 4 + 3] = srcData[srcIndex + ii * 4 + 3];
+ }
+}
+
+function unpackPixels(srcData, width, height, imageSizes, flip_y, premultiply_alpha) {
+ var bytesPerPixel = 4;
+ var unpackedSize = width * height * bytesPerPixel;
+ var dstData = setupArrayBuffer(unpackedSize, false);
+ var srcIndex = imageSizes.skipSize;
+ var dstIndex = 0;
+ var inc = width * bytesPerPixel;
+ if (flip_y)
+ dstIndex += (height - 1) * inc;
+ for (var y = 0; y < height; ++y) {
+ copyData(srcData, srcIndex, dstData, dstIndex, width * bytesPerPixel, premultiply_alpha);
+ srcIndex += imageSizes.bytesPerRow;
+ if (flip_y)
+ dstIndex -= inc;
+ else
+ dstIndex += inc;
+ }
+ if (flip_y)
+ dstIndex += height * inc;
+ return dstData;
+}
+
+function getPixelsFromTexture2D(gl, tex, xoffset, yoffset, width, height) {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ var bytesPerReadbackPixel = 4;
+ var readbackBuffer = setupArrayBuffer(width * height * bytesPerReadbackPixel, false);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readbackBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "read back texture pixels should succeed");
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ return readbackBuffer;
+}
+
+function comparePixels(buffer1, buffer2, tolerance) {
+ if (buffer1.length != buffer2.length || buffer1.length % 4 != 0) {
+ testFailed("compare pixels: invalid buffer size");
+ return;
+ }
+ var count = 0;
+ for (var ii = 0; ii < buffer1.length / 4; ++ii) {
+ var distance = 0;
+ for (var jj = 0; jj < 4; ++jj) {
+ var diff = buffer1[ii * 4 + jj] - buffer2[ii * 4 + jj];
+ distance += diff * diff;
+ }
+ if (Math.sqrt(diff) > tolerance) {
+ if (__verbose__) {
+ debug("Pixel " + ii + ": expected (" +
+ [buffer1[ii * 4], buffer1[ii * 4 + 1], buffer1[ii * 4 + 2], buffer1[ii * 4 + 3]] + "), got (" +
+ [buffer2[ii * 4], buffer2[ii * 4 + 1], buffer2[ii * 4 + 2], buffer2[ii * 4 + 3]] + ")");
+ }
+ count++;
+ }
+ }
+ if (count > 0) {
+ testFailed("compare pixels: " + count + " pixels differ");
+ } else {
+ testPassed("compare pixels: as expected");
+ }
+}
+
+function runTestIteration2D(gl, testCase, flip_y, premultiply_alpha) {
+ debug("");
+ debug("Texture upload with : flip_y = " + flip_y + ", premultiply_alpha = " + premultiply_alpha +
+ ", alignment = " + testCase.alignment + ", rowLength = " + testCase.rowLength +
+ ", skipPixels = " + testCase.skipPixels + ", skipRows = " + testCase.skipRows);
+ debug("TexImage2D : size = (" + testCase.width + ", " + testCase.height + ")");
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, testCase.alignment);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, testCase.rowLength);
+ gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, testCase.skipPixels);
+ gl.pixelStorei(gl.UNPACK_SKIP_ROWS, testCase.skipRows);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip_y);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiply_alpha);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up pixel store parameters should succeed");
+
+ var tol = 3;
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ var imageSizes = computeImageSizes2D(testCase.width, testCase.height, testCase);
+ var bufferSize = imageSizes.totalSize;
+ var array;
+
+ // Verify buffer with less than enough size will fail.
+ array = setupArrayBuffer(bufferSize - 1, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+
+ if (__apply_alignment_workaround__)
+ bufferSize += imageSizes.padding;
+ array = setupArrayBuffer(bufferSize, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, array);
+ if (testCase.validUnpackParams2D) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D with correct buffer size should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, testCase.width, testCase.height, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "unpack param constraints do not apply if no data are uploaded.");
+ return;
+ }
+
+ var buffer1 = unpackPixels(array, testCase.width, testCase.height, imageSizes, flip_y, premultiply_alpha);
+ var buffer2 = getPixelsFromTexture2D(gl, tex, 0, 0, testCase.width, testCase.height);
+ comparePixels(buffer1, buffer2, tol);
+
+ var subWidth = testCase.width - testCase.xoffset;
+ var subHeight = testCase.height - testCase.yoffset;
+ debug("TexSubImage2D : offset = (" + testCase.xoffset + ", " + testCase.yoffset +
+ "), size = (" + subWidth + ", " + subHeight + ")");
+ imageSizes = computeImageSizes2D(subWidth, subHeight, testCase);
+ bufferSize = imageSizes.totalSize;
+
+ array = setupArrayBuffer(bufferSize - 1, false);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset,
+ subWidth, subHeight, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+
+ if (__apply_alignment_workaround__)
+ bufferSize += imageSizes.padding;
+ array = setupArrayBuffer(bufferSize, true);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset, subWidth, subHeight,
+ gl.RGBA, gl.UNSIGNED_BYTE, array);
+ if (testCase.validUnpackParamsForSub2D) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D with correct buffer size should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
+ return;
+ }
+
+ var buffer1 = unpackPixels(array, subWidth, subHeight, imageSizes, flip_y, premultiply_alpha);
+ var buffer2 = getPixelsFromTexture2D(
+ gl, tex, testCase.xoffset, testCase.yoffset, subWidth, subHeight);
+ comparePixels(buffer1, buffer2, tol);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+}
+
+function runTests(gl) {
+ var testCases = [
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 6, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 8, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+
+ // ROW_LENGTH == width
+ { width: 10, height: 9, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 10, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+
+ // ROW_LENGTH < width
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 4, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 2, rowLength: 4, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 4, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 4, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: false },
+
+ // ROW_LENGTH > width
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 6, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 2, rowLength: 7, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 8, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 9, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+
+ // IMAGE_HEIGHT == height
+ { width: 6, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+
+ // IMAGE_HEIGHT < height
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+
+ // IMAGE_HEIGHT > height
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 6, height: 7, xoffset: 2, yoffset: 2,
+ alignment: 2, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 7, height: 7, xoffset: 2, yoffset: 4,
+ alignment: 4, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 8, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 0, skipPixels: 0, skipRows: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+
+ // SKIP parameters
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 0, skipPixels: 10, skipRows: 0,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 2, rowLength: 0, skipPixels: 2, skipRows: 8,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 0, skipPixels: 3, skipRows: 5,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 8, rowLength: 0, skipPixels: 7, skipRows: 0,
+ validUnpackParams2D: false },
+
+ // all mixed.
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 1, rowLength: 6, skipPixels: 3, skipRows: 5,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 2, rowLength: 4, skipPixels: 7, skipRows: 2,
+ validUnpackParams2D: false },
+ { width: 5, height: 7, xoffset: 2, yoffset: 3,
+ alignment: 4, rowLength: 10, skipPixels: 0, skipRows: 3,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ { width: 1, height: 1, xoffset: 0, yoffset: 0,
+ alignment: 2, rowLength: 3, skipPixels: 3, skipRows: 5,
+ validUnpackParams2D: false },
+ { width: 17, height: 6, xoffset: 12, yoffset: 3,
+ alignment: 2, rowLength: 4, skipPixels: 1, skipRows: 4,
+ validUnpackParams2D: false },
+ { width: 8, height: 17, xoffset: 2, yoffset: 13,
+ alignment: 4, rowLength: 9, skipPixels: 0, skipRows: 3,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true },
+ ];
+
+ var groups = [
+ // { flip_y: false, premultiply_alpha: false },
+ { flip_y: true, premultiply_alpha: false },
+ { flip_y: false, premultiply_alpha: true },
+ { flip_y: true, premultiply_alpha: true },
+ ];
+
+ for (var jj = 0; jj < groups.length; ++jj) {
+ var group = groups[jj];
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var testCase = testCases[ii];
+ runTestIteration2D(gl, testCase, group.flip_y, group.premultiply_alpha);
+ }
+ }
+}
+
+function runNegativeTests(gl) {
+ debug("");
+ debug("Test tex{Sub}Image2D from pbo fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true");
+
+ var width = 16, height = 16, depth = 2;
+
+ // Restore default values.
+ 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.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ var bufferSize = width * height * 4; // RGBA8
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D from pbo works with default pixel store settings");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D from pbo works with default pixel store settings");
+
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D from pbo with FLIP_Y=true should fail");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D from pbo with FLIP_Y=true should fail");
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D from pbo with PREMULTIPLY_ALPHA=true should fail");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage2D from pbo with PREMULTIPLY_ALPHA=true should fail");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+
+ debug("");
+ debug("Test tex{Sub}Image3D from pbo fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true");
+
+ gl.deleteTexture(tex);
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex);
+
+ bufferSize = width * height * depth * 4; // RGBA8
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
+
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D from pbo works with default pixel store settings");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D from pbo works with default pixel store settings");
+
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with FLIP_Y=true should fail");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with FLIP_Y=true should fail");
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+
+ debug("");
+ debug("Test tex{Sub}Image3D from client array fails with FLIP_Y = true or PREMULTIPLY_ALPHA = true");
+
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+ gl.deleteBuffer(buffer);
+ buffer = null;
+ var array = setupArrayBuffer(bufferSize, false);
+
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D from client array works with default pixel store settings");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D from client array works with default pixel store settings");
+
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from client array with FLIP_Y=true should fail");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from client array with FLIP_Y=true should fail");
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, array);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texSubImage3D from pbo with PREMULTIPLY_ALPHA=true should fail");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+}
+
+function runRegressionTests(gl) {
+ debug("");
+ debug("The following test serves as a regression test for crbug.com/774174");
+ var array = new Uint16Array(32);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 4);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 6);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texSubImage2D(gl.TEXTURE_2D, 4, 7, 5, 8, 5, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, array);
+ // At this point, the Chrome ASAN build used to crash.
+ testPassed("The regression test for crbug.com/774174 doesn't crash");
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Calling texSubImage2D without initializing the texture is illegal");
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+}
+
+var gl = wtu.create3DContext("example", undefined, 2);
+if (!gl) {
+ testFailed("Fail to get a WebGL context");
+} else {
+ runTests(gl);
+ runNegativeTests(gl);
+ runRegressionTests(gl);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params.html
new file mode 100644
index 0000000000..2cdfd4bd7d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params.html
@@ -0,0 +1,591 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 texture unpack parameters conformance 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>
+</head>
+<body>
+<canvas id="example" width="4" height="4"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+var __verbose__ = false;
+
+// Some drivers (for example, NVIDIA Linux) incorrectly require padding for
+// the last row. The below flag is only for testing convenience. Browsers should
+// work around the bug.
+var __apply_alignment_workaround__ = false;
+
+function setupArrayBuffer(size, initData) {
+ var array = new Uint8Array(size);
+ if (initData) {
+ for (var ii = 0; ii < size; ++ii) {
+ array[ii] = ii % 255;
+ }
+ }
+ return array;
+}
+
+function calculatePaddingBytes(bytesPerPixel, alignment, width) {
+ var padding = 0;
+ switch (alignment) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ padding = (bytesPerPixel * width) % alignment;
+ if (padding > 0)
+ padding = alignment - padding;
+ return padding;
+ default:
+ testFailed("should not reach here");
+ return;
+ }
+}
+
+function computeImageSizes2D(width, height, testCase) {
+ // Assume RGB8/UNSIGNED_BYTE
+ var bytesPerPixel = 3;
+ var actualWidth = testCase.rowLength == 0 ? width : testCase.rowLength;
+ var padding = calculatePaddingBytes(bytesPerPixel, testCase.alignment, actualWidth);
+ var bytesPerRow = actualWidth * bytesPerPixel + padding;
+ var bytesLastRow = bytesPerPixel * width;
+ var size = bytesPerRow * (height - 1) + bytesLastRow;
+ var skipSize = 0;
+ if (testCase.skipPixels > 0)
+ skipSize += bytesPerPixel * testCase.skipPixels;
+ if (testCase.skipRows > 0)
+ skipSize += bytesPerRow * testCase.skipRows;
+ return {size: size,
+ bytesPerRow: bytesPerRow,
+ bytesLastRow: bytesLastRow,
+ padding: padding,
+ skipSize: skipSize,
+ totalSize: size + skipSize};
+}
+
+function computeImageSizes3D(width, height, depth, testCase) {
+ // Assume RGB8/UNSIGNED_BYTE
+ var bytesPerPixel = 3;
+ var actualWidth = testCase.rowLength == 0 ? width : testCase.rowLength;
+ var actualHeight = testCase.imageHeight == 0 ? height : testCase.imageHeight;
+ var padding = calculatePaddingBytes(bytesPerPixel, testCase.alignment, actualWidth);
+ var bytesPerRow = actualWidth * bytesPerPixel + padding;
+ var bytesLastRow = bytesPerPixel * width;
+ var bytesPerImage = bytesPerRow * actualHeight;
+ var bytesLastImage = bytesPerRow * (height - 1) + bytesLastRow;
+ var size = bytesPerImage * (depth - 1) + bytesLastImage;
+ var skipSize = 0;
+ if (testCase.skipPixels > 0)
+ skipSize += bytesPerPixel * testCase.skipPixels;
+ if (testCase.skipRows > 0)
+ skipSize += bytesPerRow * testCase.skipRows;
+ if (testCase.skipImages > 0)
+ skipSize += bytesPerImage * testCase.skipImages;
+ return {size: size,
+ bytesPerRow: bytesPerRow,
+ bytesLastRow: bytesLastRow,
+ bytesPerImage: bytesPerImage,
+ bytesLastImage: bytesLastImage,
+ padding: padding,
+ skipSize: skipSize,
+ totalSize: size + skipSize};
+}
+
+function copyData(srcData, srcIndex, dstData, dstIndex, size) {
+ for (var ii = 0; ii < size; ++ii)
+ dstData[dstIndex + ii] = srcData[srcIndex + ii];
+}
+
+function unpackPixels(srcData, width, height, depth, imageSizes) {
+ var bytesPerPixel = 3;
+ var unpackedSize = width * height * depth * bytesPerPixel;
+ var dstData = setupArrayBuffer(unpackedSize, false);
+ var srcIndex = imageSizes.skipSize;
+ var dstIndex = 0;
+ for (var z = 0; z < depth; ++z) {
+ var srcIndexPerImage = srcIndex;
+ for (var y = 0; y < height; ++y) {
+ copyData(srcData, srcIndexPerImage, dstData, dstIndex, width * 3);
+ srcIndexPerImage += imageSizes.bytesPerRow;
+ dstIndex += width * 3;
+ }
+ if (depth > 1)
+ srcIndex += imageSizes.bytesPerImage;
+ }
+ return dstData;
+}
+
+function getPixelsFromTexture2D(gl, tex, xoffset, yoffset, width, height) {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ var bytesPerReadbackPixel = 4;
+ var readbackBuffer = setupArrayBuffer(width * height * bytesPerReadbackPixel, false);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readbackBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "read back texture pixels should succeed");
+ var bytesPerPixel = 3;
+ var buffer = setupArrayBuffer(width * height * bytesPerPixel, false);
+ var srcIndex = 0;
+ var dstIndex = 0;
+ for (var y = 0; y < height; ++y) {
+ for (var x = 0; x < width; ++x) {
+ buffer[dstIndex++] = readbackBuffer[srcIndex++]; // R
+ buffer[dstIndex++] = readbackBuffer[srcIndex++]; // G
+ buffer[dstIndex++] = readbackBuffer[srcIndex++]; // B
+ srcIndex++; // A
+ }
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ return buffer;
+}
+
+function getPixelsFromTexture3D(gl, tex, xoffset, yoffset, zoffset, width, height, depth) {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var bytesPerReadbackPixel = 4;
+ var readbackBuffer = setupArrayBuffer(width * height * bytesPerReadbackPixel, false);
+ var bytesPerPixel = 3;
+ var buffer = setupArrayBuffer(width * height * depth * bytesPerPixel, false);
+ var dstIndex = 0;
+ for (var zz = 0; zz < depth; ++zz) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, zz + zoffset);
+ gl.readPixels(xoffset, yoffset, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readbackBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "read back texture pixels should succeed");
+ var srcIndex = 0;
+ for (var y = 0; y < height; ++y) {
+ for (var x = 0; x < width; ++x) {
+ buffer[dstIndex++] = readbackBuffer[srcIndex++]; // R
+ buffer[dstIndex++] = readbackBuffer[srcIndex++]; // G
+ buffer[dstIndex++] = readbackBuffer[srcIndex++]; // B
+ srcIndex++; // A
+ }
+ }
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ return buffer;
+}
+
+function comparePixels(buffer1, buffer2) {
+ if (buffer1.length != buffer2.length || buffer1.length % 3 != 0) {
+ testFailed("compare pixels: invalid buffer size");
+ return;
+ }
+ var count = 0;
+ for (var ii = 0; ii < buffer1.length / 3; ++ii) {
+ if (buffer1[ii * 3] != buffer2[ii * 3] ||
+ buffer1[ii * 3 + 1] != buffer2[ii * 3 + 1] ||
+ buffer1[ii * 3 + 2] != buffer2[ii * 3 + 2]) {
+ if (__verbose__) {
+ debug("Pixel " + ii + ": expected (" +
+ [buffer1[ii * 3], buffer1[ii * 3 + 1], buffer1[ii * 3 + 2]] + "), got (" +
+ [buffer2[ii * 3], buffer2[ii * 3 + 1], buffer2[ii * 3 + 2]] + ")");
+ }
+ count++;
+ }
+ }
+ if (count > 0) {
+ testFailed("compare pixels: " + count + " pixels differ");
+ } else {
+ testPassed("compare pixels: as expected");
+ }
+}
+
+function runTestIteration2D(gl, testCase, useUnpackBuffer) {
+ debug("");
+ debug("Texture upload from " + (useUnpackBuffer ? "unpack buffer" : "client data") +
+ " : alignment = " + testCase.alignment + ", rowLength = " + testCase.rowLength +
+ ", skipPixels = " + testCase.skipPixels + ", skipRows = " + testCase.skipRows);
+ debug("TexImage2D : size = (" + testCase.width + ", " + testCase.height + ")");
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, testCase.alignment);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, testCase.rowLength);
+ gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, testCase.skipPixels);
+ gl.pixelStorei(gl.UNPACK_SKIP_ROWS, testCase.skipRows);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up pixel store parameters should succeed");
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ var imageSizes = computeImageSizes2D(testCase.width, testCase.height, testCase);
+ var bufferSize = imageSizes.totalSize;
+ var buffer = null;
+ var array;
+
+ // Verify buffer with less than enough size will fail.
+ if (useUnpackBuffer) {
+ buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize - 1, gl.DYNAMIC_DRAW);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB8, testCase.width, testCase.height, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, 0);
+ } else {
+ array = setupArrayBuffer(bufferSize - 1, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB8, testCase.width, testCase.height, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, array);
+ }
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+
+ if (__apply_alignment_workaround__)
+ bufferSize += imageSizes.padding;
+ array = setupArrayBuffer(bufferSize, true);
+ if (useUnpackBuffer) {
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, array, gl.DYNAMIC_DRAW);
+ }
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB8, testCase.width, testCase.height, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, useUnpackBuffer ? 0 : array);
+ if (testCase.validUnpackParams2D) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D with correct buffer size should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
+ if (!useUnpackBuffer) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB8, testCase.width, testCase.height, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "unpack param constraints do not apply if no data are uploaded.");
+ }
+ return;
+ }
+
+ var buffer1 = unpackPixels(array, testCase.width, testCase.height, 1, imageSizes);
+ var buffer2 = getPixelsFromTexture2D(gl, tex, 0, 0, testCase.width, testCase.height);
+ comparePixels(buffer1, buffer2);
+
+ var subWidth = testCase.width - testCase.xoffset;
+ var subHeight = testCase.height - testCase.yoffset;
+ debug("TexSubImage2D : offset = (" + testCase.xoffset + ", " + testCase.yoffset +
+ "), size = (" + subWidth + ", " + subHeight + ")");
+ imageSizes = computeImageSizes2D(subWidth, subHeight, testCase);
+ bufferSize = imageSizes.totalSize;
+
+ if (useUnpackBuffer) {
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize - 1, gl.DYNAMIC_DRAW);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset,
+ subWidth, subHeight, gl.RGB, gl.UNSIGNED_BYTE, 0);
+ } else {
+ array = setupArrayBuffer(bufferSize - 1, false);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset,
+ subWidth, subHeight, gl.RGB, gl.UNSIGNED_BYTE, array);
+ }
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+
+ if (__apply_alignment_workaround__)
+ bufferSize += imageSizes.padding;
+ array = setupArrayBuffer(bufferSize, true);
+ if (useUnpackBuffer) {
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, array, gl.DYNAMIC_DRAW);
+ }
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, testCase.xoffset, testCase.yoffset, subWidth, subHeight,
+ gl.RGB, gl.UNSIGNED_BYTE, useUnpackBuffer ? 0 : array);
+ if (testCase.validUnpackParamsForSub2D) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D with correct buffer size should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
+ return;
+ }
+
+ var buffer1 = unpackPixels(array, subWidth, subHeight, 1, imageSizes);
+ var buffer2 = getPixelsFromTexture2D(
+ gl, tex, testCase.xoffset, testCase.yoffset, subWidth, subHeight);
+ comparePixels(buffer1, buffer2);
+
+ if (buffer) {
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+ gl.deleteBuffer(buffer);
+ }
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+}
+
+function runTestIteration3D(gl, testCase, useUnpackBuffer) {
+ debug("");
+ debug("Texture upload from " + (useUnpackBuffer ? "unpack buffer" : "client data") +
+ " : alignment = " + testCase.alignment + ", rowLength = " + testCase.rowLength +
+ ", imageHeight = " + testCase.imageHeight + ", skipPixels = " + testCase.skipPixels +
+ ", skipRows = " + testCase.skipRows + ", skipImages = " + testCase.skipImages);
+ debug("TexImage3D : size = (" + testCase.width + ", " + testCase.height + ", " + testCase.depth + ")");
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, testCase.alignment);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, testCase.rowLength);
+ gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, testCase.imageHeight);
+ gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, testCase.skipPixels);
+ gl.pixelStorei(gl.UNPACK_SKIP_ROWS, testCase.skipRows);
+ gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, testCase.skipImages);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up pixel store parameters should succeed");
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, tex);
+
+ var imageSizes = computeImageSizes3D(testCase.width, testCase.height, testCase.depth, testCase);
+ var buffer = null;
+ var array;
+ var bufferSize = imageSizes.totalSize;
+
+ // Verify buffer with less than enough size will fail.
+ if (useUnpackBuffer) {
+ buffer = gl.createBuffer();
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer);
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize - 1, gl.DYNAMIC_DRAW);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB8, testCase.width, testCase.height, testCase.depth, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, 0);
+ } else {
+ array = setupArrayBuffer(bufferSize - 1, false);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB8, testCase.width, testCase.height, testCase.depth, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, array);
+ }
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+
+ if (__apply_alignment_workaround__)
+ bufferSize += imageSizes.padding;
+ array = setupArrayBuffer(bufferSize, true);
+ if (useUnpackBuffer) {
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, array, gl.DYNAMIC_DRAW);
+ }
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB8, testCase.width, testCase.height, testCase.depth, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, useUnpackBuffer ? 0 : array);
+ if (testCase.validUnpackParams3D) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D with correct buffer size should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
+ if (!useUnpackBuffer) {
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB8, testCase.width, testCase.height, testCase.depth, 0,
+ gl.RGB, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "unpack param constraints do not apply if no data are uploaded.");
+ }
+ return;
+ }
+
+ var buffer1 = unpackPixels(array, testCase.width, testCase.height, testCase.depth, imageSizes);
+ var buffer2 = getPixelsFromTexture3D(
+ gl, tex, 0, 0, 0, testCase.width, testCase.height, testCase.depth);
+ comparePixels(buffer1, buffer2);
+
+ var subWidth = testCase.width - testCase.xoffset;
+ var subHeight = testCase.height - testCase.yoffset;
+ var subDepth = testCase.depth - testCase.zoffset;
+ debug("TexSubImage3D : offset = (" + testCase.xoffset + ", " + testCase.yoffset + ", " +
+ testCase.zoffset + "), size = (" + subWidth + ", " + subHeight + ", " + subDepth + ")");
+ imageSizes = computeImageSizes3D(subWidth, subHeight, subDepth, testCase);
+ bufferSize = imageSizes.totalSize;
+
+ if (useUnpackBuffer) {
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, bufferSize - 1, gl.DYNAMIC_DRAW);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, testCase.xoffset, testCase.yoffset, testCase.zoffset,
+ subWidth, subHeight, subDepth, gl.RGB, gl.UNSIGNED_BYTE, 0);
+ } else {
+ array = setupArrayBuffer(bufferSize - 1, false);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, testCase.xoffset, testCase.yoffset, testCase.zoffset,
+ subWidth, subHeight, subDepth, gl.RGB, gl.UNSIGNED_BYTE, array);
+ }
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer too small");
+
+ if (__apply_alignment_workaround__)
+ bufferSize += imageSizes.padding;
+ array = setupArrayBuffer(bufferSize, true);
+ if (useUnpackBuffer) {
+ gl.bufferData(gl.PIXEL_UNPACK_BUFFER, array, gl.DYNAMIC_DRAW);
+ }
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, testCase.xoffset, testCase.yoffset, testCase.zoffset,
+ subWidth, subHeight, subDepth,
+ gl.RGB, gl.UNSIGNED_BYTE, useUnpackBuffer ? 0 : array);
+ if (testCase.validUnpackParamsForSub3D) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D with correct buffer size should succeed");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid unpack params combination");
+ return;
+ }
+
+ buffer1 = unpackPixels(array, subWidth, subHeight, subDepth, imageSizes);
+ buffer2 = getPixelsFromTexture3D(gl, tex, testCase.xoffset, testCase.yoffset, testCase.zoffset,
+ subWidth, subHeight, subDepth);
+ comparePixels(buffer1, buffer2);
+
+ if (buffer) {
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+ gl.deleteBuffer(buffer);
+ }
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ gl.deleteTexture(tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
+}
+
+function runTests() {
+ var gl = wtu.create3DContext("example", undefined, 2);
+ if (!gl) {
+ testFailed("Fail to get a WebGL context");
+ return;
+ }
+
+ // For 2D cases, depth, zoffset, imageHeight, skipImages are ignored.
+ var testCases = [
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 0, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 5, height: 7, depth: 4, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 2, rowLength: 0, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 6, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 0, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 5, height: 8, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 8, rowLength: 0, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+
+ // ROW_LENGTH == width
+ { width: 10, height: 9, depth: 2, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 10, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+
+ // ROW_LENGTH < width
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 4, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 2, rowLength: 4, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 4, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 8, rowLength: 4, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+
+ // ROW_LENGTH > width
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 6, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 2, rowLength: 7, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 8, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 5, height: 7, depth: 5, xoffset: 2, yoffset: 3, zoffset: 2,
+ alignment: 8, rowLength: 9, imageHeight: 0, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+
+ // IMAGE_HEIGHT == height
+ { width: 6, height: 7, depth: 4, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 8, rowLength: 0, imageHeight: 7, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+
+ // IMAGE_HEIGHT < height
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 0, imageHeight: 6, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 2, rowLength: 0, imageHeight: 6, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 0, imageHeight: 6, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 8, rowLength: 0, imageHeight: 6, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: false },
+
+ // IMAGE_HEIGHT > height
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 0, imageHeight: 8, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 6, height: 7, depth: 3, xoffset: 2, yoffset: 2, zoffset: 1,
+ alignment: 2, rowLength: 0, imageHeight: 9, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 7, height: 7, depth: 3, xoffset: 2, yoffset: 4, zoffset: 1,
+ alignment: 4, rowLength: 0, imageHeight: 10, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+ { width: 8, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 8, rowLength: 0, imageHeight: 11, skipPixels: 0, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: true, validUnpackParamsForSub3D: true },
+
+ // SKIP parameters
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 0, imageHeight: 0, skipPixels: 10, skipRows: 0, skipImages: 0,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 2, rowLength: 0, imageHeight: 0, skipPixels: 2, skipRows: 8, skipImages: 0,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 0, imageHeight: 0, skipPixels: 3, skipRows: 5, skipImages: 1,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 8, rowLength: 0, imageHeight: 0, skipPixels: 7, skipRows: 0, skipImages: 2,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+
+ // all mixed.
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 1, rowLength: 6, imageHeight: 6, skipPixels: 3, skipRows: 5, skipImages: 1,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 2, rowLength: 4, imageHeight: 8, skipPixels: 7, skipRows: 2, skipImages: 2,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 5, height: 7, depth: 3, xoffset: 2, yoffset: 3, zoffset: 1,
+ alignment: 4, rowLength: 10, imageHeight: 2, skipPixels: 0, skipRows: 3, skipImages: 1,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: false },
+ { width: 1, height: 1, depth: 1, xoffset: 0, yoffset: 0, zoffset: 0,
+ alignment: 2, rowLength: 3, imageHeight: 2, skipPixels: 3, skipRows: 5, skipImages: 1,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 17, height: 6, depth: 4, xoffset: 12, yoffset: 3, zoffset: 2,
+ alignment: 2, rowLength: 4, imageHeight: 8, skipPixels: 1, skipRows: 4, skipImages: 2,
+ validUnpackParams2D: false, validUnpackParams3D: false },
+ { width: 8, height: 17, depth: 3, xoffset: 2, yoffset: 13, zoffset: 1,
+ alignment: 4, rowLength: 9, imageHeight: 2, skipPixels: 0, skipRows: 3, skipImages: 1,
+ validUnpackParams2D: true, validUnpackParamsForSub2D: true,
+ validUnpackParams3D: false },
+ ];
+
+ // Upload textures from client data
+ var useUnpackBuffer = false;
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var testCase = testCases[ii];
+ runTestIteration2D(gl, testCase, useUnpackBuffer);
+ runTestIteration3D(gl, testCase, useUnpackBuffer);
+ }
+
+ // Upload textures from unpack buffer
+ useUnpackBuffer = true;
+ for (var ii = 0; ii < testCases.length; ++ii) {
+ var testCase = testCases[ii];
+ runTestIteration2D(gl, testCase, useUnpackBuffer);
+ runTestIteration3D(gl, testCase, useUnpackBuffer);
+ }
+}
+
+runTests();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texel-fetch-undefined.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texel-fetch-undefined.html
new file mode 100644
index 0000000000..056deade3b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texel-fetch-undefined.html
@@ -0,0 +1,82 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL texel fetch test.</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<canvas id="c" width="256" height="256"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vertex-shader" type="x-shader/x-vertex">#version 300 es
+ precision highp float;
+ in vec4 aPosition;
+
+ void main() {
+ gl_Position = aPosition;
+ }
+</script>
+<script id="fragment-shader" type="x-shader/x-fragment">#version 300 es
+ precision mediump float;
+ uniform sampler2D uSampler;
+ uniform ivec2 uTestPos;
+
+ out vec4 my_FragColor;
+ void main() {
+ my_FragColor = texelFetch(uSampler, uTestPos, 0);
+ }
+</script>
+<script>
+"use strict";
+description("This test makes sure that texelFetch works to the WebGL 2.0 spec when retrieving a texel outside of the texture's size.");
+
+var wtu = WebGLTestUtils;
+var textureSize = 24;
+
+var gl = wtu.create3DContext('c', undefined, 2);
+
+function testFetchAt(x, y, expectedColor) {
+ debug("");
+ debug("Test fetching a texel of the texture at x = " + x +", y = " + y);
+ gl.uniform2i(uTestPos, x, y);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, expectedColor);
+}
+
+var program = wtu.setupProgram(gl, ["vertex-shader", "fragment-shader"]);
+var aPosition = gl.getAttribLocation(program, "aPosition");
+var uTestPos = gl.getUniformLocation(program, "uTestPos");
+
+debug('Creating a texture with size ' + textureSize + '*' + textureSize);
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+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);
+wtu.fillTexture(gl, tex, textureSize, textureSize, [0, 255, 0, 255]);
+
+wtu.setupUnitQuad(gl, aPosition);
+
+testFetchAt(0, 0, [0, 255, 0, 255]);
+testFetchAt(textureSize - 1, textureSize - 1, [0, 255, 0, 255]);
+testFetchAt(textureSize, 0, [0, 0, 0, 0]);
+testFetchAt(0, textureSize, [0, 0, 0, 0]);
+testFetchAt(-1, 0, [0, 0, 0, 0]);
+testFetchAt(0, -1, [0, 0, 0, 0]);
+testFetchAt(-1, 1, [0, 0, 0, 0]);
+
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texture-npot.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texture-npot.html
new file mode 100644
index 0000000000..1d63130eeb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texture-npot.html
@@ -0,0 +1,160 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL2 Non-Power of 2 texture conformance 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>
+</head>
+<body>
+<canvas id="example" width="5" height="3" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform samplerCube tex;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = textureCube(tex, normalize(vec3(texCoord, 1)));
+}
+</script>
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+var program = wtu.setupTexturedQuad(gl);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var tests = [
+ { format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ color: [192, 0, 128, 64],
+ expected: [192, 0, 128, 64],
+ tolerance: 0,
+ },
+ { format: gl.RGB,
+ type: gl.UNSIGNED_BYTE,
+ color: [192, 0, 128],
+ expected: [192, 0, 128, 255],
+ tolerance: 0,
+ },
+ { format: gl.LUMINANCE,
+ type: gl.UNSIGNED_BYTE,
+ color: [192],
+ expected: [192, 192, 192, 255],
+ tolerance: 0,
+ },
+ { format: gl.ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ color: [64],
+ expected: [0, 0, 0, 64],
+ tolerance: 0,
+ },
+ { format: gl.LUMINANCE_ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ color: [192, 64],
+ expected: [192, 192, 192, 64],
+ tolerance: 0,
+ },
+];
+
+tests.forEach(function(test) {
+ debug("");
+ debug("test " + wtu.glEnumToString(gl, test.format) + "/" + wtu.glEnumToString(gl, test.type));
+ var tex = gl.createTexture();
+
+ // Check that an NPOT texture not on level 0 does not generate INVALID_VALUE
+ wtu.fillTexture(gl, tex, 5, 3, test.color, 1, test.format, test.type);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D with NPOT texture with level > 0 should succeed");
+
+ // Check that an NPOT texture on level 0 succeeds
+ wtu.fillTexture(gl, tex, 5, 3, test.color, 0, test.format, test.type);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D with NPOT texture at level 0 should succeed");
+
+ // Check that generateMipmap succeeds on NPOT
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.generateMipmap with NPOT texture should succeed");
+
+ // Check that nothing is drawn if filtering is not correct for NPOT
+ 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.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, test.expected,
+ "NPOT texture with TEXTURE_WRAP set to REPEAT should draw");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+ 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_MIPMAP_LINEAR);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, test.expected,
+ "NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, test.expected,
+ "NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw.");
+
+ gl.copyTexImage2D(gl.TEXTURE_2D, 1, test.format, 0, 0, 5, 3, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "copyTexImage2D with NPOT texture with level > 0 should succeed.");
+
+ // Check that generateMipmap for an POT texture succeeds
+ wtu.fillTexture(gl, tex, 2, 2, test.color, 0, test.format);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D and gl.generateMipmap with POT texture at level 0 should succeed");
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, test.expected,
+ "POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw.");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+});
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..70c3afdd2b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..cdfaa83586
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..9aa9b1b354
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..041b7efc30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..2ef4285bce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..98689741a2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..912bd48e8e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..1eee7614a0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..588df337b6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..c4e1b6c71e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..65ab812099
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..56f109c1b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..87a76f8f3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..a43a4e6677
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..8f78281514
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..5e0b208afd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..2163766665
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..3e08c1f3e9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..6c50461f75
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4af3e733c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..8286845c1c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..15118cd8e4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..4d4c701e27
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..389243484a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..8fe5f31e01
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..5f40dd0126
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..d66ef95477
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..d2ae8a5d37
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f71f0ab9bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..07453b5d6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..9bcf07331a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..0a584f8e1a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..0a4b73be41
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..89d949a817
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..931574072c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..0d3736b7d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..28edaf8484
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..375f4a34f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..be0c2169cb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..5d008b9dd6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..33c0c30d57
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..a167338ba8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..841df79968
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..9b58b96884
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..241b5779a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..b0564b4d08
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..c94c1a06ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..205041bd2f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..75a8c64adf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..1f9704ab9f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..8f20b94f34
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..7953d7df1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..ab30dfdb47
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..37da0e3c77
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..ca52e1a021
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..fc1d4c82ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..01bfb29bf0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..76f4dd17cc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..f1801ef2ec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..c6b03d38ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..f93af67120
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..69bf81a48f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..920b2f303d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..73347d83f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..dc4276bec9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..0bb5af2704
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..6c0f8a9dfc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c21c22330f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..8da33f479d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..de224234d9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..ff48aca140
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..48f19f8fc1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..53d24ec47b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..4482661a5e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..c87153e45b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..437aa3e9b3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..5d08f8ce16
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..de3935fb3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..11737a84da
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..0d4f5793a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..20ba3058e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..ea3417f308
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..60d9f40110
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..72302bac90
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..8afa91dec0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..e199aad6ef
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..f4f441038e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..89bb430792
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..8e600928e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..89694c37b5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..cc6413ea96
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..35fa5802bc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..9a94bdf215
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..68753476de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..5eaec79917
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..9400dbf128
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..7392552897
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..21227a4232
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..ac9e136b96
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..5ede605e54
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..5647dcb4f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4158166a8b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..8267be44db
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..148b0348e0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..5191af8499
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..96424f67bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..d2ea68c28e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..7cadbdd50a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..1cc91b08ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..104b0c3c7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..fff3874e6f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..cb02da362d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..13d9bd2149
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..742d80875d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6bec2e0e1f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..2101029838
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..39f2fe0609
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..8bca6ac885
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..02f26d4844
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..30aa25e21f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..6b34875b80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..e6dce95067
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..5ad8bd6bf4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..62ffa4d71c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..924be8799a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..6d339d91f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..cd8015ad8f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..eb297d466c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..bc3b520d36
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..38ae56c603
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..fb83b5984b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..3ae82983f7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..999c0601f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..bb8fb1894c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..1b97731549
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..73433f67fe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/00_test_list.txt
new file mode 100644
index 0000000000..934fa86eaa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/00_test_list.txt
@@ -0,0 +1,68 @@
+tex-2d-r8-red-unsigned_byte.html
+tex-2d-r16f-red-half_float.html
+tex-2d-r16f-red-float.html
+tex-2d-r32f-red-float.html
+tex-2d-r8ui-red_integer-unsigned_byte.html
+tex-2d-rg8-rg-unsigned_byte.html
+tex-2d-rg16f-rg-half_float.html
+tex-2d-rg16f-rg-float.html
+tex-2d-rg32f-rg-float.html
+tex-2d-rg8ui-rg_integer-unsigned_byte.html
+tex-2d-rgb8-rgb-unsigned_byte.html
+tex-2d-srgb8-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_byte.html
+tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-2d-r11f_g11f_b10f-rgb-half_float.html
+tex-2d-r11f_g11f_b10f-rgb-float.html
+tex-2d-rgb9_e5-rgb-half_float.html
+tex-2d-rgb9_e5-rgb-float.html
+tex-2d-rgb16f-rgb-half_float.html
+tex-2d-rgb16f-rgb-float.html
+tex-2d-rgb32f-rgb-float.html
+tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-2d-rgba8-rgba-unsigned_byte.html
+tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_byte.html
+tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-2d-rgba4-rgba-unsigned_byte.html
+tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba16f-rgba-half_float.html
+tex-2d-rgba16f-rgba-float.html
+tex-2d-rgba32f-rgba-float.html
+tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
+tex-3d-r8-red-unsigned_byte.html
+tex-3d-r16f-red-half_float.html
+tex-3d-r16f-red-float.html
+tex-3d-r32f-red-float.html
+tex-3d-r8ui-red_integer-unsigned_byte.html
+tex-3d-rg8-rg-unsigned_byte.html
+tex-3d-rg16f-rg-half_float.html
+tex-3d-rg16f-rg-float.html
+tex-3d-rg32f-rg-float.html
+tex-3d-rg8ui-rg_integer-unsigned_byte.html
+tex-3d-rgb8-rgb-unsigned_byte.html
+tex-3d-srgb8-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_byte.html
+tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
+tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
+tex-3d-r11f_g11f_b10f-rgb-half_float.html
+tex-3d-r11f_g11f_b10f-rgb-float.html
+tex-3d-rgb9_e5-rgb-half_float.html
+tex-3d-rgb9_e5-rgb-float.html
+tex-3d-rgb16f-rgb-half_float.html
+tex-3d-rgb16f-rgb-float.html
+tex-3d-rgb32f-rgb-float.html
+tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
+tex-3d-rgba8-rgba-unsigned_byte.html
+tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_byte.html
+tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
+tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
+tex-3d-rgba4-rgba-unsigned_byte.html
+tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
+tex-3d-rgba16f-rgba-half_float.html
+tex-3d-rgba16f-rgba-float.html
+tex-3d-rgba32f-rgba-float.html
+tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..f2ad493097
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..572663d228
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..3b451cda0e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html
new file mode 100644
index 0000000000..14da0a40f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html
new file mode 100644
index 0000000000..63ecff5a46
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html
new file mode 100644
index 0000000000..58412cc6e3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..51461d9611
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6f791ef39f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html
new file mode 100644
index 0000000000..519a8fd783
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..2d8c646176
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html
new file mode 100644
index 0000000000..95562187df
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..6c09f94fb5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..52d6638f01
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..19e1f0618e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..6dad747733
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..536ca73944
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..fcb7a1f6bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..cd4d7f2b87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..92b0986a76
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..8b5d03bfc7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..d306085a26
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..ac91e3352d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6153033352
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..f9b1eabcd8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..a79e67496c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..c06adc5bc0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..bf88f69b53
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..6bd3b2ae64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..1768f8be8e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..43ec606dbc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..c77410acf4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..1a1b69f8ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..69f2892b62
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..517daedcbe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html
new file mode 100644
index 0000000000..66fcf4e320
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html
new file mode 100644
index 0000000000..58e257d4f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
new file mode 100644
index 0000000000..e124673126
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R11F_G11F_B10F", "RGB", "UNSIGNED_INT_10F_11F_11F_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html
new file mode 100644
index 0000000000..a6b6d216fa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html
new file mode 100644
index 0000000000..908d5935fc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R16F", "RED", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html
new file mode 100644
index 0000000000..6960f8bce8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R32F", "RED", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html
new file mode 100644
index 0000000000..a37d1c4bf0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8", "RED", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html
new file mode 100644
index 0000000000..38801bd3f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("R8UI", "RED_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html
new file mode 100644
index 0000000000..69cf2e9141
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html
new file mode 100644
index 0000000000..50d04e6b7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG16F", "RG", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html
new file mode 100644
index 0000000000..463a0ef19b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG32F", "RG", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html
new file mode 100644
index 0000000000..ee97689f18
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8", "RG", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html
new file mode 100644
index 0000000000..6fec968239
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RG8UI", "RG_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
new file mode 100644
index 0000000000..6450a174d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB10_A2", "RGBA", "UNSIGNED_INT_2_10_10_10_REV", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html
new file mode 100644
index 0000000000..4fcb222ba2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html
new file mode 100644
index 0000000000..7dd91adc70
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB16F", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html
new file mode 100644
index 0000000000..a6b5c973e6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB32F", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..1293e5a5fd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..7aa3770fee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB565", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..05a09947f2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..2529c36698
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB5_A1", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..a38c237d33
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
new file mode 100644
index 0000000000..c3563665ad
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB8UI", "RGB_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html
new file mode 100644
index 0000000000..1d4d0200aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html
new file mode 100644
index 0000000000..a9ae2f904d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB9_E5", "RGB", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html
new file mode 100644
index 0000000000..aee016ff9e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html
new file mode 100644
index 0000000000..dcbe835102
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA16F", "RGBA", "HALF_FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html
new file mode 100644
index 0000000000..d26fbf5eb1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA32F", "RGBA", "FLOAT", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..700e4482ec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..c33d936c97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA4", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..a7da2df13d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
new file mode 100644
index 0000000000..061d12d12f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA8UI", "RGBA_INTEGER", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..d14b5eeaf8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..20b6f7cc5c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("SRGB8_ALPHA8", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 2)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/00_test_list.txt
new file mode 100644
index 0000000000..35caba6ccd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/00_test_list.txt
@@ -0,0 +1,9 @@
+--min-version 2.0.1 non-existent-varying.html
+--min-version 2.0.1 default_transform_feedback.html
+transform_feedback.html
+two-unreferenced-varyings.html
+--min-version 2.0.1 too-small-buffers.html
+unwritten-output-defaults-to-zero.html
+--min-version 2.0.1 same-buffer-two-binding-points.html
+--min-version 2.0.1 simultaneous_binding.html
+--min-version 2.0.1 switching-objects.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/default_transform_feedback.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/default_transform_feedback.html
new file mode 100644
index 0000000000..1d5e72811a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/default_transform_feedback.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Transform Feedback Conformance Test - Default Transform Feedback</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in float in_value;
+out float out_value;
+
+void main() {
+ out_value = in_value * 2.;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 dummy;
+void main() {
+ dummy = vec4(1);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies using the default transform feedback object");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runDefaultTransformFeedbackTest();
+ finishTest();
+}
+
+function runDefaultTransformFeedbackTest() {
+ const prog = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_value"], gl.SEPARATE_ATTRIBS,
+ ["in_value"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+
+ const inLoc = 0;
+ const outLoc = 0;
+
+ const srcBuffer1 = createBuffer(gl, new Float32Array([1, 2, 3]));
+ const srcVAO1 = createVAO(gl, srcBuffer1, inLoc);
+
+ const dstBuffer = createBuffer(gl, Float32Array.BYTES_PER_ELEMENT * 3);
+
+ const tf = null; // use the default transform feedback gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.useProgram(prog);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, outLoc, dstBuffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors binding a buffer to the default transform feedback");
+
+ runFeedback(gl, prog, srcVAO1, tf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors having drawn with the default transform feedback");
+
+ const expected = [2, 4, 6];
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, dstBuffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors after readback");
+}
+
+function runFeedback(gl, prog, srcVAO, tf, dstBufferInfo) {
+ gl.enable(gl.RASTERIZER_DISCARD);
+
+ gl.useProgram(prog);
+ gl.bindVertexArray(srcVAO);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors setting up to draw with the default transform feedback");
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ gl.endTransformFeedback();
+
+ gl.disable(gl.RASTERIZER_DISCARD);
+}
+
+function createBuffer(gl, dataOrSize) {
+ const buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, dataOrSize, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null); // Clear this or we'll have tfo/non-tfo simultaneous usage.
+ return buf;
+}
+
+function createVAO(gl, buf, inLoc) {
+ const vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.enableVertexAttribArray(inLoc);
+ gl.vertexAttribPointer(inLoc, 1, gl.FLOAT, false, 0, 0);
+ gl.bindVertexArray(null);
+ return vao;
+}
+</script>
+</body>
+</html>
+
+<!--
+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.
+-->
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/non-existent-varying.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/non-existent-varying.html
new file mode 100644
index 0000000000..80800c2dc5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/non-existent-varying.html
@@ -0,0 +1,70 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Transform Feedback Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec3 position;
+void main()
+{
+ gl_Position = vec4(position, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+void main()
+{
+ color = vec4(0);
+}
+</script>
+<script>
+"use strict";
+description("Test that specifying non-existent varyings for transform feedback causes the program to fail to link. This test covers an ANGLE bug.");
+
+// Spec: GLES 3.0.5 section 2.12.8:
+// "A program will fail to link if:"
+// "any variable name specified in the varyings array is not declared as an output in the vertex shader;"
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ runTest("bogus");
+ runTest("gl_Bogus");
+}
+
+function runTest(nonExistentVaryingName) {
+ var program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ [nonExistentVaryingName], gl.INTERLEAVED_ATTRIBS,
+ ["position"]);
+ var msg = "Program should fail to link when a nonexistent varying '" + nonExistentVaryingName + "' is specified for transform feedback.";
+ if (program) {
+ testFailed(msg);
+ } else {
+ testPassed(msg);
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/same-buffer-two-binding-points.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/same-buffer-two-binding-points.html
new file mode 100644
index 0000000000..86e7a5d402
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/same-buffer-two-binding-points.html
@@ -0,0 +1,176 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Transform Feedback Conformance Tests - one buffer bound to two binding points</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+
+in vec4 in_data;
+out vec4 out_add;
+out vec4 out_mul;
+void main(void) {
+ out_add = in_data + vec4(2.0, 3.0, 4.0, 5.0);
+ out_mul = in_data * vec4(2.0, 3.0, 4.0, 5.0);
+}
+</script>
+<script>
+"use strict";
+description();
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(null, null, 2);
+var program = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ runTwoOutFeedbackTest();
+}
+
+function doDrawWithTransformFeedback(expectedError, msg) {
+ gl.beginTransformFeedback(gl.POINTS);
+ wtu.glErrorShouldBe(gl, expectedError, msg);
+ gl.drawArrays(gl.POINTS, 0, 3);
+ gl.endTransformFeedback();
+ gl.getError();
+}
+
+function runTwoOutFeedbackTest() {
+ debug("");
+ debug("Test binding the same buffer to two transform feedback binding points. Buffer should be untouched and an error should be generated.")
+
+ // Build the input and output buffers
+ var in_data = [
+ 1.0, 2.0, 3.0, 4.0,
+ 2.0, 4.0, 8.0, 16.0,
+ 0.75, 0.5, 0.25, 0.0
+ ];
+
+ var in_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
+
+ // Create the transform feedback shader
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", wtu.simpleColorFragmentShaderESSL300],
+ ["out_add", "out_mul"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeNonNull("program");
+
+ // Draw the the transform feedback buffers
+ var tf = gl.createTransformFeedback();
+
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0);
+
+ var out_buffer = gl.createBuffer();
+ var out_buffer2 = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+
+ // Test binding the same buffer to two transform feedback binding points with bindBufferBase.
+ debug("");
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer);
+
+ doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferBase");
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null);
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ // Check buffer contents.
+ var expectedZeroes = [];
+ for (var i = 0; i < in_data.length * 2; ++i)
+ {
+ expectedZeroes.push(0.0);
+ }
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ debug("buffer should be untouched - filled with zeroes");
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes);
+
+ // Test binding the same buffer to two transform feedback binding points with bindBufferRange. The ranges overlap just slightly.
+ debug("");
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer, 0, in_data.length * 4);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer, (in_data.length - 1) * 4, in_data.length * 4);
+
+ doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferRange, overlapping ranges");
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null);
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ // Check buffer contents.
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ debug("buffer should be untouched - filled with zeroes");
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes);
+
+ // Test non-overlapping ranges.
+ debug("");
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer, 0, in_data.length * 4);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer, in_data.length * 4, in_data.length * 4);
+
+ doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferRange, non-overlapping ranges");
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null);
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ // Check buffer contents.
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ debug("buffer should be untouched - filled with zeroes");
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes);
+
+ // Test binding the same buffer to a binding point that doesn't have a corresponding output in the vertex shader.
+ debug("");
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer2);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer2);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, out_buffer); // No corresponding output.
+
+ doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferBase, but one of the binding points doesn't have a corresponding shader output");
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, null);
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ // Check buffer contents.
+ debug("buffers should be untouched - filled with zeroes");
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer2);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes);
+
+ finishTest();
+}
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/simultaneous_binding.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/simultaneous_binding.html
new file mode 100644
index 0000000000..228b4ab5cf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/simultaneous_binding.html
@@ -0,0 +1,330 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Simultaneous binding</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in float in_value;
+in float in_value2;
+out float out_value;
+
+void main() {
+ out_value = in_value * 2.;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 dummy;
+uniform UniformBlock {
+ float fragment_value;
+};
+void main() {
+ dummy = vec4(fragment_value);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies that access to a buffer simultaneously bound to a transform feedback object and a non-transform-feedback binding point is forbidden.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+}
+
+function drawWithFeedbackBound(gl, drawFunction, prog, vao, tf, enableFeedback) {
+ gl.useProgram(prog);
+ gl.bindVertexArray(vao);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ if (enableFeedback) gl.beginTransformFeedback(gl.POINTS);
+ let error = gl.getError();
+ if (error != gl.NO_ERROR) testFailed("Unexpected error before drawing: " + error)
+ drawFunction();
+ if (enableFeedback) gl.endTransformFeedback();
+ gl.bindVertexArray(null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+}
+
+function createBuffer(gl, dataOrSize) {
+ const buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, dataOrSize, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ return buf;
+}
+
+function createVAO(gl, vertexBuffer, vertexBuffer2, indexBuffer) {
+ const vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer2);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribDivisor(1, 2);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindVertexArray(null);
+ return vao;
+}
+
+const prog = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_value"], gl.SEPARATE_ATTRIBS,
+ ["in_value", "in_value2"]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+
+const vertexBuffer = createBuffer(gl, new Float32Array([1, 2, 3, 4]));
+const vertexBuffer2 = createBuffer(gl, new Float32Array([1, 2, 3, 4]));
+const vertexBuffer3 = createBuffer(gl, new Float32Array([1, 2, 3, 4]));
+
+const indexBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
+gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array([0, 1, 2, 3]), gl.STATIC_DRAW);
+
+const tfBuffer = createBuffer(gl, new Float32Array([0, 0, 0, 0]));
+
+const vao = createVAO(gl, vertexBuffer, vertexBuffer2, indexBuffer);
+// This tests that having a transform feedback buffer bound in an unbound VAO
+// does not affect anything.
+const unboundVao = createVAO(gl, tfBuffer, tfBuffer, indexBuffer);
+
+const tf = gl.createTransformFeedback();
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+gl.useProgram(prog);
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer);
+// this binds the default (id = 0) TRANSFORM_FEEBACK buffer
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+
+const uniformBuffer = createBuffer(gl, new Float32Array([1, 0, 0, 0]));
+const ubi = gl.getUniformBlockIndex(prog, "UniformBlock");
+gl.uniformBlockBinding(prog, ubi, 0);
+gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uniformBuffer);
+
+const drawFunctions = [
+ [
+ ()=>gl.drawArrays(gl.POINTS, 0, 4),
+ ()=>gl.drawElements(gl.POINTS, 4, gl.UNSIGNED_SHORT, 0),
+ ],
+ [
+ ()=>gl.drawArraysInstanced(gl.POINTS, 0, 4, 1),
+ ()=>gl.drawElementsInstanced(gl.POINTS, 4, gl.UNSIGNED_SHORT, 0, 1),
+ ],
+ [
+ ()=>gl.drawArrays(gl.POINTS, 0, 4),
+ ()=>gl.drawRangeElements(gl.POINTS, 0, 3, 4, gl.UNSIGNED_SHORT, 0),
+ ],
+ ];
+
+for (let [drawArrays, drawElements] of drawFunctions) {
+ debug("<h3>With draw functions " + drawArrays + " and " + drawElements + "</h3>");
+ debug("<hr/>Test baseline");
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 16, gl.STATIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bufferData to TRANSFORM_FEEDBACK_BUFFER");
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements should be successful");
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "transform feedback should be successful");
+
+ const expected = [2, 4, 6, 8];
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected);
+
+ debug("<hr/>Test generic bind point set to null");
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null);
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements should be successful");
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "transform feedback should be successful");
+
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected);
+
+ debug("<hr/>Test generic bind point set to vertex buffer");
+ // The TRANSFORM_FEEDBACK_BUFFER generic binding point is not part of the
+ // transform feedback object and not written to by transform feedback. Only
+ // the indexed binding points are written to. So it should be legal to draw
+ // from a buffer bound to the generic binding point.
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, vertexBuffer);
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements should be successful");
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "transform feedback should be successful");
+
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected);
+
+ debug("<hr/>Test ARRAY_BUFFER");
+ // this should fail because the transform feedback's buffer #0 and the
+ // badVao's buffer #0 are the same buffer
+ const badVao = createVAO(gl, tfBuffer, vertexBuffer2, indexBuffer);
+ drawWithFeedbackBound(gl, drawArrays, prog, badVao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArrays: buffer used as vertex attrib and tf simultaneously");
+ drawWithFeedbackBound(gl, drawElements, prog, badVao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElements: buffer used as vertex attrib and tf simultaneously");
+ drawWithFeedbackBound(gl, drawArrays, prog, badVao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer used as vertex attrib and tf simultaneously");
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected, "should be the same as before as nothing has executed");
+
+ debug("<hr/>Test UNIFORM_BUFFER");
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, tfBuffer);
+ gl.bindBuffer(gl.UNIFORM_BUFFER, null); // tfBuffer is still bound at index 0
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawArrays: buffer used as uniform buffer and tf simultaneously");
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "drawElements: buffer used as uniform buffer and tf simultaneously");
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "buffer used as uniform buffer and tf simultaneously");
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uniformBuffer);
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays: tf buffer not used as uniform buffer anymore");
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements: tf buffer not used as uniform buffer anymore");
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "tf buffer not used as uniform buffer anymore");
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ const tfBuffer2 = createBuffer(gl, Float32Array.BYTES_PER_ELEMENT * 4);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer2);
+ drawWithFeedbackBound(gl, drawArrays, prog, badVao, tf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "buffer is no longer bound for transform feedback");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer);
+
+ debug("<hr/>Test TF buffer bound to target unused by draw");
+ // Even if the TF buffer is bound to a target that's not used by the draw, it's
+ // still an error.
+ gl.bindBuffer(gl.COPY_READ_BUFFER, tfBuffer);
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, true);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "tf enabled");
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArrays: tf disabled");
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElements: tf disabled");
+ gl.bindBuffer(gl.COPY_READ_BUFFER, null);
+
+ debug("<hr/>Test TF buffer bound to disabled vertex attrib");
+ // Having a TF buffer bound to a disabled vertex attrib should not be an error
+ // when TF is not enabled, because the buffer is not used.
+ gl.bindVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, tfBuffer);
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, 0, 0);
+ gl.disableVertexAttribArray(2);
+ gl.bindVertexArray(null);
+ drawWithFeedbackBound(gl, drawArrays, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "tf disabled, draw should succeed");
+ drawWithFeedbackBound(gl, drawElements, prog, vao, tf, false);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "tf disabled, draw should succeed");
+ // Remove the TF buffer binding from the VAO after the test.
+ gl.bindVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer3);
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, 0, 0);
+ gl.disableVertexAttribArray(2);
+ gl.bindVertexArray(null);
+}
+
+debug("<h1>Non-drawing tests</h1>");
+
+debug("<hr/>Test bufferData");
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 16, gl.STATIC_DRAW);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bufferData to TRANSFORM_FEEDBACK_BUFFER");
+gl.bindBuffer(gl.COPY_WRITE_BUFFER, tfBuffer);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 16, gl.STATIC_DRAW);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "bufferData with double bound buffer");
+gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
+
+// The value of the TRANSFORM_FEEDBACK_BUFFER generic bind point should not
+// affect the legality of any operation.
+let genericBindPointValues = [()=>null, ()=>tfBuffer, ()=>vertexBuffer];
+
+for (let genericBindPointValue of genericBindPointValues) {
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ debug("<h3>With TRANSFORM_FEEDBACK_BUFFER generic bind point value " + genericBindPointValue + "</h3>");
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, genericBindPointValue());
+
+ debug("<hr/>Test PIXEL_UNPACK_BUFFER");
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, vertexBuffer);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "PIXEL_UNPACK_BUFFER is not bound for transform feedback");
+
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, tfBuffer);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "PIXEL_UNPACK_BUFFER is bound for transform feedback");
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+
+ debug("<hr/>Test PIXEL_PACK_BUFFER");
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, vertexBuffer);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "PIXEL_PACK_BUFFER is not bound for transform feedback");
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, tfBuffer);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "PIXEL_PACK_BUFFER is bound for transform feedback");
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null)
+
+ debug("<hr/>Test bufferData family with tf object bound");
+
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, tfBuffer);
+ gl.bufferData(gl.COPY_WRITE_BUFFER, 16, gl.STATIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "bufferData with double bound buffer");
+ gl.bufferSubData(gl.COPY_WRITE_BUFFER, 0, new Uint8Array([0]));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "bufferSubData with double bound buffer");
+ gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, new Uint8Array([0]), 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "getBufferSubData with double bound buffer");
+
+ gl.bindBuffer(gl.COPY_READ_BUFFER, vertexBuffer);
+ gl.copyBufferSubData(gl.COPY_WRITE_BUFFER, gl.COPY_READ_BUFFER, 0, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "copyBufferSubData with double bound buffer");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "copyBufferSubData with double bound buffer");
+
+ debug("<hr/>Test bufferData family with tf object unbound");
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, tfBuffer);
+ gl.bufferData(gl.COPY_WRITE_BUFFER, 16, gl.STATIC_DRAW);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bufferData should succeed");
+ gl.bufferSubData(gl.COPY_WRITE_BUFFER, 0, new Uint8Array([0]));
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bufferSubData should succeed");
+ gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, new Uint8Array([0]), 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getBufferSubData should succeed");
+
+ gl.bindBuffer(gl.COPY_READ_BUFFER, vertexBuffer);
+ gl.copyBufferSubData(gl.COPY_WRITE_BUFFER, gl.COPY_READ_BUFFER, 0, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copyBufferSubData should succeed");
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 1);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copyBufferSubData should succeed");
+}
+
+finishTest();
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/switching-objects.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/switching-objects.html
new file mode 100644
index 0000000000..fce82dd21f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/switching-objects.html
@@ -0,0 +1,231 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Switching transform feedback objects</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in float in_value;
+out float out_value1;
+out float out_value2;
+
+void main() {
+ out_value1 = in_value * 2.;
+ out_value2 = in_value * 4.;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 dummy;
+void main() {
+ dummy = vec4(0.);
+}
+</script>
+<script>
+"use strict";
+description("Tests switching transform feedback objects.");
+
+debug("<h3>Setup</h3>")
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+if (!gl) {
+ testFailed("WebGL context does not exist");
+}
+
+// Setup
+const prog_interleaved = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_value1", "out_value2"], gl.INTERLEAVED_ATTRIBS,
+ ["in_value"]);
+const prog_no_varyings = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ [], gl.INTERLEAVED_ATTRIBS,
+ ["in_value"]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "shader compilation");
+const vertexBuffer = createBuffer(gl, new Float32Array([1, 2, 3, 4]));
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
+gl.enableVertexAttribArray(0);
+gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+gl.useProgram(prog_interleaved);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "vertex buffer and program setup");
+
+const tf1 = gl.createTransformFeedback();
+const tf2 = gl.createTransformFeedback();
+const tfBuffer1 = createBuffer(gl, new Float32Array([0, 0]));
+const tfBuffer2 = createBuffer(gl, new Float32Array([0, 0]));
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer1);
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf2);
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer2);
+const expected_tf_output = [2, 4];
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "TF object setup");
+
+debug("<h3>Baseline transform feedback success case</h3>");
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+gl.beginTransformFeedback(gl.POINTS);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "begin TF");
+gl.drawArrays(gl.POINTS, 0, 1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "draw");
+gl.endTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "end TF");
+
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected_tf_output);
+
+debug("<h3>Generic binding is not changed when switching TF object</h3>");
+
+// According to the GL ES spec historically, TRANSFORM_FEEDBACK_BUFFER_BINDING is listed as part
+// of the transform feedback object state. However, many drivers treat it as global context state
+// and not part of the tranform feedback object, which means that it does not change when
+// bindTransformFeedback is called. Khronos has resolved to change the spec to specify the latter
+// behavior: https://gitlab.khronos.org/opengl/API/issues/66 (Khronos private link). This tests
+// for the new behavior.
+
+// Set each buffer to contain its buffer number. We use this to check which
+// buffer is *really* bound at the driver level by reading the buffer contents.
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array([1]), gl.STREAM_READ);
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer2);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array([2]), gl.STREAM_READ);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bufferData");
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+checkParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, tfBuffer2);
+checkIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, tfBuffer1);
+wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [2]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readback");
+
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null);
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf2);
+checkParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, null);
+checkIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, tfBuffer2);
+
+debug("<h3>Error switching TF object while TF is enabled</h3>");
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array([0, 0]), gl.STREAM_READ);
+gl.beginTransformFeedback(gl.POINTS);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "begin");
+checkParameter(gl.TRANSFORM_FEEDBACK_BINDING, tf1);
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf2);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "bind while unpaused");
+
+// Check that nothing actually changed and rendering still works
+checkParameter(gl.TRANSFORM_FEEDBACK_BINDING, tf1);
+gl.drawArrays(gl.POINTS, 0, 1);
+gl.endTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "transform feedback should complete successfully");
+wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected_tf_output);
+
+
+debug("<h3>Successfully switching TF object while TF is paused</h3>");
+
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array([0, 0]), gl.STREAM_READ);
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer2);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array([0, 0]), gl.STREAM_READ);
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf2);
+gl.beginTransformFeedback(gl.POINTS);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "begin on tf2");
+checkParameter(gl.TRANSFORM_FEEDBACK_BINDING, tf2);
+
+gl.pauseTransformFeedback();
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bind while paused");
+gl.beginTransformFeedback(gl.POINTS);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "begin on tf1");
+checkParameter(gl.TRANSFORM_FEEDBACK_BINDING, tf1);
+gl.drawArrays(gl.POINTS, 0, 1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "draw should succeed");
+gl.endTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "end on tf1");
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected_tf_output);
+
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf2);
+gl.endTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "end on tf2");
+
+debug("<h3>Misc. invalid operations</h3>")
+
+gl.endTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "endTransformFeedback before begin");
+gl.pauseTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "pauseTransformFeedback when not active");
+gl.resumeTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "pauseTransformFeedback when not active");
+
+gl.beginTransformFeedback(gl.POINTS);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "transform feedback should begin successfully");
+gl.drawArrays(gl.TRIANGLE_STRIP, 0, 1);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "wrong primitive mode");
+gl.useProgram(prog_no_varyings);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "switch program while active");
+gl.resumeTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "resumeTransformFeedback when not paused");
+gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf2);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "bindTransformFeedback when active");
+gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer2);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "bindBuffer(TRANSFORM_FEEDBACK_BUFFER) when active");
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer2);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "bindBufferBase(TRANSFORM_FEEDBACK_BUFFER) when active");
+
+gl.pauseTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "pause");
+gl.pauseTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "already paused");
+gl.endTransformFeedback();
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "end while paused");
+
+finishTest();
+
+// Helper functions
+function createBuffer(gl, dataOrSize) {
+ const buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, dataOrSize, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ return buf;
+}
+
+function checkParameter(param, expected) {
+ const value = gl.getParameter(param);
+ if (value != expected) {
+ testFailed(wtu.glEnumToString(gl, param) + " was " + value + ", but expected " + expected);
+ } else {
+ testPassed(wtu.glEnumToString(gl, param) + " was " + value + ", matching expected " + expected);
+ }
+}
+
+function checkIndexedParameter(param, index, expected) {
+ const value = gl.getIndexedParameter(param, index);
+ if (value != expected) {
+ testFailed(wtu.glEnumToString(gl, param) + "[" + index + "] was " + value + ", but expected " + expected);
+ } else {
+ testPassed(wtu.glEnumToString(gl, param) + "[" + index + "] was " + value + ", matching expected " + expected);
+ }
+}
+
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/too-small-buffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/too-small-buffers.html
new file mode 100644
index 0000000000..64acfbad7b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/too-small-buffers.html
@@ -0,0 +1,242 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>TF too small buffers</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in float in_value1;
+in float in_value2;
+out float out_value1;
+out float out_value2;
+void main() {
+ out_value1 = in_value1 * 2.;
+ out_value2 = in_value2 * 2.;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 dummy;
+void main() {
+ dummy = vec4(0.);
+}
+</script>
+<script>
+"use strict";
+description("Transform feedback into buffers that are too small should produce errors.");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+}
+
+const progInterleaved = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_value1", "out_value2"], gl.INTERLEAVED_ATTRIBS,
+ ["in_value1", "in_value2"]);
+const progSeparate = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_value1", "out_value2"], gl.SEPARATE_ATTRIBS,
+ ["in_value1", "in_value2"]);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "program compilation");
+
+// Attrib 1 contains 4 vertices. Attrib 2 contains 4 instance indices.
+const vertexBuffer0 = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
+const vertexBuffer1 = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
+gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
+gl.enableVertexAttribArray(0);
+gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
+gl.enableVertexAttribArray(1);
+gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
+gl.vertexAttribDivisor(1, 1);
+
+let tfBuffer0 = gl.createBuffer();
+let tfBuffer1 = gl.createBuffer();
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup");
+
+const sizeOfFloat = 4;
+
+let cases = [
+ { name: "drawArrays",
+ drawFunction: ()=>gl.drawArrays(gl.POINTS, 0, 4),
+ result: [[2, 4, 6, 8], [2, 2, 2, 2]]},
+ { name: "drawArraysInstanced one instance",
+ drawFunction: ()=>gl.drawArraysInstanced(gl.POINTS, 0, 4, 1),
+ result: [[2, 4, 6, 8], [2, 2, 2, 2]]},
+ { name: "drawArraysInstanced four instances",
+ drawFunction: ()=>gl.drawArraysInstanced(gl.POINTS, 0, 1, 4),
+ result: [[2, 2, 2, 2], [2, 4, 6, 8]]},
+ ];
+
+for (let {name, drawFunction, result} of cases) {
+ debug("<h1>" + name + "</h1>")
+
+ let interleavedResult = [];
+ for (let i = 0; i < result[0].length; i++) {
+ interleavedResult.push(result[0][i], result[1][i]);
+ }
+
+ let doTransformFeedback = (drawFunction, error) => {
+ gl.beginTransformFeedback(gl.POINTS);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "before draw");
+ drawFunction();
+ wtu.glErrorShouldBe(gl, error, "draw");
+ gl.endTransformFeedback();
+ }
+
+ gl.useProgram(progInterleaved);
+
+ debug("<h3>interleaved - Baseline success case</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat, gl.STREAM_READ);
+ doTransformFeedback(drawFunction, gl.NO_ERROR);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult);
+
+ debug("<h3>interleaved - Buffer too small</h3>")
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat-1, gl.STREAM_READ);
+ doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
+ [0, 0, 0, 0, 0, 0, 0]);
+
+ debug("<h3>interleaved - Multiple draws success case</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat*2, gl.STREAM_READ);
+ doTransformFeedback(()=>{drawFunction(); drawFunction()}, gl.NO_ERROR);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult.concat(interleavedResult))
+
+ debug("<h3>interleaved - Too small for multiple draws</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat*2-1, gl.STREAM_READ);
+ doTransformFeedback(()=>{drawFunction(); drawFunction()}, gl.INVALID_OPERATION);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, interleavedResult.concat([0, 0, 0, 0, 0, 0, 0]))
+
+ debug("<h3>interleaved - bindBufferRange too small</h3>")
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat, gl.STREAM_READ);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0, 0, 7*sizeOfFloat);
+ doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
+ [0, 0, 0, 0, 0, 0, 0, 0]);
+
+ debug("<h3>interleaved - bindBufferRange larger than buffer</h3>")
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 8*sizeOfFloat-1, gl.STREAM_READ);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0, 0, 8*sizeOfFloat);
+ doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER,
+ [0, 0, 0, 0, 0, 0, 0]);
+
+ gl.useProgram(progSeparate);
+
+ debug("<h3>separate - Baseline success case</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
+ doTransformFeedback(drawFunction, gl.NO_ERROR);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1]);
+
+ debug("<h3>separate - Buffer too small</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat-1, gl.STREAM_READ);
+ doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
+
+ debug("<h3>separate - multiple draws success case</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
+ doTransformFeedback(()=>{drawFunction(); drawFunction();}, gl.NO_ERROR);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0].concat(result[0]));
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1].concat(result[1]));
+
+ debug("<h3>separate - Too small for multiple draws</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2, gl.STREAM_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat*2-1, gl.STREAM_READ);
+ doTransformFeedback(()=>{drawFunction(); drawFunction();}, gl.INVALID_OPERATION);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[0].concat([0, 0, 0, 0]));
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, result[1].concat([0, 0, 0]));
+
+ debug("<h3>separate - bindBufferRange too small</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1, 0, 3*sizeOfFloat);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
+ doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
+
+ debug("<h3>separate - bindBufferRange larger than buffer</h3>")
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat, gl.STREAM_READ);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, tfBuffer1, 0, 4*sizeOfFloat);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*sizeOfFloat-1, gl.STREAM_READ);
+ doTransformFeedback(drawFunction, gl.INVALID_OPERATION);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer0);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0, 0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, tfBuffer1);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, [0, 0, 0]);
+}
+
+debug("<h1>integer overflow</h1>")
+
+gl.useProgram(progInterleaved);
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer0);
+gl.bufferData(gl.ARRAY_BUFFER, (1<<16)*sizeOfFloat, gl.STREAM_READ);
+gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer1);
+gl.bufferData(gl.ARRAY_BUFFER, (1<<16)*sizeOfFloat, gl.STREAM_READ);
+gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer0);
+gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, (1<<16)*sizeOfFloat*2, gl.STREAM_READ);
+
+gl.beginTransformFeedback(gl.POINTS);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "before draw");
+// If count and primcount are stored in 32-bit signed integers and then
+// multiplied to calculate the number of transform feedback vertices, the
+// calculation will overflow to 0.
+gl.drawArraysInstanced(gl.POINTS, 0, 1<<16, 1<<16);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "integer overflow and/or buffer too small");
+gl.endTransformFeedback();
+
+finishTest();
+
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/transform_feedback.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/transform_feedback.html
new file mode 100644
index 0000000000..20256c6ace
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/transform_feedback.html
@@ -0,0 +1,645 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Transform Feedback Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+
+in vec4 in_data;
+out vec4 out_add;
+out vec4 out_mul;
+void main(void) {
+ out_add = in_data + vec4(2.0, 3.0, 4.0, 5.0);
+ out_mul = in_data * vec4(2.0, 3.0, 4.0, 5.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 out_color;
+void main(void) {
+ out_color = vec4(1.0, 1.0, 1.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the functionality of the Transform Feedback objects.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var tf = null;
+var tf1 = null;
+var buf = null;
+let out_add_buffer = null;
+var program = null;
+var activeInfo = null;
+var query = null;
+var numberOfQueryCompletionAttempts = 0;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runBindingTest();
+ runTFBufferBindingTest();
+ runObjectTest();
+ runGetBufferSubDataTest();
+ runUnboundDeleteTest();
+ runBoundDeleteTest();
+ runOneOutputFeedbackTest();
+ // Must be the last test, since it's asynchronous and calls finishTest().
+ runTwoOutputFeedbackTest();
+}
+
+function runBindingTest() {
+ debug("");
+ debug("Testing binding enum");
+
+ shouldBe("gl.TRANSFORM_FEEDBACK_BINDING", "0x8E25");
+
+ gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "TRANSFORM_FEEDBACK_BINDING query should succeed");
+
+ // Default value is null
+ shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)", "null");
+
+ debug("Testing binding a Transform Feedback object");
+ tf = gl.createTransformFeedback();
+ tf1 = gl.createTransformFeedback();
+ shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)", "tf");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+ shouldBe("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)", "tf1");
+ gl.deleteTransformFeedback(tf);
+ gl.deleteTransformFeedback(tf1);
+ shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted Transform Feedback object");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ shouldBeNull("gl.getParameter(gl.TRANSFORM_FEEDBACK_BINDING)");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runTFBufferBindingTest() {
+ debug("");
+ debug("Testing binding and unbinding transform feedback objects and buffers");
+
+ buf = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 16, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null);
+
+ tf = gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+
+ // gl.TRANSFORM_FEEDBACK_BUFFER is part of Transform Feedback objects'
+ // state. See OpenGL ES 3.0.5 Section 6.24.
+ //
+ // Since the TRANSFORM_FEEDBACK was just unbound, there should be nothing
+ // bound.
+ shouldBeNull('gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)');
+
+ // Binding the buffer to the ARRAY_BUFFER binding point should succeed.
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "binding buffer to ARRAY_BUFFER");
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(buf);
+ buf = null;
+ gl.deleteTransformFeedback(tf);
+ tf = null;
+}
+
+function runObjectTest() {
+ debug("");
+ debug("Testing object creation");
+
+ tf = gl.createTransformFeedback();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createTransformFeedback should not set an error");
+ shouldBeNonNull("tf");
+
+ // Expect false if never bound
+ shouldBeFalse("gl.isTransformFeedback(tf)");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ shouldBeTrue("gl.isTransformFeedback(tf)");
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ shouldBeTrue("gl.isTransformFeedback(tf)");
+ gl.deleteTransformFeedback(tf);
+ shouldBeFalse("gl.isTransformFeedback(tf)");
+
+ shouldBeFalse("gl.isTransformFeedback(null)");
+
+ tf = null;
+}
+
+function runOneOutputFeedbackTest() {
+ debug("");
+ debug("Testing one-output transform feedback");
+
+ // Build the input and output buffers
+ var in_data = [
+ 1.0, 2.0, 3.0, 4.0,
+ 2.0, 4.0, 8.0, 16.0,
+ 0.75, 0.5, 0.25, 0.0
+ ];
+
+ var in_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
+
+ out_add_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
+
+ // Create the transform feedback shader
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_add"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeNonNull("program");
+
+ // Draw the the transform feedback buffers
+ tf = gl.createTransformFeedback();
+
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.beginTransformFeedback(gl.POINTS);
+
+ debug("Testing switching program while transform feedback is active");
+ gl.pauseTransformFeedback();
+ var program2 = wtu.setupSimpleColorProgram(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Switching program while transform feedback is active and paused should succeed");
+ gl.useProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Switching program while transform feedback is active and paused should succeed");
+ gl.resumeTransformFeedback();
+ gl.useProgram(program2);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Switching program while transform feedback is active should fail");
+ shouldBe("gl.getParameter(gl.CURRENT_PROGRAM)", "program");
+
+ debug("Testing deleting an active transform feedback object");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors before testing deletion");
+ gl.deleteTransformFeedback(tf);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Deleting the transform feedback while active should fail, and have no effect");
+ shouldBe("gl.isTransformFeedback(tf)", "true");
+ debug("Resuming testing of single-output transform feedback");
+
+ gl.drawArrays(gl.POINTS, 0, 3);
+
+ gl.endTransformFeedback();
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+
+ // Verify the output buffer contents
+ var add_expected = [
+ 3.0, 5.0, 7.0, 9.0,
+ 4.0, 7.0, 12.0, 21.0,
+ 2.75, 3.5, 4.25, 5.0
+ ];
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, add_expected);
+
+ gl.deleteBuffer(in_buffer);
+ gl.deleteBuffer(out_add_buffer);
+ gl.deleteProgram(program);
+ gl.deleteTransformFeedback(tf);
+
+ tf = null;
+ program = null;
+}
+
+function runTwoOutputFeedbackTest() {
+ debug("");
+ debug("Testing two-output transform feedback");
+
+ // Build the input and output buffers
+ var in_data = [
+ 1.0, 2.0, 3.0, 4.0,
+ 2.0, 4.0, 8.0, 16.0,
+ 0.75, 0.5, 0.25, 0.0
+ ];
+
+ var in_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
+
+ out_add_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
+
+ var out_mul_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_mul_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
+
+ // Create the transform feedback shader
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_add", "out_mul"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeNonNull("program");
+
+ // Create a query object to check the number of primitives written
+ query = gl.createQuery();
+
+ // Draw the the transform feedback buffers
+ tf = gl.createTransformFeedback();
+
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_mul_buffer);
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.beginTransformFeedback(gl.POINTS);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
+
+ gl.drawArrays(gl.POINTS, 0, 3);
+
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ gl.endTransformFeedback();
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null);
+
+ // Verify the output buffer contents
+ var add_expected = [
+ 3.0, 5.0, 7.0, 9.0,
+ 4.0, 7.0, 12.0, 21.0,
+ 2.75, 3.5, 4.25, 5.0
+ ];
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, add_expected);
+
+ var mul_expected = [
+ 2.0, 6.0, 12.0, 20.0,
+ 4.0, 12.0, 32.0, 80.0,
+ 1.5, 1.5, 1.0, 0.0
+ ];
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_mul_buffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, mul_expected);
+
+ gl.deleteBuffer(in_buffer);
+ gl.deleteBuffer(out_add_buffer);
+ gl.deleteBuffer(out_mul_buffer);
+ gl.deleteProgram(program);
+ gl.deleteTransformFeedback(tf);
+
+ tf = null;
+ program = null;
+
+ // Check the result of the query. It should not be available yet.
+ // This constant was chosen arbitrarily to take around 1 second on
+ // one WebGL implementation on one desktop operating system. (Busy-
+ // loops based on calling Date.now() have been found unreliable.)
+ var numEarlyTests = 50000;
+ while (--numEarlyTests > 0) {
+ gl.finish();
+ if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) {
+ testFailed("Query's result became available too early");
+ finishTest();
+ return;
+ }
+ }
+ testPassed("TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query's result didn't become available too early");
+
+ // Complete the rest of the test asynchronously.
+ requestAnimationFrame(completeTransformFeedbackQueryTest);
+}
+
+function runUnboundDeleteTest() {
+ debug("");
+ debug("Testing deleting buffers attached to an unbound transform feedback object");
+
+ // Theoretically it would be possible to verify the result of performing
+ // transform feedback into a deleted buffer object. The buffer would have to
+ // be latched into a VAO as well as into the transform feedback object. In
+ // order to get the results out of the output buffer, it would be necessary
+ // to run transform feedback again, reading from the buffer bound to the
+ // VAO, and writing into a (non-deleted) buffer object latched into the
+ // transform feedback object. It's not possible to arrange things to be able
+ // to copyBufferSubData from the deleted buffer object into a temporary one
+ // for readback.
+
+ // This would be a lot of code to test an unlikely corner case, so instead,
+ // this test verifies simpler behaviors.
+
+ out_add_buffer = gl.createBuffer();
+ const output_buffer_length = Float32Array.BYTES_PER_ELEMENT * 16;
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, output_buffer_length, gl.STATIC_DRAW);
+
+ // Set up the transform feedback object
+ tf = gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
+
+ // Unbind transform feedback and delete out_add_buffer.
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ gl.deleteBuffer(out_add_buffer);
+ debug("isBuffer should report false after deletion");
+ shouldBe("gl.isBuffer(out_add_buffer)", "false");
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ debug("Transform feedback object should keep output buffer alive");
+ shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "out_add_buffer");
+ // Deleting the buffer again while the transform feedback is bound shouldn't unbind it.
+ gl.deleteBuffer(out_add_buffer);
+ debug("Deleting output buffer again should be a no-op");
+ shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "out_add_buffer");
+
+ // Try unbinding and rebinding the transform feedback object just
+ // to make sure that has no effect on the attached output buffer.
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ debug("Transform feedback object should still keep output buffer alive");
+ shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "out_add_buffer");
+
+ gl.deleteTransformFeedback(tf);
+
+ tf = null;
+ out_add_buffer = null;
+}
+
+function runBoundDeleteTest() {
+ debug("");
+ debug("Testing deleting buffers attached to a bound transform feedback object");
+
+ out_add_buffer = gl.createBuffer();
+ const output_buffer_length = Float32Array.BYTES_PER_ELEMENT * 16;
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, output_buffer_length, gl.STATIC_DRAW);
+
+ // Set up the transform feedback object
+ tf = gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
+
+ // Delete the output buffer
+ gl.deleteBuffer(out_add_buffer);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ debug("Buffer should have been unbound from active transform feedback");
+ shouldBeNull("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)");
+
+ gl.deleteTransformFeedback(tf);
+
+ tf = null;
+ out_add_buffer = null;
+}
+
+var retArray;
+
+function verifyGetBufferSubData(expected) {
+ wtu.shouldGenerateGLError(gl, expected, "gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, retArray, 0, retArray.length)");
+}
+
+function runGetBufferSubDataTest() {
+ debug("");
+ debug("Test that getBufferSubData...");
+
+ // Build the input and output buffers
+ var in_data = [
+ 1.0, 2.0, 3.0, 4.0,
+ 2.0, 4.0, 8.0, 16.0,
+ 0.75, 0.5, 0.25, 0.0
+ ];
+
+ retArray = new Float32Array(in_data.length);
+
+ var in_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
+
+ out_add_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
+
+ // Create the transform feedback shader
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_add"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeNonNull("program");
+
+ // Draw the the transform feedback buffers
+ tf = gl.createTransformFeedback();
+
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+
+ debug("... passes when a transform feedback object is not bound");
+ verifyGetBufferSubData(gl.NO_ERROR);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
+
+ debug("... passes when a transform feedback object is bound but not active");
+ verifyGetBufferSubData(gl.NO_ERROR);
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.beginTransformFeedback(gl.POINTS);
+
+ debug("... fails when a transform feedback object is active");
+ verifyGetBufferSubData(gl.INVALID_OPERATION);
+
+ gl.drawArrays(gl.POINTS, 0, 3);
+
+ gl.endTransformFeedback();
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+
+ // Verify the output buffer contents
+ var add_expected = [
+ 3.0, 5.0, 7.0, 9.0,
+ 4.0, 7.0, 12.0, 21.0,
+ 2.75, 3.5, 4.25, 5.0
+ ];
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, add_expected);
+
+ tf = null;
+ program = null;
+}
+
+function completeTransformFeedbackQueryTest() {
+ debug("");
+ debug("Testing TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query");
+
+ ++numberOfQueryCompletionAttempts;
+ if (numberOfQueryCompletionAttempts > 500) {
+ testFailed("Query didn't become available in a reasonable time");
+ finishTest();
+ return;
+ }
+
+ if (!gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) {
+ requestAnimationFrame(completeTransformFeedbackQueryTest);
+ return;
+ }
+
+ var result = gl.getQueryParameter(query, gl.QUERY_RESULT);
+ if (result == 3) {
+ testPassed("TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query returned a correct result (3)");
+ } else {
+ testFailed("TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query returned an incorrect result " + result + " (expected 3)");
+ }
+
+ runVaryingsTest();
+}
+
+function verifyTransformFeedbackVarying(prog, index, valid, name) {
+ activeInfo = gl.getTransformFeedbackVarying(prog, index);
+ if (valid) {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "Should be no errors from valid getTransformFeedbackVarying.");
+ shouldBeNonNull("activeInfo");
+ shouldBe("activeInfo.name", "'" + name + "'");
+ shouldBe("activeInfo.type", "gl.FLOAT_VEC4");
+ shouldBe("activeInfo.size", "1");
+ } else {
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "Should be INVALID_VALUE when calling getTransformFeedbackVarying with an invalid index.");
+ shouldBeNull("activeInfo");
+ }
+}
+
+function runVaryingsTest() {
+ debug("");
+ debug("Testing transform feedback varyings");
+
+ // Create the transform feedback shader. This is explicitly run after runTwoOutputFeedbackTest,
+ // as re-linking the shader here will test browser caching.
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_add", "out_mul"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeNonNull("program");
+
+ // Check the varyings
+ shouldBe("gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS)", "2");
+ verifyTransformFeedbackVarying(program, 0, true, "out_add");
+ verifyTransformFeedbackVarying(program, 1, true, "out_mul");
+ verifyTransformFeedbackVarying(program, 2, false);
+
+ // transformFeedbackVaryings() doesn't take effect until a successful link.
+ gl.transformFeedbackVaryings(program, ["out_mul"], gl.SEPARATE_ATTRIBS);
+ shouldBe("gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS)", "2");
+ verifyTransformFeedbackVarying(program, 0, true, "out_add");
+ verifyTransformFeedbackVarying(program, 1, true, "out_mul");
+ verifyTransformFeedbackVarying(program, 2, false);
+
+ // Now relink.
+ gl.linkProgram(program);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
+ shouldBe("gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS)", "1");
+ verifyTransformFeedbackVarying(program, 0, true, "out_mul");
+ verifyTransformFeedbackVarying(program, 1, false);
+ verifyTransformFeedbackVarying(program, 2, false);
+
+ // Test recompiling/relinking the program
+ // Regression test for http://crbug.com/716018
+ var skipCompileStatus = true;
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_add", "out_mul"], gl.SEPARATE_ATTRIBS,
+ ["in_data"], undefined, undefined, skipCompileStatus);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
+ shouldBe("gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS)", "2");
+ verifyTransformFeedbackVarying(program, 0, true, "out_add");
+ verifyTransformFeedbackVarying(program, 1, true, "out_mul");
+ verifyTransformFeedbackVarying(program, 2, false);
+
+ runContextLostOneOutputFeedbackTest();
+}
+
+function runContextLostOneOutputFeedbackTest() {
+ var ext = gl.getExtension("WEBGL_lose_context");
+ if (!ext) {
+ debug("No WEBGL_lose_context support");
+ finishTest();
+ return;
+ }
+ debug("");
+ debug("Testing switching program after context lost while transform feedback is active");
+
+ var in_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(12), gl.STATIC_DRAW);
+
+ out_add_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * 12, gl.STATIC_DRAW);
+
+ // Create an extra program to try switching to
+ var program2 = wtu.setupSimpleColorProgram(gl);
+
+ // Create the transform feedback shader
+ program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_add"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
+ shouldBeNonNull("program");
+
+ // Draw the the transform feedback buffers
+ tf = gl.createTransformFeedback();
+
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
+
+ gl.beginTransformFeedback(gl.POINTS);
+
+ debug("Calling loseContext()");
+ ext.loseContext();
+ shouldBeTrue("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ debug("Trying to switch program");
+ gl.useProgram(program2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No transform feedback error generated on lost context");
+ finishTest();
+}
+
+debug("");
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/two-unreferenced-varyings.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/two-unreferenced-varyings.html
new file mode 100644
index 0000000000..2173fd35ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/two-unreferenced-varyings.html
@@ -0,0 +1,136 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Transform Feedback Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec3 position;
+out vec3 outAttrib1;
+out vec3 outAttrib2;
+void main()
+{
+ outAttrib1 = position;
+ outAttrib2 = position;
+ gl_Position = vec4(position, 1);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 color;
+in vec3 outAttrib1;
+in vec3 outAttrib2;
+void main()
+{
+ color = vec4(0);
+}
+</script>
+<script>
+"use strict";
+description("This test covers an ANGLE bug with two transform feedback varyings. When the two are declared, but not referenced in the fragment shader, ANGLE would fail capture.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var quadVB;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("");
+ debug("Testing transform feedback with two unreferenced outputs");
+ runTest();
+}
+
+function getQuadVerts(depth) {
+ var quadVerts = new Float32Array(3 * 6);
+ quadVerts[0] = -1.0; quadVerts[1] = 1.0; quadVerts[2] = depth;
+ quadVerts[3] = -1.0; quadVerts[4] = -1.0; quadVerts[5] = depth;
+ quadVerts[6] = 1.0; quadVerts[7] = -1.0; quadVerts[8] = depth;
+ quadVerts[9] = -1.0; quadVerts[10] = 1.0; quadVerts[11] = depth;
+ quadVerts[12] = 1.0; quadVerts[13] = -1.0; quadVerts[14] = depth;
+ quadVerts[15] = 1.0; quadVerts[16] = 1.0; quadVerts[17] = depth;
+ return quadVerts;
+}
+
+function drawQuad(depth) {
+ if (!quadVB) {
+ quadVB = gl.createBuffer()
+ }
+
+ var quadVerts = getQuadVerts(depth);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, quadVB);
+ gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+}
+
+function runTest() {
+
+ // Create the transform feedback program
+ var program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["outAttrib1", "outAttrib2"], gl.INTERLEAVED_ATTRIBS,
+ ["position"]);
+ if (!program) {
+ testFailed("Fail to set up the program");
+ return;
+ }
+
+ // Init transform feedback buffers
+ var out_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * 3 * 2 * 6,
+ gl.STREAM_DRAW);
+
+ var tf = gl.createTransformFeedback();
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Init transform feedback should succeed");
+
+ // Draw the quad
+ gl.useProgram(program)
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ drawQuad(0.5);
+ gl.endTransformFeedback();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Draw with transform feedback should succeed");
+
+ // Verify the output buffer contents
+ var quadVerts = getQuadVerts(0.5);
+ var expected_data = [];
+ for (var i = 0; i < quadVerts.length; i += 3) {
+ for (var count = 0; count < 2; count++) {
+ expected_data[expected_data.length] = quadVerts[i];
+ expected_data[expected_data.length] = quadVerts[i+1];
+ expected_data[expected_data.length] = quadVerts[i+2];
+ }
+ }
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected_data);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html
new file mode 100644
index 0000000000..615ab9bab1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html
@@ -0,0 +1,133 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Transform Feedback Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 in_data;
+uniform int flag;
+out vec4 out_data;
+void main(void) {
+ if (flag > 0) {
+ out_data = in_data + vec4(2.0, 3.0, 4.0, 5.0);
+ }
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+out vec4 out_color;
+void main(void) {
+ out_color = vec4(1.0, 1.0, 1.0, 1.0);
+}
+</script>
+<script>
+"use strict";
+description("This test verifies if an output variable is specified to be streamed to a transform feedback buffer but not actually written, the value defaults to 0.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ debug("");
+ debug("Testing transform feedback works fine");
+ runTest(1);
+
+ debug("");
+ debug("Testing unwritten output variables default to zero");
+ runTest(0);
+}
+
+function runTest(flag) {
+ var in_data = [
+ 1.0, 2.0, 3.0, 4.0,
+ 2.0, 4.0, 8.0, 16.0,
+ 0.75, 0.5, 0.25, 0.0
+ ];
+
+ var in_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
+
+ var out_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
+
+ // Create the transform feedback program
+ var program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
+ ["out_data"], gl.SEPARATE_ATTRIBS,
+ ["in_data"]);
+ var loc = gl.getUniformLocation(program, "flag");
+ if (!program || !loc) {
+ testFailed("Fail to set up the program");
+ return;
+ }
+ gl.uniform1i(loc, flag);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Set up program should succeed");
+
+ // Draw the the transform feedback buffers
+ var tf = gl.createTransformFeedback();
+
+ gl.enableVertexAttribArray(0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer);
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ gl.beginTransformFeedback(gl.POINTS);
+
+ gl.drawArrays(gl.POINTS, 0, 3);
+
+ gl.endTransformFeedback();
+ gl.disable(gl.RASTERIZER_DISCARD);
+
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+
+ // Verify the output buffer contents
+ var expected_data;
+ if (flag > 0) {
+ expected_data = [
+ 3.0, 5.0, 7.0, 9.0,
+ 4.0, 7.0, 12.0, 21.0,
+ 2.75, 3.5, 4.25, 5.0
+ ];
+ } else {
+ expected_data = [
+ 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0
+ ];
+ }
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer);
+ wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected_data);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/00_test_list.txt
new file mode 100644
index 0000000000..05e01f554c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/00_test_list.txt
@@ -0,0 +1,9 @@
+--min-version 2.0.1 draw-with-uniform-blocks.html
+--min-version 2.0.1 gl-uniform-arrays-sub-source.html
+--min-version 2.0.1 query-uniform-blocks-after-shader-detach.html
+--min-version 2.0.1 uniform-blocks-with-arrays.html
+--min-version 2.0.1 simple-buffer-change.html
+--min-version 2.0.1 dependent-buffer-change.html
+--min-version 2.0.1 incompatible-texture-type-for-sampler.html
+--min-version 2.0.1 large-uniform-buffers.html
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/dependent-buffer-change.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/dependent-buffer-change.html
new file mode 100644
index 0000000000..888305e6d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/dependent-buffer-change.html
@@ -0,0 +1,121 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL draw with uniform blocks conformance tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_vertex;
+void main(void) {
+ gl_Position = a_vertex;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+layout (std140) uniform color_ubo {
+ vec4 color;
+};
+out vec4 fragColor;
+void main(void) {
+ fragColor = color;
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="100", height="100"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+// Ported from: https://github.com/google/angle/blob/master/src/tests/gl_tests/UniformBufferTest.cpp#L1507
+description("Regression test for https://bugs.chromium.org/p/chromium/issues/detail?id=792966");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function runTest() {
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_vertex']);
+ var uboIndex = gl.INVALID_INDEX;
+ if (program)
+ uboIndex = gl.getUniformBlockIndex(program, "color_ubo");
+ if (!program || uboIndex == gl.INVALID_INDEX) {
+ testFailed("Loading program failed");
+ return;
+ }
+ testPassed("Loading program succeeded");
+
+ var vertices = new Float32Array([
+ -1, -1, 0,
+ 1, -1, 0,
+ -1, 1, 0,
+ 1, 1, 0
+ ]);
+ var vertexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var indexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array([ 0, 1, 2, 2, 1, 3 ]), gl.STATIC_DRAW);
+
+ var uboDataSize = gl.getActiveUniformBlockParameter(
+ program, uboIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ if (uboDataSize == 0) {
+ testFailed("uniform block data size invalid");
+ return;
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from setup");
+
+ debug("draw lower triangle - should be red");
+ var uboBuf1 = gl.createBuffer();
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uboBuf1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboDataSize, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([ 1, 0, 0, 1 ]));
+ gl.uniformBlockBinding(program, uboIndex, 0);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ // Resize the buffer - triggers a re-allocation in the D3D11 back-end.
+ debug("draw upper triangle - should be green");
+ var bigData = new Float32Array(128 * 4);
+ bigData.set([ 0, 1, 0, 1 ]);
+ gl.bufferData(gl.UNIFORM_BUFFER, bigData, gl.STATIC_DRAW);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ var width = 100, height = 100;
+ wtu.checkCanvasRectColor(gl, 0, 0, width/2-5, height/2-5, [255, 0, 0, 255], 2,
+ function() { testPassed("lower left should be red"); },
+ function() { testFailed("lower left should be red"); });
+ wtu.checkCanvasRectColor(gl, width/2+5, height/2+5, width/2-5, height/2-5, [0, 255, 0, 255], 2,
+ function() { testPassed("top right should be green"); },
+ function() { testFailed("top right should be green"); });
+}
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/draw-with-uniform-blocks.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/draw-with-uniform-blocks.html
new file mode 100644
index 0000000000..3fa7949eac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/draw-with-uniform-blocks.html
@@ -0,0 +1,120 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL draw with uniform blocks conformance tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_vertex;
+void main(void) {
+ gl_Position = a_vertex;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+layout (std140) uniform color_ubo {
+ vec4 color;
+};
+out vec4 fragColor;
+void main(void) {
+ fragColor = color;
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="100", height="100"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+description("Regression test for crbug.com/793307 and https://bugzilla.mozilla.org/show_bug.cgi?id=1424258");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function runTest() {
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_vertex']);
+ var uboIndex = gl.INVALID_INDEX;
+ if (program)
+ uboIndex = gl.getUniformBlockIndex(program, "color_ubo");
+ if (!program || uboIndex == gl.INVALID_INDEX) {
+ testFailed("Loading program failed");
+ return;
+ }
+ testPassed("Loading program succeeded");
+
+ var vertices = new Float32Array([
+ -1, -1, 0,
+ 1, -1, 0,
+ -1, 1, 0,
+ 1, 1, 0
+ ]);
+ var vertexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var indexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array([ 0, 1, 2, 2, 1, 3 ]), gl.STATIC_DRAW);
+
+ var uboDataSize = gl.getActiveUniformBlockParameter(
+ program, uboIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ if (uboDataSize == 0) {
+ testFailed("uniform block data size invalid");
+ return;
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from setup");
+
+ debug("draw lower triangle - should be red");
+ var uboBuf1 = gl.createBuffer();
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uboBuf1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboDataSize, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([ 1, 0, 0, 1 ]));
+ gl.uniformBlockBinding(program, uboIndex, 0);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ debug("draw upper triangle - should be green");
+ var uboBuf2 = gl.createBuffer();
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 1, uboBuf2);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboDataSize, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([ 0, 1, 0, 1 ]));
+ gl.uniformBlockBinding(program, uboIndex, 1);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ var width = 100, height = 100;
+ wtu.checkCanvasRectColor(gl, 0, 0, width/2-5, height/2-5, [255, 0, 0, 255], 2,
+ function() { testPassed("lower left should be red"); },
+ function() { testFailed("lower left should be red"); });
+ wtu.checkCanvasRectColor(gl, width/2+5, height/2+5, width/2-5, height/2-5, [0, 255, 0, 255], 2,
+ function() { testPassed("top right should be green"); },
+ function() { testFailed("top right should be green"); });
+}
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/gl-uniform-arrays-sub-source.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/gl-uniform-arrays-sub-source.html
new file mode 100644
index 0000000000..7780a7ba01
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/gl-uniform-arrays-sub-source.html
@@ -0,0 +1,404 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL uniform array Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="example" width="2" height="2"> </canvas>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_position;
+void main() {
+ gl_Position = a_position;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+uniform $(type) color[3];
+out vec4 myFragColor;
+void main() {
+ myFragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1);
+}
+</script>
+<script>
+"use strict";
+description();
+debug("");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+var vSrc = wtu.getScript("vshader");
+var fTemplate = wtu.getScript("fshader");
+
+// |color| is defined in fragment shader as an array of 3 elements.
+var uniformArraySize = 3;
+var initialUniformValue = 99;
+
+var typeInfos = [
+ { type: 'float',
+ setter: 'uniform1fv',
+ elem: '',
+ numElementsPerType: 1,
+ srcValues: [16, 15],
+ srcValuesWithOffset: [0, 0, 16, 15],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 0],
+ srcOffset: 2,
+ },
+ { type: 'int',
+ setter: 'uniform1iv',
+ elem: '',
+ numElementsPerType: 1,
+ srcValues: [16, 15],
+ srcValuesWithOffset: [0, 0, 16, 15],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 0],
+ srcOffset: 2,
+ },
+ { type: 'uint',
+ setter: 'uniform1uiv',
+ elem: '',
+ numElementsPerType: 1,
+ srcValues: [16, 15],
+ srcValuesWithOffset: [0, 0, 16, 15],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 0],
+ srcOffset: 2,
+ },
+ { type: 'vec2',
+ setter: 'uniform2fv',
+ elem: '[1]',
+ numElementsPerType: 2,
+ srcValues: [16, 15, 14, 13],
+ srcValuesWithOffset: [0, 16, 15, 14, 13],
+ srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 0],
+ srcOffset: 1,
+ },
+ { type: 'ivec2',
+ setter: 'uniform2iv',
+ elem: '[1]',
+ numElementsPerType: 2,
+ srcValues: [16, 15, 14, 13],
+ srcValuesWithOffset: [0, 16, 15, 14, 13],
+ srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 0],
+ srcOffset: 1,
+ },
+ { type: 'uvec2',
+ setter: 'uniform2uiv',
+ elem: '[1]',
+ numElementsPerType: 2,
+ srcValues: [16, 15, 14, 13],
+ srcValuesWithOffset: [0, 16, 15, 14, 13],
+ srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 0],
+ srcOffset: 1,
+ },
+ { type: 'vec3',
+ setter: 'uniform3fv',
+ elem: '[2]',
+ numElementsPerType: 3,
+ srcValues: [16, 15, 14, 13, 12, 11],
+ srcValuesWithOffset: [0, 16, 15, 14, 13, 12, 11],
+ srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 12, 11, 0, 0],
+ srcOffset: 1,
+ },
+ { type: 'ivec3',
+ setter: 'uniform3iv',
+ elem: '[2]',
+ numElementsPerType: 3,
+ srcValues: [16, 15, 14, 13, 12, 11],
+ srcValuesWithOffset: [0, 16, 15, 14, 13, 12, 11],
+ srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 12, 11, 0, 0],
+ srcOffset: 1,
+ },
+ { type: 'uvec3',
+ setter: 'uniform3uiv',
+ elem: '[2]',
+ numElementsPerType: 3,
+ srcValues: [16, 15, 14, 13, 12, 11],
+ srcValuesWithOffset: [0, 16, 15, 14, 13, 12, 11],
+ srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 12, 11, 0, 0],
+ srcOffset: 1,
+ },
+ { type: 'vec4',
+ setter: 'uniform4fv',
+ elem: '[3]',
+ numElementsPerType: 4,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0],
+ srcOffset: 3,
+ },
+ { type: 'ivec4',
+ setter: 'uniform4iv',
+ elem: '[3]',
+ numElementsPerType: 4,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0],
+ srcOffset: 3,
+ },
+ { type: 'uvec4',
+ setter: 'uniform4uiv',
+ elem: '[3]',
+ numElementsPerType: 4,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0],
+ srcOffset: 3,
+ },
+
+ // Matrix
+ { type: 'mat2',
+ setter: 'uniformMatrix2fv',
+ elem: '[1][1]',
+ numElementsPerType: 4,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0],
+ srcOffset: 3,
+ },
+ { type: 'mat3',
+ setter: 'uniformMatrix3fv',
+ elem: '[2][2]',
+ numElementsPerType: 9,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8],
+ srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 0],
+ srcOffset: 3,
+ },
+ { type: 'mat4',
+ setter: 'uniformMatrix4fv',
+ elem: '[3][3]',
+ numElementsPerType: 16,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+ srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0],
+ srcOffset: 2,
+ },
+ { type: 'mat2x3',
+ setter: 'uniformMatrix2x3fv',
+ elem: '[1][2]',
+ numElementsPerType: 6,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffset: [0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0],
+ srcOffset: 4,
+ },
+ { type: 'mat3x2',
+ setter: 'uniformMatrix3x2fv',
+ elem: '[2][1]',
+ numElementsPerType: 6,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0, 0],
+ srcOffset: 3,
+ },
+ { type: 'mat2x4',
+ setter: 'uniformMatrix2x4fv',
+ elem: '[1][3]',
+ numElementsPerType: 8,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+ srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0],
+ srcOffset: 2,
+ },
+ { type: 'mat4x2',
+ setter: 'uniformMatrix4x2fv',
+ elem: '[3][1]',
+ numElementsPerType: 8,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+ srcValuesWithOffset: [0, 0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
+ srcValuesWithOffsetAndLength: [0, 0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0],
+ srcOffset: 5,
+ },
+ { type: 'mat3x4',
+ setter: 'uniformMatrix3x4fv',
+ elem: '[2][3]',
+ numElementsPerType: 12,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0, 0, 0],
+ srcOffset: 2,
+ },
+ { type: 'mat4x3',
+ setter: 'uniformMatrix4x3fv',
+ elem: '[3][2]',
+ numElementsPerType: 12,
+ srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
+ srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0, 0, 0],
+ srcOffset: 2,
+ },
+
+];
+
+function checkUniformValues(program, typeInfo, useInitialValues) {
+ var numSrcValues = typeInfo.srcValues.length / typeInfo.numElementsPerType;
+ for (var ii = 0; ii < uniformArraySize; ++ii) {
+ var expectedValues;
+ if (useInitialValues || ii >= numSrcValues) {
+ expectedValues = new Array(typeInfo.numElementsPerType);
+ for (var jj = 0; jj < typeInfo.numElementsPerType; ++jj) {
+ expectedValues[jj] = initialUniformValue;
+ }
+ } else {
+ expectedValues = typeInfo.srcValues.slice(
+ typeInfo.numElementsPerType * ii, typeInfo.numElementsPerType * (ii + 1));
+ }
+ var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can get location of element " + ii + " of array from gl.getUniformLocation");
+ var value = gl.getUniform(program, elemLoc);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can get value of element " + ii + " of array from gl.getUniform");
+ var equal = true;
+ if (value === null) {
+ equal = false;
+ } else if (typeInfo.numElementsPerType == 1) {
+ if (value != expectedValues[0]) {
+ equal = false;
+ }
+ } else {
+ for (var jj = 0; jj < typeInfo.numElementsPerType; ++jj) {
+ if (value[jj] != expectedValues[jj]) {
+ equal = false;
+ break;
+ }
+ }
+ }
+ assertMsg(equal,
+ "value put in (" + expectedValues + ") matches value pulled out (" +
+ (value === null ? "null" : value) + ")");
+ }
+}
+
+for (var tt = 0; tt < typeInfos.length; ++tt) {
+ var typeInfo = typeInfos[tt];
+ debug("");
+ debug("check " + typeInfo.type);
+ var srcLength = typeInfo.srcValues.length;
+ var fSrc = wtu.replaceParams(fTemplate, typeInfo);
+ var program = wtu.loadProgram(gl, vSrc, fSrc);
+ if (!program) {
+ testFailed("Failed to create the program");
+ continue;
+ }
+ gl.useProgram(program);
+
+ var loc = gl.getUniformLocation(program, "color[0]");
+ if (!loc) {
+ testFailed("Failed to obtain the location of the uniform");
+ continue;
+ }
+
+ function setter(loc, array, srcOffset, srcLength) {
+ var isMatrix = (typeInfo.setter.indexOf("Matrix") == 7);
+ if (typeof(srcOffset) != 'undefined') {
+ if (isMatrix) {
+ gl[typeInfo.setter](loc, gl.FALSE, array, srcOffset, srcLength);
+ } else {
+ gl[typeInfo.setter](loc, array, srcOffset, srcLength);
+ }
+ } else if (typeof(srcLength) != 'undefined') {
+ if (isMatrix) {
+ gl[typeInfo.setter](loc, gl.FALSE, array, srcOffset);
+ } else {
+ gl[typeInfo.setter](loc, array, srcOffset);
+ }
+ } else {
+ if (isMatrix) {
+ gl[typeInfo.setter](loc, gl.FALSE, array);
+ } else {
+ gl[typeInfo.setter](loc, array);
+ }
+ }
+ }
+
+ // Initialize uniforms to value 99 and verify it.
+ var initValues = new Array(typeInfo.numElementsPerType * uniformArraySize);
+ for (var ii = 0; ii < typeInfo.numElementsPerType * uniformArraySize; ++ii) {
+ initValues[ii] = initialUniformValue;
+ }
+ setter(loc, initValues);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "no error from initializing uniforms to 99");
+ checkUniformValues(program, typeInfo, true);
+
+ setter(loc, typeInfo.srcValues);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can set an array of uniforms with gl." + typeInfo.setter +
+ " without srcOffset / srcLength");
+ checkUniformValues(program, typeInfo);
+
+ setter(loc, typeInfo.srcValues, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can set an array of uniforms with gl." + typeInfo.setter +
+ " with srcOffset = 0");
+ checkUniformValues(program, typeInfo);
+
+ setter(loc, typeInfo.srcValues, 0, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can set an array of uniforms with gl." + typeInfo.setter +
+ " with srcOffset = 0 / srcLength = 0");
+ checkUniformValues(program, typeInfo);
+
+ setter(loc, typeInfo.srcValuesWithOffset, typeInfo.srcOffset);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can set an array of uniforms with gl." + typeInfo.setter +
+ " with srcOffset = " + typeInfo.srcOffset);
+ checkUniformValues(program, typeInfo);
+
+ setter(loc, typeInfo.srcValuesWithOffset, typeInfo.srcOffset, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can set an array of uniforms with gl." + typeInfo.setter +
+ " with srcOffset = " + typeInfo.srcOffset + " / srcLength = 0");
+ checkUniformValues(program, typeInfo);
+
+ setter(loc, typeInfo.srcValuesWithOffsetAndLength, typeInfo.srcOffset, srcLength);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "can set an array of uniforms with gl." + typeInfo.setter +
+ " with srcOffset = " + typeInfo.srcOffset + " / srcLength = " + srcLength);
+ checkUniformValues(program, typeInfo);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors");
+
+ // Negative tests
+ setter(loc, typeInfo.srcValues, typeInfo.srcValues.length + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl." + typeInfo.setter + " with srcOffset out-of-bounds");
+
+ setter(loc, typeInfo.srcValues, 0, typeInfo.srcValues.length + 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl." + typeInfo.setter + " with srcLength out-of-bounds");
+
+ setter(loc, typeInfo.srcValues, typeInfo.srcOffset, srcLength);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl." + typeInfo.setter + " with srcOffset + srcLength out-of-bounds");
+
+ setter(loc, typeInfo.srcValues, typeInfo.srcValues.length);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl." + typeInfo.setter + " with 0 data");
+
+ if (typeInfo.numElementsPerType > 1) {
+ setter(loc, typeInfo.srcValuesWithOffsetAndLength, typeInfo.srcOffset);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl." + typeInfo.setter + " with array length minus srcOffset not multiple of " + typeInfo.type);
+ }
+}
+
+debug("");
+var successfullyParsed = true;
+
+</script>
+<script src="../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/incompatible-texture-type-for-sampler.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/incompatible-texture-type-for-sampler.html
new file mode 100644
index 0000000000..90cb54317a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/incompatible-texture-type-for-sampler.html
@@ -0,0 +1,335 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL uniform samplers with incompatible texture formats tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_vertex;
+void main(void) {
+ gl_Position = a_vertex;
+ gl_PointSize = 1.0;
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="100", height="100"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+description("Test that using an incompatible texture type generates INVALID_OPERATION at draw time");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function makeFragmentShader(samplerType, uvType) {
+ return `#version 300 es
+ precision mediump float;
+ uniform mediump ${samplerType} u_tex;
+ out vec4 color;
+ void main() {
+ color = vec4(texture(u_tex, ${uvType}));
+ }
+ `;
+}
+
+// Sampler types.
+const FLOAT = 1;
+const SIGNED = 2;
+const UNSIGNED = 3;
+const SHADOW = 4;
+
+const textureInternalFormatInfo = {};
+{
+ const t = textureInternalFormatInfo;
+ // unsized formats
+ t[gl.ALPHA] = { textureFormat: gl.ALPHA, samplerType: FLOAT, depth: false, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
+ t[gl.LUMINANCE] = { textureFormat: gl.LUMINANCE, samplerType: FLOAT, depth: false, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
+ t[gl.LUMINANCE_ALPHA] = { textureFormat: gl.LUMINANCE_ALPHA, samplerType: FLOAT, depth: false, bytesPerElement: [2, 4, 4, 8], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
+ t[gl.RGB] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3, 6, 6, 12, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_5_6_5], };
+ t[gl.RGBA] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_4_4_4_4, gl.UNSIGNED_SHORT_5_5_5_1], };
+
+ // sized formats
+ t[gl.R8] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
+ t[gl.R8_SNORM] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [1], type: [gl.BYTE], };
+ t[gl.R16F] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [4, 2], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.R32F] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.FLOAT], };
+ t[gl.R8UI] = { textureFormat: gl.RED_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
+ t[gl.R8I] = { textureFormat: gl.RED_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [1], type: [gl.BYTE], };
+ t[gl.R16UI] = { textureFormat: gl.RED_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [2], type: [gl.UNSIGNED_SHORT], };
+ t[gl.R16I] = { textureFormat: gl.RED_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [2], type: [gl.SHORT], };
+ t[gl.R32UI] = { textureFormat: gl.RED_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
+ t[gl.R32I] = { textureFormat: gl.RED_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [4], type: [gl.INT], };
+ t[gl.RG8] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RG8_SNORM] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [2], type: [gl.BYTE], };
+ t[gl.RG16F] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [8, 4], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.RG32F] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [8], type: [gl.FLOAT], };
+ t[gl.RG8UI] = { textureFormat: gl.RG_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RG8I] = { textureFormat: gl.RG_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [2], type: [gl.BYTE], };
+ t[gl.RG16UI] = { textureFormat: gl.RG_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_SHORT], };
+ t[gl.RG16I] = { textureFormat: gl.RG_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [4], type: [gl.SHORT], };
+ t[gl.RG32UI] = { textureFormat: gl.RG_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [8], type: [gl.UNSIGNED_INT], };
+ t[gl.RG32I] = { textureFormat: gl.RG_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [8], type: [gl.INT], };
+ t[gl.RGB8] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
+ t[gl.SRGB8] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGB565] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_6_5], };
+ t[gl.RGB8_SNORM] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3], type: [gl.BYTE], };
+ t[gl.R11F_G11F_B10F] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_10F_11F_11F_REV], };
+ t[gl.RGB9_E5] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_5_9_9_9_REV], };
+ t[gl.RGB16F] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12, 6], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.RGB32F] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12], type: [gl.FLOAT], };
+ t[gl.RGB8UI] = { textureFormat: gl.RGB_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGB8I] = { textureFormat: gl.RGB_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [3], type: [gl.BYTE], };
+ t[gl.RGB16UI] = { textureFormat: gl.RGB_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [6], type: [gl.UNSIGNED_SHORT], };
+ t[gl.RGB16I] = { textureFormat: gl.RGB_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [6], type: [gl.SHORT], };
+ t[gl.RGB32UI] = { textureFormat: gl.RGB_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [12], type: [gl.UNSIGNED_INT], };
+ t[gl.RGB32I] = { textureFormat: gl.RGB_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [12], type: [gl.INT], };
+ t[gl.RGBA8] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
+ t[gl.SRGB8_ALPHA8] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGBA8_SNORM] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.BYTE], };
+ t[gl.RGB5_A1] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4, 2, 4], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_5_5_1, gl.UNSIGNED_INT_2_10_10_10_REV], };
+ t[gl.RGBA4] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_4_4_4_4], };
+ t[gl.RGB10_A2] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
+ t[gl.RGBA16F] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [16, 8], type: [gl.FLOAT, gl.HALF_FLOAT], };
+ t[gl.RGBA32F] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [16], type: [gl.FLOAT], };
+ t[gl.RGBA8UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
+ t[gl.RGBA8I] = { textureFormat: gl.RGBA_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [4], type: [gl.BYTE], };
+ t[gl.RGB10_A2UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
+ t[gl.RGBA16UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [8], type: [gl.UNSIGNED_SHORT], };
+ t[gl.RGBA16I] = { textureFormat: gl.RGBA_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [8], type: [gl.SHORT], };
+ t[gl.RGBA32I] = { textureFormat: gl.RGBA_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [16], type: [gl.INT], };
+ t[gl.RGBA32UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [16], type: [gl.UNSIGNED_INT], };
+
+ // Sized Internal
+ // Note that samplerType is FLOAT for depth formats, not SHADOW. Shadow
+ // samplers are handled as a special case in the test code because they have
+ // special rules about TEXTURE_COMPARE_MODE.
+ t[gl.DEPTH_COMPONENT16] = { textureFormat: gl.DEPTH_COMPONENT, samplerType: FLOAT, depth: true, bytesPerElement: [2, 4], type: [gl.UNSIGNED_SHORT, gl.UNSIGNED_INT], };
+ t[gl.DEPTH_COMPONENT24] = { textureFormat: gl.DEPTH_COMPONENT, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
+ t[gl.DEPTH_COMPONENT32F] = { textureFormat: gl.DEPTH_COMPONENT, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.FLOAT], };
+ t[gl.DEPTH24_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT_24_8], };
+ t[gl.DEPTH32F_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.FLOAT_32_UNSIGNED_INT_24_8_REV], };
+
+ // TODO: Compressed formats.
+
+ Object.keys(t).forEach(function(internalFormat) {
+ const info = t[internalFormat];
+ info.bytesPerElementMap = {};
+ info.bytesPerElement.forEach(function(bytesPerElement, ndx) {
+ const type = info.type[ndx];
+ info.bytesPerElementMap[type] = bytesPerElement;
+ });
+ });
+}
+
+const floatSamplerTypes = [
+ { type: 'sampler2D', uvType: 'vec2(0)', target: gl.TEXTURE_2D, },
+ { type: 'sampler3D', uvType: 'vec3(0)', target: gl.TEXTURE_3D, },
+ { type: 'samplerCube', uvType: 'vec3(0)', target: gl.TEXTURE_CUBE_MAP, },
+ { type: 'sampler2DArray', uvType: 'vec3(0)', target: gl.TEXTURE_2D_ARRAY, },
+];
+
+const signedIntSamplerTypes = [
+ { type: 'isampler2D', uvType: 'vec2(0)', target: gl.TEXTURE_2D, },
+ { type: 'isampler3D', uvType: 'vec3(0)', target: gl.TEXTURE_3D, },
+ { type: 'isamplerCube', uvType: 'vec3(0)', target: gl.TEXTURE_CUBE_MAP, },
+ { type: 'isampler2DArray', uvType: 'vec3(0)', target: gl.TEXTURE_2D_ARRAY, },
+];
+
+const unsignedIntSamplerTypes = [
+ { type: 'usampler2D', uvType: 'vec2(0)', target: gl.TEXTURE_2D, },
+ { type: 'usampler3D', uvType: 'vec3(0)', target: gl.TEXTURE_3D, },
+ { type: 'usamplerCube', uvType: 'vec3(0)', target: gl.TEXTURE_CUBE_MAP, },
+ { type: 'usampler2DArray', uvType: 'vec3(0)', target: gl.TEXTURE_2D_ARRAY, },
+];
+
+const shadowSamplerTypes = [
+ { type: 'sampler2DShadow', uvType: 'vec3(0)', target: gl.TEXTURE_2D, },
+ { type: 'samplerCubeShadow', uvType: 'vec4(0)', target: gl.TEXTURE_CUBE_MAP, },
+ { type: 'sampler2DArrayShadow', uvType: 'vec4(0)', target: gl.TEXTURE_2D_ARRAY, },
+]
+
+/**
+ * Gets the number of bytes per element for a given internalFormat / type
+ * @param {number} internalFormat The internalFormat parameter from texImage2D etc..
+ * @param {number} type The type parameter for texImage2D etc..
+ * @return {number} the number of bytes per element for the given internalFormat, type combo
+ * @memberOf module:twgl/textures
+ */
+function getBytesPerElementForInternalFormat(internalFormat, type) {
+ const info = textureInternalFormatInfo[internalFormat];
+ if (!info) {
+ throw "unknown internal format";
+ }
+ const bytesPerElement = info.bytesPerElementMap[type];
+ if (bytesPerElement === undefined) {
+ throw "unknown internal format";
+ }
+ return bytesPerElement;
+}
+
+function make2DTexture(target, internalFormat, format, type) {
+ gl.texImage2D(target, 0, internalFormat, 1, 1, 0, format, type, null);
+}
+
+function make3DTexture(target, internalFormat, format, type) {
+ gl.texImage3D(target, 0, internalFormat, 1, 1, 1, 0, format, type, null);
+}
+
+function makeCubeMapTexture(target, internalFormat, format, type) {
+ [
+ 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,
+ ].forEach(function(target) {
+ gl.texImage2D(target, 0, internalFormat, 1, 1, 0, format, type, null);
+ });
+}
+
+function runTest() {
+ const targets = {};
+ targets[gl.TEXTURE_2D] = { fn: make2DTexture, },
+ targets[gl.TEXTURE_3D] = { fn: make3DTexture, },
+ targets[gl.TEXTURE_CUBE_MAP] = { fn: makeCubeMapTexture, },
+ targets[gl.TEXTURE_2D_ARRAY] = { fn: make3DTexture, },
+
+ Object.keys(targets).forEach(function(target) {
+ target = parseInt(target);
+ const targetInfo = targets[target];
+ targetInfo.textures = [];
+ Object.keys(textureInternalFormatInfo).forEach(function(internalFormat) {
+ internalFormat = parseInt(internalFormat);
+ const isDepthFormat = textureInternalFormatInfo[internalFormat].depth;
+ if (target === gl.TEXTURE_3D && isDepthFormat) {
+ return;
+ }
+ const info = textureInternalFormatInfo[internalFormat];
+ const texture = gl.createTexture();
+ gl.bindTexture(target, texture);
+ targetInfo.fn(target, internalFormat, info.textureFormat, info.type[0]);
+ targetInfo.textures.push({
+ internalFormat: internalFormat,
+ texture: texture,
+ });
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(target, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from setup for ${wtu.glEnumToString(gl, target)} ${wtu.glEnumToString(gl, internalFormat)}`);
+ });
+ });
+
+ const samplerObject = gl.createSampler();
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
+
+ // The rules implemented here are:
+
+ // Float samplers accept only float textures and normalized integer textures
+ // (signed or unsigned) and depth textures with TEXTURE_COMPARE_MODE set to
+ // NONE.
+
+ // Signed samplers accept only signed unnormalized integer textures.
+
+ // Unsigned samplers accept only unsigned unnormalized integer textures.
+
+ // Shadow samplers accept only depth textures with
+ // TEXTURE_COMPARE_MODE set to COMPARE_REF_TO_TEXTURE.
+
+ testSamplerType(FLOAT, floatSamplerTypes);
+ testSamplerType(SIGNED, signedIntSamplerTypes);
+ testSamplerType(UNSIGNED, unsignedIntSamplerTypes);
+ testSamplerType(SHADOW, shadowSamplerTypes);
+
+ function testSamplerType(samplerType, samplerInfos) {
+ samplerInfos.forEach(function(samplerInfo) {
+ debug(`\nchecking ${samplerInfo.type}`);
+ const program = wtu.setupProgram(gl, ['vshader', makeFragmentShader(samplerInfo.type, samplerInfo.uvType)], [], console.log.bind(console));
+ if (!program) {
+ testFailed("Loading program failed");
+ return;
+ }
+ testPassed("Loading program succeeded");
+
+ const target = samplerInfo.target;
+ const targetInfo = targets[target];
+ targetInfo.textures.forEach(function(textureInfo) {
+ const internalFormat = textureInfo.internalFormat;
+ const desc = wtu.glEnumToString(gl, internalFormat);
+ const info = textureInternalFormatInfo[internalFormat];
+
+ // The texture object can have two values of TEXTURE_COMPARE_MODE: NONE or
+ // COMPARE_REF_TO_TEXTURE. However, the sampler can have three states:
+ // No sampler object bound, sampler object with NONE, and sampler object with
+ // COMPARE_REF_TO_TEXTURE. When a sampler object is bound, it overrides the
+ // texture object's state. We test 2*3=6 possible combinations of state.
+
+ // First test the three states that result in TEXTURE_COMPARE_MODE being NONE.
+ let expected = samplerType == info.samplerType ? gl.NONE : gl.INVALID_OPERATION;
+ gl.bindTexture(target, textureInfo.texture);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expected, `${desc} texture state NONE, no sampler object`);
+
+ gl.bindSampler(0, samplerObject);
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_COMPARE_MODE, gl.NONE);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expected, `${desc} texture state NONE, sampler state NONE`);
+
+ gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expected, `${desc} texture state COMPARE_REF_TO_TEXTURE, sampler state NONE`);
+
+ // Now test test the three states that result in TEXTURE_COMPARE_MODE being COMPARE_REF_TO_TEXTURE.
+ if (info.depth) {
+ expected = samplerType == SHADOW ? gl.NONE : gl.INVALID_OPERATION;
+ }
+ gl.bindSampler(0, null);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expected, `${desc} texture state COMPARE_REF_TO_TEXTURE, no sampler object`);
+
+ gl.bindSampler(0, samplerObject);
+ gl.samplerParameteri(samplerObject, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expected, `${desc} texture state COMPARE_REF_TO_TEXTURE, sampler state COMPARE_REF_TO_TEXTURE`);
+
+ gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.NONE);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ wtu.glErrorShouldBe(gl, expected, `${desc} texture state NONE, sampler state COMPARE_REF_TO_TEXTURE`);
+ gl.bindSampler(0, null);
+ });
+ });
+ };
+}
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/large-uniform-buffers.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/large-uniform-buffers.html
new file mode 100644
index 0000000000..5e67195ea8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/large-uniform-buffers.html
@@ -0,0 +1,138 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL large uniform buffers conformance tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_vertex;
+void main(void) {
+ gl_Position = a_vertex;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+layout (std140) uniform color_ubo {
+ vec4 color;
+};
+out vec4 fragColor;
+void main(void) {
+ fragColor = color;
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="100", height="100"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+description("Test for UBOs sized over 65536 - https://bugs.chromium.org/p/angleproject/issues/detail?id=3388");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function runTest() {
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_vertex']);
+ var uboIndex = gl.INVALID_INDEX;
+ if (program)
+ uboIndex = gl.getUniformBlockIndex(program, "color_ubo");
+ if (!program || uboIndex == gl.INVALID_INDEX) {
+ testFailed("Loading program failed");
+ return;
+ }
+ testPassed("Loading program succeeded");
+
+ var vertices = new Float32Array([
+ -1, -1, 0,
+ 1, -1, 0,
+ -1, 1, 0,
+ 1, 1, 0
+ ]);
+ var vertexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var indexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array([ 0, 1, 2, 2, 1, 3 ]), gl.STATIC_DRAW);
+
+ var uboDataSize = gl.getActiveUniformBlockParameter(
+ program, uboIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ if (uboDataSize == 0) {
+ testFailed("uniform block data size invalid");
+ return;
+ }
+
+ var uboBuf = gl.createBuffer();
+ var uboData = new Float32Array(0x20000);
+
+ var offs0 = 0x00000;
+ // Red
+ uboData[offs0 + 0] = 1;
+ uboData[offs0 + 1] = 0;
+ uboData[offs0 + 2] = 0;
+ uboData[offs0 + 3] = 1;
+
+ var offs1 = 0x10000;
+ const alignment = gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ if (offs1 % alignment != 0)
+ testFailed("Platform has a strange uniform buffer offset alignment requirement: " + alignment);
+
+ // Green
+ uboData[offs1 + 0] = 0;
+ uboData[offs1 + 1] = 1;
+ uboData[offs1 + 2] = 0;
+ uboData[offs1 + 3] = 1;
+
+ gl.uniformBlockBinding(program, uboIndex, 0);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uboBuf);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboData, gl.STATIC_DRAW);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from setup");
+
+ debug("draw lower triangle - should be red");
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, uboBuf, offs0 * 4, 0x10);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ debug("draw upper triangle - should be green");
+ var uboBuf2 = gl.createBuffer();
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, uboBuf, offs1 * 4, 0x10);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ var width = 100, height = 100;
+ wtu.checkCanvasRectColor(gl, 0, 0, width/2-5, height/2-5, [255, 0, 0, 255], 2,
+ function() { testPassed("lower left should be red"); },
+ function() { testFailed("lower left should be red"); });
+ wtu.checkCanvasRectColor(gl, width/2+5, height/2+5, width/2-5, height/2-5, [0, 255, 0, 255], 2,
+ function() { testPassed("top right should be green"); },
+ function() { testFailed("top right should be green"); });
+}
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/query-uniform-blocks-after-shader-detach.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/query-uniform-blocks-after-shader-detach.html
new file mode 100644
index 0000000000..24c7060e5c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/query-uniform-blocks-after-shader-detach.html
@@ -0,0 +1,93 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Uniform Buffers Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+
+in vec4 position;
+
+uniform localInputs
+{
+ mat4 projectionModelViewMatrix;
+};
+
+void main ()
+{
+ gl_Position = projectionModelViewMatrix * position;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+
+out lowp vec4 resultColor;
+
+void main()
+{
+ resultColor = vec4(0,1,0,1);
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script>
+// Adopted from the test case provided in crbug.com/735784
+"use strict";
+description("This tests UBO block lookups still work after detaching shaders");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+
+function runTest(gl) {
+ var program = wtu.loadProgramFromScript(gl, "vshader", "fshader");
+ if (!program) {
+ testFailed("Loading program failed");
+ return;
+ }
+
+ var shaders = gl.getAttachedShaders(program);
+ if (!shaders || shaders.length != 2) {
+ testFailed("getAttachedShaders failed");
+ return;
+ }
+ gl.detachShader (program, shaders[0]);
+ gl.detachShader (program, shaders[1]);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
+
+ var index = gl.getUniformBlockIndex(program, "localInputs");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from getUniformBlockIndex");
+ if (index == gl.INVALID_INDEX) {
+ testFailed("getUniformBlockIndex returns INVALID_INDEX");
+ } else {
+ testPassed("getUniformBlockIndex returns valid index");
+ }
+}
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+ runTest(gl);
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/simple-buffer-change.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/simple-buffer-change.html
new file mode 100644
index 0000000000..c5646faae8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/simple-buffer-change.html
@@ -0,0 +1,122 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL draw with uniform blocks conformance tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 a_vertex;
+void main(void) {
+ gl_Position = a_vertex;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+layout (std140) uniform color_ubo {
+ vec4 color;
+};
+out vec4 fragColor;
+void main(void) {
+ fragColor = color;
+}
+</script>
+</head>
+<body>
+<canvas id="example" width="100", height="100"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+debug("");
+
+// Ported from: https://github.com/google/angle/blob/master/src/tests/gl_tests/UniformBufferTest.cpp#L1463
+description("Regression test for https://bugs.chromium.org/p/chromium/issues/detail?id=792966");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example", undefined, 2);
+
+function runTest() {
+ var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_vertex']);
+ var uboIndex = gl.INVALID_INDEX;
+ if (program)
+ uboIndex = gl.getUniformBlockIndex(program, "color_ubo");
+ if (!program || uboIndex == gl.INVALID_INDEX) {
+ testFailed("Loading program failed");
+ return;
+ }
+ testPassed("Loading program succeeded");
+
+ var vertices = new Float32Array([
+ -1, -1, 0,
+ 1, -1, 0,
+ -1, 1, 0,
+ 1, 1, 0
+ ]);
+ var vertexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuf);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var indexBuf = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array([ 0, 1, 2, 2, 1, 3 ]), gl.STATIC_DRAW);
+
+ var uboDataSize = gl.getActiveUniformBlockParameter(
+ program, uboIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
+ if (uboDataSize == 0) {
+ testFailed("uniform block data size invalid");
+ return;
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from setup");
+
+ debug("draw lower triangle - should be red");
+ var uboBuf1 = gl.createBuffer();
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uboBuf1);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboDataSize, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([ 1, 0, 0, 1 ]));
+ gl.uniformBlockBinding(program, uboIndex, 0);
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ // Bind a second buffer to the same binding point (0). This should set to draw green.
+ debug("draw upper triangle - should be green");
+ var uboBuf2 = gl.createBuffer();
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uboBuf2);
+ gl.bufferData(gl.UNIFORM_BUFFER, uboDataSize, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([ 0, 1, 0, 1 ]));
+ gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ var width = 100, height = 100;
+ wtu.checkCanvasRectColor(gl, 0, 0, width/2-5, height/2-5, [255, 0, 0, 255], 2,
+ function() { testPassed("lower left should be red"); },
+ function() { testFailed("lower left should be red"); });
+ wtu.checkCanvasRectColor(gl, width/2+5, height/2+5, width/2-5, height/2-5, [0, 255, 0, 255], 2,
+ function() { testPassed("top right should be green"); },
+ function() { testFailed("top right should be green"); });
+}
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ testPassed("WebGL context creation succeeded");
+ runTest();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/uniform-blocks-with-arrays.html b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/uniform-blocks-with-arrays.html
new file mode 100644
index 0000000000..2d40a62c00
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/uniform-blocks-with-arrays.html
@@ -0,0 +1,115 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL uniform blocks containing 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 id="vshader" type="x-shader/x-vertex">#version 300 es
+in vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+<script id="fshaderArraysOfStructs" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+struct light_t {
+ vec4 intensity;
+};
+const int maxLights = 2;
+layout(std140) uniform lightData { light_t lights[maxLights]; };
+vec4 processLight(vec4 lighting, light_t light)
+{
+ return lighting + light.intensity;
+}
+void main()
+{
+ vec4 lighting = vec4(0, 1, 0, 1);
+ for (int n = 0; n < maxLights; n++)
+ lighting = processLight(lighting, lights[n]);
+ my_FragColor = lighting;
+}
+</script>
+<script id="fshaderArraysOfStructsContainingArrays" type="x-shader/x-fragment">#version 300 es
+precision highp float;
+out vec4 my_FragColor;
+struct light_t {
+ vec4 intensity[3];
+};
+const int maxLights = 2;
+layout(std140) uniform lightData { light_t lights[maxLights]; };
+vec4 processLight(vec4 lighting, light_t light)
+{
+ return lighting + light.intensity[1];
+}
+void main()
+{
+ vec4 lighting = vec4(0, 1, 0, 1);
+ for (int n = 0; n < maxLights; n++)
+ lighting = processLight(lighting, lights[n]);
+ my_FragColor = lighting;
+}
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description();
+
+// GLSL ES 3.00.6 section 4.3.7:
+// "Otherwise, built-in types, previously declared structures, and arrays of these are allowed as the type of a declarator in the same manner they are allowed outside a block."
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext(undefined, undefined, 2);
+
+function runTest(fragShader, bufferFloatCount, shaderBlockDescription) {
+ debug('');
+ debug('Testing fragment shader with an uniform block containing ' + shaderBlockDescription);
+ var program = wtu.setupProgram(gl, ['vshader', fragShader], ['vPosition'], undefined, true);
+ if (!program) {
+ testFailed("Loading program failed");
+ return;
+ }
+ var blockIndex = gl.getUniformBlockIndex(program, "lightData");
+
+ var uniformBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, uniformBuffer);
+ gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(bufferFloatCount), gl.DYNAMIC_READ);
+
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, uniformBuffer);
+ gl.uniformBlockBinding(program, blockIndex, 0);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from uniform buffer setup");
+
+ wtu.clearAndDrawUnitQuad(gl);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors from draw");
+
+ wtu.checkCanvas(gl, [0, 255, 0, 255], 'should be green', 1);
+}
+
+if (!gl) {
+ testFailed("WebGL context creation failed");
+} else {
+ wtu.setupUnitQuad(gl);
+ runTest("fshaderArraysOfStructs", 2 * 4, 'arrays of structs');
+ runTest("fshaderArraysOfStructsContainingArrays", 2 * 3 * 4, 'arrays of structs containing arrays');
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/00_test_list.txt
new file mode 100644
index 0000000000..8ce1225636
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/00_test_list.txt
@@ -0,0 +1,2 @@
+vertex-array-object.html
+--min-version 2.0.1 vertex-array-object-and-disabled-attributes.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html b/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html
new file mode 100644
index 0000000000..08abba728c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html
@@ -0,0 +1,132 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL 2 Disabled Vertex Array Object and Disabled Attributes 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>
+</head>
+<body>
+<canvas id="example" width="50" height="50">
+</canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="singlevshader" type="x-shader/x-vertex">
+attribute vec4 position;
+void main() {
+ gl_Position = position;
+}
+</script>
+
+<script id="singlefshader" type="x-shader/x-fragment">
+void main() {
+ gl_FragColor = vec4(1, 0, 0, 1);
+}
+</script>
+<script id="dualvshader" type="x-shader/x-vertex">#version 300 es
+in vec4 position;
+in vec4 color;
+out vec4 varyColor;
+void main() {
+ gl_Position = position;
+ varyColor = color;
+}
+</script>
+<script id="dualfshader" type="x-shader/x-fragment">#version 300 es
+precision mediump float;
+in vec4 varyColor;
+out vec4 colorOut;
+void main() {
+ colorOut = varyColor;
+}
+</script>
+
+<script>
+// Test that switching VAOs keeps the disabled "current value" attributes up-to-date.
+// Based on ANGLE test (StateChangeTestES3, VertexArrayObjectAndDisabledAttributes) from https://github.com/google/angle/blob/f7f0b8c3ab21c52cc2915048959361cf628d95f0/src/tests/gl_tests/StateChangeTest.cpp
+"use strict";
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example", undefined, 2);
+
+// Location of "position" attribute must match between shaders.
+var singleProgram = wtu.setupProgram(gl, ['singlevshader', 'singlefshader'], ['position'], [0]);
+var dualProgram = wtu.setupProgram(gl, ['dualvshader', 'dualfshader'], ['position'], [0]);
+
+var positionLocation = gl.getAttribLocation(dualProgram, "position");
+var colorLocation = gl.getAttribLocation(dualProgram, "color");
+var singlePositionLocation = gl.getAttribLocation(singleProgram, "position");
+
+
+gl.useProgram(singleProgram);
+
+var positions = new Float32Array([
+ -1, 1,
+ -1, -1,
+ 1, -1,
+ -1, 1,
+ 1, -1,
+ 1, 1
+]);
+
+var positionBuffer = gl.createBuffer();
+gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+
+var vertexArray = gl.createVertexArray();
+gl.bindVertexArray(vertexArray);
+
+gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+gl.vertexAttribPointer(singlePositionLocation, 2, gl.FLOAT, false, 0, 0);
+gl.enableVertexAttribArray(singlePositionLocation);
+
+gl.drawArrays(gl.TRIANGLES, 0, 6);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+
+gl.bindVertexArray(null);
+gl.useProgram(dualProgram);
+gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
+gl.enableVertexAttribArray(positionLocation);
+
+var greenBuffer = gl.createBuffer();
+var green = new Uint8Array(4 * 6);
+
+for (var i = 0; i < 6; ++i) {
+ var ci = i * 4;
+
+ green[ci] = 0;
+ green[ci + 1] = 255;
+ green[ci + 2] = 0;
+ green[ci + 3] = 255;
+}
+
+gl.bindBuffer(gl.ARRAY_BUFFER, greenBuffer);
+gl.bufferData(gl.ARRAY_BUFFER, green, gl.STATIC_DRAW);
+gl.vertexAttribPointer(colorLocation, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+gl.enableVertexAttribArray(colorLocation);
+
+gl.drawArrays(gl.TRIANGLES, 0, 6);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+
+gl.bindVertexArray(vertexArray);
+gl.drawArrays(gl.TRIANGLES, 0, 6);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+wtu.checkCanvas(gl, [0, 0, 0, 255], "should be black");
+
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object.html b/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object.html
new file mode 100644
index 0000000000..160a7f4ea6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object.html
@@ -0,0 +1,671 @@
+<!--
+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.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta 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>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 a_position;
+attribute vec4 a_color;
+varying vec4 v_color;
+void main(void) {
+ gl_Position = a_position;
+ v_color = a_color;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec4 v_color;
+void main(void) {
+ gl_FragColor = v_color;
+}
+</script>
+<script>
+"use strict";
+description("This test verifies the functionality of the Vertex Array Objects.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = wtu.create3DContext(canvas, null, 2);
+var vao = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ runBindingTest();
+ runObjectTest();
+ runAttributeTests();
+ runAttributeValueTests();
+ runDrawTests();
+ runUnboundDeleteTests();
+ runBoundDeleteTests();
+ runArrayBufferBindTests();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function runBindingTest() {
+ debug("Testing binding enum");
+
+ shouldBe("gl.VERTEX_ARRAY_BINDING", "0x85B5");
+
+ gl.getParameter(gl.VERTEX_ARRAY_BINDING);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "VERTEX_ARRAY_BINDING query should succeed");
+
+ // Default value is null
+ if (gl.getParameter(gl.VERTEX_ARRAY_BINDING) === null) {
+ testPassed("Default value of VERTEX_ARRAY_BINDING is null");
+ } else {
+ testFailed("Default value of VERTEX_ARRAY_BINDING is not null");
+ }
+
+ debug("Testing binding a VAO");
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+ shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+ gl.bindVertexArray(vao0);
+ if (gl.getParameter(gl.VERTEX_ARRAY_BINDING) == vao0) {
+ testPassed("gl.getParameter(gl.VERTEX_ARRAY_BINDING) is expected VAO");
+ } else {
+ testFailed("gl.getParameter(gl.VERTEX_ARRAY_BINDING) is not expected VAO")
+ }
+ gl.bindVertexArray(vao1);
+ if (gl.getParameter(gl.VERTEX_ARRAY_BINDING) == vao1) {
+ testPassed("gl.getParameter(gl.VERTEX_ARRAY_BINDING) is expected VAO");
+ } else {
+ testFailed("gl.getParameter(gl.VERTEX_ARRAY_BINDING) is not expected VAO")
+ }
+ gl.deleteVertexArray(vao1);
+ shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+ gl.bindVertexArray(vao1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "binding a deleted vertex array object");
+ gl.bindVertexArray(null);
+ shouldBeNull("gl.getParameter(gl.VERTEX_ARRAY_BINDING)");
+ gl.deleteVertexArray(vao1);
+}
+
+function runObjectTest() {
+ debug("Testing object creation");
+
+ vao = gl.createVertexArray();
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "createVertexArray should not set an error");
+ shouldBeNonNull("vao");
+
+ // Expect false if never bound
+ shouldBeFalse("gl.isVertexArray(vao)");
+ gl.bindVertexArray(vao);
+ shouldBeTrue("gl.isVertexArray(vao)");
+ gl.bindVertexArray(null);
+ shouldBeTrue("gl.isVertexArray(vao)");
+
+ shouldBeFalse("gl.isVertexArray(null)");
+
+ gl.deleteVertexArray(vao);
+ vao = null;
+}
+
+function runAttributeTests() {
+ debug("Testing attributes work across bindings");
+
+ var states = [];
+
+ var attrCount = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
+ for (var n = 0; n < attrCount; n++) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+
+ var state = {};
+ states.push(state);
+
+ var vao = state.vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+
+ var enableArray = (n % 2 == 0);
+ if (enableArray) {
+ gl.enableVertexAttribArray(n);
+ } else {
+ gl.disableVertexAttribArray(n);
+ }
+
+ if (enableArray) {
+ var buffer = state.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
+
+ gl.vertexAttribPointer(n, 1 + n % 4, gl.FLOAT, true, n * 4, n * 4);
+ }
+
+ if (enableArray) {
+ var elbuffer = state.elbuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elbuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
+ }
+
+ gl.bindVertexArray(null);
+ }
+
+ var anyMismatch = false;
+ for (var n = 0; n < attrCount; n++) {
+ var state = states[n];
+
+ gl.bindVertexArray(state.vao);
+
+ var shouldBeEnabled = (n % 2 == 0);
+ var isEnabled = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ if (shouldBeEnabled != isEnabled) {
+ testFailed("VERTEX_ATTRIB_ARRAY_ENABLED not preserved");
+ anyMismatch = true;
+ }
+
+ var buffer = gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+ if (shouldBeEnabled) {
+ if (buffer == state.buffer) {
+ // Matched
+ if ((gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_SIZE) == 1 + n % 4) &&
+ (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_TYPE) == gl.FLOAT) &&
+ (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED) == true) &&
+ (gl.getVertexAttrib(n, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == n * 4) &&
+ (gl.getVertexAttribOffset(n, gl.VERTEX_ATTRIB_ARRAY_POINTER) == n * 4)) {
+ // Matched
+ } else {
+ testFailed("VERTEX_ATTRIB_ARRAY_* not preserved");
+ anyMismatch = true;
+ }
+ } else {
+ testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved");
+ anyMismatch = true;
+ }
+ } else {
+ // GL_CURRENT_VERTEX_ATTRIB is not preserved
+ if (buffer) {
+ testFailed("VERTEX_ATTRIB_ARRAY_BUFFER_BINDING not preserved");
+ anyMismatch = true;
+ }
+ }
+
+ var elbuffer = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING);
+ if (shouldBeEnabled) {
+ if (elbuffer == state.elbuffer) {
+ // Matched
+ } else {
+ testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved");
+ anyMismatch = true;
+ }
+ } else {
+ if (elbuffer == null) {
+ // Matched
+ } else {
+ testFailed("ELEMENT_ARRAY_BUFFER_BINDING not preserved");
+ anyMismatch = true;
+ }
+ }
+ }
+ gl.bindVertexArray(null);
+ if (!anyMismatch) {
+ testPassed("All attributes preserved across bindings");
+ }
+
+ for (var n = 0; n < attrCount; n++) {
+ var state = states[n];
+ gl.deleteVertexArray(state.vao);
+ }
+}
+
+function runAttributeValueTests() {
+ debug("Testing that attribute values are not attached to bindings");
+
+ var v;
+ var vao0 = gl.createVertexArray();
+ var anyFailed = false;
+
+ gl.bindVertexArray(null);
+ gl.vertexAttrib4f(0, 0, 1, 2, 3);
+
+ v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
+ if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) {
+ testFailed("Vertex attrib value not round-tripped?");
+ anyFailed = true;
+ }
+
+ gl.bindVertexArray(vao0);
+
+ v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
+ if (!(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)) {
+ testFailed("Vertex attrib value reset across bindings");
+ anyFailed = true;
+ }
+
+ gl.vertexAttrib4f(0, 4, 5, 6, 7);
+ gl.bindVertexArray(null);
+
+ v = gl.getVertexAttrib(0, gl.CURRENT_VERTEX_ATTRIB);
+ if (!(v[0] == 4 && v[1] == 5 && v[2] == 6 && v[3] == 7)) {
+ testFailed("Vertex attrib value bound to buffer");
+ anyFailed = true;
+ }
+
+ if (!anyFailed) {
+ testPassed("Vertex attribute values are not attached to bindings")
+ }
+
+ gl.bindVertexArray(null);
+ gl.deleteVertexArray(vao0);
+}
+
+function runDrawTests() {
+ debug("Testing draws with various VAO bindings");
+
+ canvas.width = 50; canvas.height = 50;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ var opt_positionLocation = 0;
+ var opt_texcoordLocation = 1;
+
+ var program = wtu.setupSimpleTextureProgram(gl, opt_positionLocation, opt_texcoordLocation);
+
+ function setupQuad(s) {
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ 1.0 * s, 1.0 * s, 0.0,
+ -1.0 * s, 1.0 * s, 0.0,
+ -1.0 * s, -1.0 * s, 0.0,
+ 1.0 * s, 1.0 * s, 0.0,
+ -1.0 * s, -1.0 * s, 0.0,
+ 1.0 * s, -1.0 * s, 0.0]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(opt_positionLocation);
+ gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
+ 1.0 * s, 1.0 * s,
+ 0.0 * s, 1.0 * s,
+ 0.0 * s, 0.0 * s,
+ 1.0 * s, 1.0 * s,
+ 0.0 * s, 0.0 * s,
+ 1.0 * s, 0.0 * s]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(opt_texcoordLocation);
+ gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0);
+ };
+
+ function readLocation(x, y) {
+ var pixels = new Uint8Array(1 * 1 * 4);
+ gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ return pixels;
+ };
+ function testPixel(blockList, allowList) {
+ function testList(list, expected) {
+ for (var n = 0; n < list.length; n++) {
+ var l = list[n];
+ var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2;
+ var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2;
+ var source = readLocation(x, y);
+ if (Math.abs(source[0] - expected) > 2) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return testList(blockList, 0) && testList(allowList, 255);
+ };
+ function verifyDraw(drawNumber, s) {
+ wtu.clearAndDrawUnitQuad(gl);
+ var blockList = [];
+ var allowList = [];
+ var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0];
+ for (var n = 0; n < points.length; n++) {
+ if (points[n] <= s) {
+ blockList.push(points[n]);
+ } else {
+ allowList.push(points[n]);
+ }
+ }
+ if (testPixel(blockList, allowList)) {
+ testPassed("Draw " + drawNumber + " passed pixel test");
+ } else {
+ testFailed("Draw " + drawNumber + " failed pixel test");
+ }
+ };
+
+ // Setup all bindings
+ setupQuad(1);
+ gl.bindVertexArray(vao0);
+ setupQuad(0.5);
+ gl.bindVertexArray(vao1);
+ setupQuad(0.25);
+
+ // Verify drawing
+ gl.bindVertexArray(null);
+ verifyDraw(0, 1);
+ gl.bindVertexArray(vao0);
+ verifyDraw(1, 0.5);
+ gl.bindVertexArray(vao1);
+ verifyDraw(2, 0.25);
+
+ gl.bindVertexArray(null);
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+
+ // Disable global vertex attrib array
+ gl.disableVertexAttribArray(opt_positionLocation);
+ gl.disableVertexAttribArray(opt_texcoordLocation);
+
+ // Draw with values.
+ var positionLoc = 0;
+ var colorLoc = 1;
+ var gridRes = 1;
+ wtu.setupIndexedQuad(gl, gridRes, positionLoc);
+ // Set the vertex color to red.
+ gl.vertexAttrib4f(colorLoc, 1, 0, 0, 1);
+
+ var vao0 = gl.createVertexArray();
+ gl.bindVertexArray(vao0);
+ var program = wtu.setupSimpleVertexColorProgram(gl, positionLoc, colorLoc);
+ wtu.setupIndexedQuad(gl, gridRes, positionLoc);
+ // Set the vertex color to green.
+ gl.vertexAttrib4f(colorLoc, 0, 1, 0, 1);
+ wtu.clearAndDrawIndexedQuad(gl, gridRes);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green")
+ gl.deleteVertexArray(vao0);
+ wtu.clearAndDrawIndexedQuad(gl, gridRes);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green")
+}
+
+function runUnboundDeleteTests() {
+ debug("Testing using buffers that are deleted when attached to unbound VAOs");
+
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position", "a_color"]);
+ gl.useProgram(program);
+
+ var positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array([
+ 1.0, 1.0,
+ -1.0, 1.0,
+ -1.0, -1.0,
+ 1.0, -1.0]),
+ gl.STATIC_DRAW);
+
+ var colors = [
+ [255, 0, 0, 255],
+ [ 0, 255, 0, 255],
+ [ 0, 0, 255, 255],
+ [ 0, 255, 255, 255]
+ ];
+ var colorBuffers = [];
+ var elementBuffers = [];
+ var vaos = [];
+ for (var ii = 0; ii < colors.length; ++ii) {
+ var vao = gl.createVertexArray();
+ vaos.push(vao);
+ gl.bindVertexArray(vao);
+ // Set the position buffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+ var elementBuffer = gl.createBuffer();
+ elementBuffers.push(elementBuffer);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+ gl.bufferData(
+ gl.ELEMENT_ARRAY_BUFFER,
+ new Uint8Array([0, 1, 2, 0, 2, 3]),
+ gl.STATIC_DRAW);
+
+ // Setup the color attrib
+ var color = colors[ii];
+ if (ii < 3) {
+ var colorBuffer = gl.createBuffer();
+ colorBuffers.push(colorBuffer);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+ [ color[0], color[1], color[2], color[3],
+ color[0], color[1], color[2], color[3],
+ color[0], color[1], color[2], color[3],
+ color[0], color[1], color[2], color[3]
+ ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+ } else {
+ gl.vertexAttrib4f(1, color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
+ }
+ }
+
+ // delete the color buffers AND the position buffer.
+ gl.bindVertexArray(null);
+ for (var ii = 0; ii < colorBuffers.length; ++ii) {
+ gl.deleteBuffer(colorBuffers[ii]);
+ gl.deleteBuffer(elementBuffers[ii]);
+ gl.bindVertexArray(vaos[ii]);
+ var boundBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+ // The buffers should still be valid at this point, since it was attached to the VAO
+ if(boundBuffer != colorBuffers[ii]) {
+ testFailed("buffer removed too early");
+ }
+ }
+ gl.bindVertexArray(null);
+ gl.deleteBuffer(positionBuffer);
+
+ // Render with the deleted buffers. As they are referenced by VAOs they
+ // must still be around.
+ for (var ii = 0; ii < colors.length; ++ii) {
+ var color = colors[ii];
+ gl.bindVertexArray(vaos[ii]);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ wtu.checkCanvas(gl, color, "should be " + color);
+ }
+
+ // Clean up.
+ for (var ii = 0; ii < colorBuffers.length; ++ii) {
+ gl.deleteVertexArray(vaos[ii]);
+ }
+
+ for (var ii = 0; ii < colorBuffers.length; ++ii) {
+ // The buffers should no longer be valid now that the VAOs are deleted
+ if(gl.isBuffer(colorBuffers[ii])) {
+ testFailed("buffer not properly cleaned up after VAO deletion");
+ }
+ }
+}
+
+function runBoundDeleteTests() {
+ debug("Testing using buffers that are deleted when attached to bound VAOs");
+
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position", "a_color"]);
+ gl.useProgram(program);
+
+ var positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array([
+ 1.0, 1.0,
+ -1.0, 1.0,
+ -1.0, -1.0,
+ 1.0, -1.0]),
+ gl.STATIC_DRAW);
+
+ // Setup the color attrib
+ var colorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+ [ 255, 0, 0, 255,
+ 0, 255, 0, 255,
+ 0, 0, 255, 255,
+ 0, 255, 255, 255
+ ]), gl.STATIC_DRAW);
+
+ var vaos = [];
+ var elementBuffers = [];
+ for (var ii = 0; ii < 4; ++ii) {
+ var vao = gl.createVertexArray();
+ vaos.push(vao);
+ gl.bindVertexArray(vao);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+ var elementBuffer = gl.createBuffer();
+ elementBuffers.push(elementBuffer);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+ gl.bufferData(
+ gl.ELEMENT_ARRAY_BUFFER,
+ new Uint8Array([0, 1, 2, 0, 2, 3]),
+ gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+ }
+
+ // delete the color buffers AND the position buffer, that are bound to the current VAO
+ for (var ii = 0; ii < vaos.length; ++ii) {
+ gl.bindVertexArray(vaos[ii]);
+
+ gl.deleteBuffer(colorBuffer);
+ gl.deleteBuffer(positionBuffer);
+
+ // After the first iteration, deleteBuffer will be a no-op, and will not unbind its matching
+ // bind points on the now-bound VAO like it did on the first iteration.
+ var expectRetained = (ii != 0);
+ var shouldBeStr = (expectRetained ? "retained" : "cleared");
+
+ var boundPositionBuffer = gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+ if (expectRetained != (boundPositionBuffer == positionBuffer)) {
+ testFailed("Position attrib stored buffer should be " + shouldBeStr + ".");
+ }
+
+ var boundColorBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+ if (expectRetained != (boundColorBuffer == colorBuffer)) {
+ testFailed("Color attrib stored buffer should be " + shouldBeStr + ".");
+ }
+
+ // If retained, everything should still work. If cleared, drawing should now fail.
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ var expectedError = (expectRetained ? gl.NO_ERROR : gl.INVALID_OPERATION);
+ wtu.glErrorShouldBe(gl, expectedError,
+ "Draw call should " + (expectRetained ? "not " : "") + "fail.");
+
+ if (gl.isBuffer(positionBuffer)) {
+ testFailed("References from unbound VAOs don't keep Position buffer alive.");
+ }
+ if (gl.isBuffer(colorBuffer)) {
+ testFailed("References from unbound VAOs don't keep Color buffer alive");
+ }
+ }
+}
+
+function runArrayBufferBindTests() {
+ debug("Testing that VAOs don't effect ARRAY_BUFFER binding.");
+
+ gl.bindVertexArray(null);
+
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_color", "a_position"]);
+ gl.useProgram(program);
+
+ // create shared element buuffer
+ var elementBuffer = gl.createBuffer();
+ // bind to default
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+ gl.bufferData(
+ gl.ELEMENT_ARRAY_BUFFER,
+ new Uint8Array([0, 1, 2, 0, 2, 3]),
+ gl.STATIC_DRAW);
+
+ // first create the buffers for no vao draw.
+ var nonVAOColorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, nonVAOColorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+ [ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ ]), gl.STATIC_DRAW);
+
+ // shared position buffer.
+ var positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array([
+ 1.0, 1.0,
+ -1.0, 1.0,
+ -1.0, -1.0,
+ 1.0, -1.0]),
+ gl.STATIC_DRAW);
+
+ // attach position buffer to default
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+ // now create vao
+ var vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+
+ // attach the position buffer vao
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+ var vaoColorBuffer = gl.createBuffer();
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, vaoColorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array(
+ [ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+
+ // now set the buffer back to the nonVAOColorBuffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, nonVAOColorBuffer);
+
+ // bind to vao
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
+
+ // unbind vao
+ gl.bindVertexArray(null);
+
+ // At this point the nonVAOColorBuffer should be still be bound.
+ // If the WebGL impl is emulating VAOs it must make sure
+ // it correctly restores this binding.
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, true, 0, 0);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../js/js-test-post.js"></script>
+
+</body>
+</html>