DO NOT MERGE: Sparse resources fixes am: ae793c389b  -s ours
am: ce25f76fbb  -s ours

Change-Id: I8fa668d939b6c45df4590f823b029536895b4574
diff --git a/Android.mk b/Android.mk
index ac2c53c..7d60924 100644
--- a/Android.mk
+++ b/Android.mk
@@ -555,6 +555,7 @@
 	modules/egl/teglTestPackageEntry.cpp \
 	modules/egl/teglThreadCleanUpTests.cpp \
 	modules/egl/teglVGRenderUtil.cpp \
+	modules/egl/teglWideColorTests.cpp \
 	modules/gles2/accuracy/es2aAccuracyTests.cpp \
 	modules/gles2/accuracy/es2aTextureFilteringTests.cpp \
 	modules/gles2/accuracy/es2aTextureMipmapTests.cpp \
@@ -811,9 +812,11 @@
 	modules/gles31/functional/es31fDebugTests.cpp \
 	modules/gles31/functional/es31fDefaultVertexArrayObjectTests.cpp \
 	modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp \
+	modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp \
 	modules/gles31/functional/es31fDrawTests.cpp \
 	modules/gles31/functional/es31fFboColorbufferTests.cpp \
 	modules/gles31/functional/es31fFboNoAttachmentTests.cpp \
+	modules/gles31/functional/es31fFboSRGBWriteControlTests.cpp \
 	modules/gles31/functional/es31fFboTestCase.cpp \
 	modules/gles31/functional/es31fFboTestUtil.cpp \
 	modules/gles31/functional/es31fFramebufferDefaultStateQueryTests.cpp \
@@ -830,11 +833,14 @@
 	modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp \
 	modules/gles31/functional/es31fNegativeAtomicCounterTests.cpp \
 	modules/gles31/functional/es31fNegativeBufferApiTests.cpp \
+	modules/gles31/functional/es31fNegativeComputeTests.cpp \
 	modules/gles31/functional/es31fNegativeFragmentApiTests.cpp \
 	modules/gles31/functional/es31fNegativePreciseTests.cpp \
 	modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp \
+	modules/gles31/functional/es31fNegativeSampleVariablesTests.cpp \
 	modules/gles31/functional/es31fNegativeShaderApiTests.cpp \
 	modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp \
+	modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.cpp \
 	modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp \
 	modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp \
 	modules/gles31/functional/es31fNegativeShaderStorageTests.cpp \
@@ -863,6 +869,7 @@
 	modules/gles31/functional/es31fShaderAtomicOpTests.cpp \
 	modules/gles31/functional/es31fShaderBuiltinConstantTests.cpp \
 	modules/gles31/functional/es31fShaderCommonFunctionTests.cpp \
+	modules/gles31/functional/es31fShaderFramebufferFetchTests.cpp \
 	modules/gles31/functional/es31fShaderHelperInvocationTests.cpp \
 	modules/gles31/functional/es31fShaderImageLoadStoreTests.cpp \
 	modules/gles31/functional/es31fShaderIntegerFunctionTests.cpp \
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..579961c
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,7 @@
+tinazh@google.com
+chrisforbes@google.com
+
+# We miss you
+# phaulos@google.com
+# kraita@google.com
+# misojarvi@google.com
diff --git a/android/cts/Android.mk b/android/cts/Android.mk
index 2eb34f7..762eb2a 100644
--- a/android/cts/Android.mk
+++ b/android/cts/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_MODULE_TAGS := optional
 
 # Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
 LOCAL_SDK_VERSION := 22
 
diff --git a/android/cts/master/egl-master.txt b/android/cts/master/egl-master.txt
index 4a2a176..3d71c30 100644
--- a/android/cts/master/egl-master.txt
+++ b/android/cts/master/egl-master.txt
@@ -2382,6 +2382,7 @@
 dEQP-EGL.functional.get_proc_address.extension.egl_hi_clientpixmap
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_cl_event2
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_debug
+dEQP-EGL.functional.get_proc_address.extension.egl_khr_display_reference
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_fence_sync
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_image
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_image_base
@@ -2409,6 +2410,7 @@
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_stream_sync
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_sync
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_system_time
+dEQP-EGL.functional.get_proc_address.extension.egl_ext_compositor
 dEQP-EGL.functional.get_proc_address.extension.gl_apple_copy_texture_levels
 dEQP-EGL.functional.get_proc_address.extension.gl_apple_framebuffer_multisample
 dEQP-EGL.functional.get_proc_address.extension.gl_apple_sync
@@ -2447,6 +2449,7 @@
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_base_instance
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_blend_func_extended
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_buffer_storage
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_clear_texture
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_copy_image
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_debug_label
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_debug_marker
@@ -2455,20 +2458,34 @@
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_draw_buffers_indexed
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_draw_elements_base_vertex
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_draw_instanced
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_draw_transform_feedback
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_external_buffer
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_geometry_shader
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_instanced_arrays
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_memory_object
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_memory_object_fd
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_memory_object_win32
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_multi_draw_indirect
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_multiview_draw_buffers
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_occlusion_query_boolean
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_polygon_offset_clamp
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_primitive_bounding_box
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_raster_multisample
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_semaphore
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_semaphore_fd
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_semaphore_win32
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_separate_shader_objects
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_shader_pixel_local_storage2
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_sparse_texture
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_tessellation_shader
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_texture_border_clamp
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_texture_buffer
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_texture_filter_minmax
 dEQP-EGL.functional.get_proc_address.extension.gl_ext_texture_view
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_win32_keyed_mutex
+dEQP-EGL.functional.get_proc_address.extension.gl_ext_window_rectangles
+dEQP-EGL.functional.get_proc_address.extension.gl_img_bindless_texture
+dEQP-EGL.functional.get_proc_address.extension.gl_img_framebuffer_downsample
 dEQP-EGL.functional.get_proc_address.extension.gl_intel_framebuffer_cmaa
 dEQP-EGL.functional.get_proc_address.extension.gl_intel_performance_query
 dEQP-EGL.functional.get_proc_address.extension.gl_khr_blend_equation_advanced
@@ -2478,14 +2495,17 @@
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_blend_equation_advanced
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_conditional_render
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_conservative_raster
+dEQP-EGL.functional.get_proc_address.extension.gl_nv_conservative_raster_pre_snap_triangles
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_copy_buffer
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_coverage_sample
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_draw_buffers
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_draw_instanced
+dEQP-EGL.functional.get_proc_address.extension.gl_nv_draw_vulkan_image
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_fragment_coverage_to_color
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_framebuffer_blit
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_framebuffer_mixed_samples
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_framebuffer_multisample
+dEQP-EGL.functional.get_proc_address.extension.gl_nv_gpu_shader5
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_instanced_arrays
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_internalformat_sample_query
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_non_square_matrices
@@ -2494,6 +2514,7 @@
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_read_buffer
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_sample_locations
 dEQP-EGL.functional.get_proc_address.extension.gl_nv_viewport_array
+dEQP-EGL.functional.get_proc_address.extension.gl_nv_viewport_swizzle
 dEQP-EGL.functional.get_proc_address.extension.gl_oes_copy_image
 dEQP-EGL.functional.get_proc_address.extension.gl_oes_draw_buffers_indexed
 dEQP-EGL.functional.get_proc_address.extension.gl_oes_draw_elements_base_vertex
@@ -2507,8 +2528,12 @@
 dEQP-EGL.functional.get_proc_address.extension.gl_oes_texture_buffer
 dEQP-EGL.functional.get_proc_address.extension.gl_oes_texture_storage_multisample_2d_array
 dEQP-EGL.functional.get_proc_address.extension.gl_oes_texture_view
+dEQP-EGL.functional.get_proc_address.extension.gl_oes_viewport_array
 dEQP-EGL.functional.get_proc_address.extension.gl_ovr_multiview
+dEQP-EGL.functional.get_proc_address.extension.gl_ovr_multiview_multisampled_render_to_texture
 dEQP-EGL.functional.get_proc_address.extension.gl_qcom_alpha_test
+dEQP-EGL.functional.get_proc_address.extension.gl_qcom_framebuffer_foveated
+dEQP-EGL.functional.get_proc_address.extension.gl_qcom_shader_framebuffer_fetch_noncoherent
 dEQP-EGL.functional.get_proc_address.core.egl
 dEQP-EGL.functional.get_proc_address.core.gles
 dEQP-EGL.functional.get_proc_address.core.gles2
@@ -3620,3 +3645,28 @@
 dEQP-EGL.functional.robustness.reset_context.fixed_function_pipeline.reset_status.vertex_buffer_out_of_bounds
 dEQP-EGL.functional.robustness.negative_context.invalid_robust_context_creation
 dEQP-EGL.functional.robustness.negative_context.invalid_robust_shared_context_creation
+dEQP-EGL.functional.robustness.negative_context.invalid_notification_strategy_enum
+dEQP-EGL.functional.wide_color.fp16
+dEQP-EGL.functional.wide_color.1010102
+dEQP-EGL.functional.wide_color.window_fp16_default_colorspace
+dEQP-EGL.functional.wide_color.window_fp16_colorspace_srgb
+dEQP-EGL.functional.wide_color.window_fp16_colorspace_p3
+dEQP-EGL.functional.wide_color.window_fp16_colorspace_scrgb
+dEQP-EGL.functional.wide_color.window_fp16_colorspace_scrgb_linear
+dEQP-EGL.functional.wide_color.pbuffer_fp16_default_colorspace
+dEQP-EGL.functional.wide_color.pbuffer_fp16_colorspace_srgb
+dEQP-EGL.functional.wide_color.pbuffer_fp16_colorspace_p3
+dEQP-EGL.functional.wide_color.pbuffer_fp16_colorspace_scrgb
+dEQP-EGL.functional.wide_color.pbuffer_fp16_colorspace_scrgb_linear
+dEQP-EGL.functional.wide_color.window_1010102_colorspace_default
+dEQP-EGL.functional.wide_color.window_1010102_colorspace_srgb
+dEQP-EGL.functional.wide_color.window_1010102_colorspace_p3
+dEQP-EGL.functional.wide_color.pbuffer_1010102_colorspace_default
+dEQP-EGL.functional.wide_color.pbuffer_1010102_colorspace_srgb
+dEQP-EGL.functional.wide_color.pbuffer_1010102_colorspace_p3
+dEQP-EGL.functional.wide_color.window_8888_colorspace_default
+dEQP-EGL.functional.wide_color.window_8888_colorspace_srgb
+dEQP-EGL.functional.wide_color.window_8888_colorspace_p3
+dEQP-EGL.functional.wide_color.pbuffer_8888_colorspace_default
+dEQP-EGL.functional.wide_color.pbuffer_8888_colorspace_srgb
+dEQP-EGL.functional.wide_color.pbuffer_8888_colorspace_p3
diff --git a/android/cts/master/gles3-master.txt b/android/cts/master/gles3-master.txt
index 37e6728..8156022 100644
--- a/android/cts/master/gles3-master.txt
+++ b/android/cts/master/gles3-master.txt
@@ -796,6 +796,8 @@
 dEQP-GLES3.functional.shaders.preprocessor.basic.empty_function_fragment
 dEQP-GLES3.functional.shaders.preprocessor.basic.empty_directive_vertex
 dEQP-GLES3.functional.shaders.preprocessor.basic.empty_directive_fragment
+dEQP-GLES3.functional.shaders.preprocessor.basic.identifier_with_double_underscore_vertex
+dEQP-GLES3.functional.shaders.preprocessor.basic.identifier_with_double_underscore_fragment
 dEQP-GLES3.functional.shaders.preprocessor.definitions.define_value_and_function_vertex
 dEQP-GLES3.functional.shaders.preprocessor.definitions.define_value_and_function_fragment
 dEQP-GLES3.functional.shaders.preprocessor.definitions.undefine_object_invalid_syntax_vertex
@@ -1482,6 +1484,7 @@
 dEQP-GLES3.functional.shaders.linkage.varying.rules.type_mismatch_1
 dEQP-GLES3.functional.shaders.linkage.varying.rules.type_mismatch_2
 dEQP-GLES3.functional.shaders.linkage.varying.rules.type_mismatch_3
+dEQP-GLES3.functional.shaders.linkage.varying.rules.struct_type_mismatch_1
 dEQP-GLES3.functional.shaders.linkage.varying.rules.struct_type_mismatch_2
 dEQP-GLES3.functional.shaders.linkage.varying.rules.struct_type_mismatch_3
 dEQP-GLES3.functional.shaders.linkage.varying.rules.interpolation_mismatch_1
@@ -1537,6 +1540,7 @@
 dEQP-GLES3.functional.shaders.linkage.varying.struct.uvec3
 dEQP-GLES3.functional.shaders.linkage.varying.struct.uvec4
 dEQP-GLES3.functional.shaders.linkage.varying.struct.float_vec3
+dEQP-GLES3.functional.shaders.linkage.varying.struct.float_uvec2_vec3
 dEQP-GLES3.functional.shaders.linkage.varying.interpolation.smooth
 dEQP-GLES3.functional.shaders.linkage.varying.interpolation.centroid
 dEQP-GLES3.functional.shaders.linkage.varying.interpolation.flat
@@ -2826,6 +2830,8 @@
 dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_array_without_instance_name_1_fragment
 dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_array_without_instance_name_2_vertex
 dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_array_without_instance_name_2_fragment
+dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_in_vertex
+dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_in_fragment
 dEQP-GLES3.functional.shaders.swizzles.vector_swizzles.mediump_vec2_x_vertex
 dEQP-GLES3.functional.shaders.swizzles.vector_swizzles.mediump_vec2_x_fragment
 dEQP-GLES3.functional.shaders.swizzles.vector_swizzles.mediump_vec2_xx_vertex
@@ -3474,6 +3480,550 @@
 dEQP-GLES3.functional.shaders.swizzles.vector_swizzles.mediump_bvec4_rgrr_fragment
 dEQP-GLES3.functional.shaders.swizzles.vector_swizzles.mediump_bvec4_bbab_vertex
 dEQP-GLES3.functional.shaders.swizzles.vector_swizzles.mediump_bvec4_bbab_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_vec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_add.mediump_ivec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_vec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_subtract.mediump_ivec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_vec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_multiply.mediump_ivec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_vec4_zzzz_zzzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_xx_xx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_xx_xx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_xy_yx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_xy_yx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_yx_xy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_yx_xy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_yxyx_xyxy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec2_yxyx_xyxy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_z_z_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_z_z_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xz_zx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xz_zx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zz_zz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zz_zz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xyz_yzx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xyz_yzx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zyx_yxz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zyx_yxz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xxx_xxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xxx_xxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zzz_zzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zzz_zzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zzy_zyz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zzy_zyz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_yxy_xyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_yxy_xyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xzx_zxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xzx_zxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xyyx_yyxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_xyyx_yyxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zxyz_xyzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec3_zxyz_xyzz_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_x_x_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_x_x_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_w_w_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_w_w_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wx_xw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wx_xw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wz_zw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wz_zw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_www_www_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_www_www_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_yyw_ywy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_yyw_ywy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wzy_zyw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wzy_zyw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_xyzw_yzwx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_xyzw_yzwx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wzyx_zyxw_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wzyx_zyxw_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_xyxy_yxyx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_xyxy_yxyx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_yzzy_zzyy_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_yzzy_zzyy_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wxww_xwww_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_wxww_xwww_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_xyxx_yxxx_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_xyxx_yxxx_fragment
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_zzzz_zzzz_vertex
+dEQP-GLES3.functional.shaders.swizzle_math_operations.vector_divide.mediump_ivec4_zzzz_zzzz_fragment
 dEQP-GLES3.functional.shaders.functions.datatypes.float_float_vertex
 dEQP-GLES3.functional.shaders.functions.datatypes.float_float_fragment
 dEQP-GLES3.functional.shaders.functions.datatypes.float_vec2_vertex
@@ -3899,6 +4449,22 @@
 dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style3_fragment
 dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style4_vertex
 dEQP-GLES3.functional.shaders.arrays.invalid.constructor_c_style4_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_16_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_16_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_32_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_32_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_64_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_64_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_128_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_128_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_16_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_16_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_32_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_32_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_64_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_64_fragment
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_128_vertex
+dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_128_fragment
 dEQP-GLES3.functional.shaders.keywords.keywords.const_vertex
 dEQP-GLES3.functional.shaders.keywords.keywords.const_fragment
 dEQP-GLES3.functional.shaders.keywords.keywords.uniform_vertex
@@ -15593,8 +16159,30 @@
 dEQP-GLES3.functional.shaders.texture_functions.texelfetch.isampler3d_fragment
 dEQP-GLES3.functional.shaders.texture_functions.texelfetch.usampler3d_vertex
 dEQP-GLES3.functional.shaders.texture_functions.texelfetch.usampler3d_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_fixed_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_fixed_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_float_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_float_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2d_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2d_fragment
 dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler2d_vertex
 dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler2d_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_fixed_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_fixed_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_float_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_float_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2darray_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2darray_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler2darray_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler2darray_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_fixed_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_fixed_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_float_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_float_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler3d_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler3d_fragment
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler3d_vertex
+dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler3d_fragment
 dEQP-GLES3.functional.shaders.texture_functions.texturesize.sampler2d_fixed_vertex
 dEQP-GLES3.functional.shaders.texture_functions.texturesize.sampler2d_fixed_fragment
 dEQP-GLES3.functional.shaders.texture_functions.texturesize.sampler2d_float_vertex
@@ -17393,8 +17981,11 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat2x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat2x4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat3x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat3x4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat4x2
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_vertex.mat2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_vertex.mat2x3
@@ -17408,8 +17999,11 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat2x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat2x4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat3x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat3x4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat4x2
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_vertex.mat2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_vertex.mat2x3
@@ -17423,8 +18017,11 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat2x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat2x4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat3x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat3x4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat4x2
+dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.outerproduct.lowp_vertex.mat2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.outerproduct.lowp_vertex.mat2x3
@@ -17490,8 +18087,11 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_vertex.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_vertex.mat4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat2
+dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat2x3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat2x4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat3x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat3x4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat4x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat4
@@ -17505,8 +18105,11 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_vertex.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_vertex.mat4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat2
+dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat2x3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat2x4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat3x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat3x4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat4x2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat4
@@ -21903,6 +22506,11 @@
 dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_linear_mirror_clamp
 dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_linear_mirror_repeat
 dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_linear_mirror_mirror
+dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_nearest_nearest_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_nearest_linear_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_linear_nearest_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_linear_linear_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_linear_linear_clamp_mirror
 dEQP-GLES3.functional.texture.filtering.cube.formats.rgba16f_nearest
 dEQP-GLES3.functional.texture.filtering.cube.formats.rgba16f_linear
 dEQP-GLES3.functional.texture.filtering.cube.formats.rgba16f_nearest_mipmap_nearest
@@ -22121,10 +22729,22 @@
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_linear_mirror_clamp
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_linear_mirror_repeat
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_linear_mirror_mirror
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_nearest_nearest_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_nearest_linear_clamp_clamp
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_clamp_mirror
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_mirror_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_mirror_mirror
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_clamp_mirror
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_mirror_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_mirror_mirror
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_linear_nearest_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_linear_linear_clamp_clamp
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_linear_nearest_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_linear_nearest_mirror_clamp
 dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_linear_linear_clamp_clamp
+dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_linear_linear_mirror_clamp
 dEQP-GLES3.functional.texture.filtering.3d.formats.rgba16f_nearest
 dEQP-GLES3.functional.texture.filtering.3d.formats.rgba16f_linear
 dEQP-GLES3.functional.texture.filtering.3d.formats.rgba16f_nearest_mipmap_nearest
@@ -23589,22 +24209,28 @@
 dEQP-GLES3.functional.texture.specification.basic_copytexsubimage2d.cube_rgb
 dEQP-GLES3.functional.texture.specification.basic_copytexsubimage2d.cube_rgba
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba32f_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba32f_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba32i_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba32ui_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba16f_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba16i_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba16i_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba16ui_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba8_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba8i_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba8ui_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.srgb8_alpha8_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.srgb8_alpha8_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb10_a2_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb10_a2_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb10_a2ui_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb10_a2ui_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba4_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba4_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb5_a1_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba8_snorm_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb565_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb565_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r11f_g11f_b10f_2d_array
@@ -23616,7 +24242,9 @@
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb16ui_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8_snorm_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8i_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8i_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8ui_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8ui_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.srgb8_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb9_e5_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg32f_2d_array
@@ -23625,20 +24253,30 @@
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg16f_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg16i_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg16ui_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg16ui_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg8_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg8i_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg8i_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg8ui_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg8_snorm_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32f_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32f_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32i_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32i_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32ui_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32ui_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16f_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16f_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16i_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16ui_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16ui_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8i_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8i_3d
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8ui_2d_array
 dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8_snorm_2d_array
+dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8_snorm_3d
 dEQP-GLES3.functional.texture.specification.teximage3d_unpack_params.rgb8_image_height
 dEQP-GLES3.functional.texture.specification.teximage3d_unpack_params.rgb8_row_length
 dEQP-GLES3.functional.texture.specification.teximage3d_unpack_params.rgb8_skip_images
@@ -23952,35 +24590,56 @@
 dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth_component16_2d_array
 dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth32f_stencil8_2d_array
 dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth24_stencil8_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32i_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16f_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.srgb8_alpha8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.srgb8_alpha8_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb10_a2_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb10_a2_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb10_a2ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb10_a2ui_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba4_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba4_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb5_a1_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb5_a1_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8_snorm_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8_snorm_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb565_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb565_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r11f_g11f_b10f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r11f_g11f_b10f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16ui_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8_snorm_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8ui_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.srgb8_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb9_e5_cube
@@ -23988,32 +24647,50 @@
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg32f_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg32i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg32i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg32ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg32ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8i_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8_snorm_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8_snorm_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32i_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16i_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16ui_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8i_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8i_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8ui_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8ui_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8_snorm_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8_snorm_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component32f_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component32f_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component24_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component24_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component16_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component16_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth32f_stencil8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth32f_stencil8_cube
+dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth24_stencil8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth24_stencil8_cube
 dEQP-GLES3.functional.texture.specification.texstorage2d.size.2d_1x1_1_levels
 dEQP-GLES3.functional.texture.specification.texstorage2d.size.2d_2x2_2_levels
@@ -24028,20 +24705,69 @@
 dEQP-GLES3.functional.texture.specification.texstorage2d.size.cube_57x57_6_levels
 dEQP-GLES3.functional.texture.specification.texstorage2d.size.cube_64x64_4_levels
 dEQP-GLES3.functional.texture.specification.texstorage2d.size.cube_64x64_7_levels
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba32f_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba32i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba32ui_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16f_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16ui_2d_array
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8ui_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.srgb8_alpha8_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb10_a2_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb10_a2_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb10_a2ui_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba4_2d_array
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba4_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb5_a1_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8_snorm_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb8_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb565_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.r11f_g11f_b10f_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r11f_g11f_b10f_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb32i_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb32ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16f_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb8i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb8ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.srgb8_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb9_e5_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32f_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32ui_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg16f_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg16i_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg16ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8_snorm_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8_snorm_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32f_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32i_3d
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32ui_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16f_2d_array
 dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16f_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8i_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8i_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8ui_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8_snorm_2d_array
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8_snorm_3d
+dEQP-GLES3.functional.texture.specification.texstorage3d.format.depth32f_stencil8_2d_array
 dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_1x1x1_1_levels
 dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_2x2x2_2_levels
 dEQP-GLES3.functional.texture.specification.texstorage3d.size.2d_array_64x32x3_7_levels
@@ -32768,6 +33494,7 @@
 dEQP-GLES3.functional.ubo.random.basic_arrays.12
 dEQP-GLES3.functional.ubo.random.basic_arrays.13
 dEQP-GLES3.functional.ubo.random.basic_arrays.14
+dEQP-GLES3.functional.ubo.random.basic_arrays.15
 dEQP-GLES3.functional.ubo.random.basic_arrays.16
 dEQP-GLES3.functional.ubo.random.basic_arrays.17
 dEQP-GLES3.functional.ubo.random.basic_arrays.18
@@ -32840,6 +33567,7 @@
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.11
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.12
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.13
+dEQP-GLES3.functional.ubo.random.nested_structs_arrays.14
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.15
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.16
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.17
@@ -32986,6 +33714,7 @@
 dEQP-GLES3.functional.ubo.random.all_shared_buffer.34
 dEQP-GLES3.functional.ubo.random.all_shared_buffer.35
 dEQP-GLES3.functional.ubo.random.all_shared_buffer.36
+dEQP-GLES3.functional.ubo.random.all_shared_buffer.37
 dEQP-GLES3.functional.ubo.random.all_shared_buffer.38
 dEQP-GLES3.functional.ubo.random.all_shared_buffer.39
 dEQP-GLES3.functional.ubo.random.all_shared_buffer.40
@@ -35230,6 +35959,7 @@
 dEQP-GLES3.functional.attribute_location.bind_hole.float
 dEQP-GLES3.functional.attribute_location.bind_hole.vec2
 dEQP-GLES3.functional.attribute_location.bind_hole.vec3
+dEQP-GLES3.functional.attribute_location.bind_hole.vec4
 dEQP-GLES3.functional.attribute_location.bind_hole.mat2
 dEQP-GLES3.functional.attribute_location.bind_hole.mat3
 dEQP-GLES3.functional.attribute_location.bind_hole.mat4
@@ -35404,6 +36134,54 @@
 dEQP-GLES3.functional.attribute_location.mixed_hole.mat4x2
 dEQP-GLES3.functional.attribute_location.mixed_hole.mat4x3
 dEQP-GLES3.functional.attribute_location.mixed_hole.mat4x4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.float
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.vec2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.vec3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.vec4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.int
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.ivec2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.ivec3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.ivec4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.uint
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.uvec2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.uvec3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.uvec4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3x2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3x3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3x4
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4x2
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4x3
+dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4x4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.float
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.vec2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.vec3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.vec4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.int
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.ivec2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.ivec3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.ivec4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uint
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uvec2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uvec3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uvec4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3x2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3x3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3x4
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4x2
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4x3
+dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4x4
 dEQP-GLES3.functional.fragment_out.basic.float.rgba32f_lowp_float
 dEQP-GLES3.functional.fragment_out.basic.float.rgba32f_lowp_vec2
 dEQP-GLES3.functional.fragment_out.basic.float.rgba32f_lowp_vec3
@@ -39583,14 +40361,23 @@
 dEQP-GLES3.functional.state_query.integers64.max_combined_fragment_uniform_components_getfloat
 dEQP-GLES3.functional.state_query.floats.depth_range_getboolean
 dEQP-GLES3.functional.state_query.floats.depth_range_getinteger
+dEQP-GLES3.functional.state_query.floats.depth_range_getinteger64
 dEQP-GLES3.functional.state_query.floats.depth_range_getfloat
 dEQP-GLES3.functional.state_query.floats.line_width_getboolean
+dEQP-GLES3.functional.state_query.floats.line_width_getinteger
+dEQP-GLES3.functional.state_query.floats.line_width_getinteger64
 dEQP-GLES3.functional.state_query.floats.line_width_getfloat
 dEQP-GLES3.functional.state_query.floats.polygon_offset_factor_getboolean
+dEQP-GLES3.functional.state_query.floats.polygon_offset_factor_getinteger
+dEQP-GLES3.functional.state_query.floats.polygon_offset_factor_getinteger64
 dEQP-GLES3.functional.state_query.floats.polygon_offset_factor_getfloat
 dEQP-GLES3.functional.state_query.floats.polygon_offset_units_getboolean
+dEQP-GLES3.functional.state_query.floats.polygon_offset_units_getinteger
+dEQP-GLES3.functional.state_query.floats.polygon_offset_units_getinteger64
 dEQP-GLES3.functional.state_query.floats.polygon_offset_units_getfloat
 dEQP-GLES3.functional.state_query.floats.sample_coverage_value_getboolean
+dEQP-GLES3.functional.state_query.floats.sample_coverage_value_getinteger
+dEQP-GLES3.functional.state_query.floats.sample_coverage_value_getinteger64
 dEQP-GLES3.functional.state_query.floats.sample_coverage_value_getfloat
 dEQP-GLES3.functional.state_query.floats.blend_color_getboolean
 dEQP-GLES3.functional.state_query.floats.blend_color_getinteger
@@ -39769,7 +40556,9 @@
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_min_filter_getsamplerparameteri
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_min_filter_getsamplerparameterf
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_min_lod_getsamplerparameteri
+dEQP-GLES3.functional.state_query.sampler.sampler_texture_min_lod_getsamplerparameterf
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_max_lod_getsamplerparameteri
+dEQP-GLES3.functional.state_query.sampler.sampler_texture_max_lod_getsamplerparameterf
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_compare_mode_getsamplerparameteri
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_compare_mode_getsamplerparameterf
 dEQP-GLES3.functional.state_query.sampler.sampler_texture_compare_func_getsamplerparameteri
@@ -39798,6 +40587,7 @@
 dEQP-GLES3.functional.state_query.fbo.framebuffer_attachment_x_size_texture
 dEQP-GLES3.functional.state_query.fbo.framebuffer_unspecified_attachment_color_encoding
 dEQP-GLES3.functional.state_query.fbo.framebuffer_unspecified_attachment_component_type
+dEQP-GLES3.functional.state_query.fbo.framebuffer_unspecified_attachment_x_size_rbo
 dEQP-GLES3.functional.state_query.fbo.framebuffer_unspecified_attachment_x_size_texture
 dEQP-GLES3.functional.state_query.rbo.renderbuffer_size
 dEQP-GLES3.functional.state_query.rbo.renderbuffer_internal_format
@@ -39819,13 +40609,16 @@
 dEQP-GLES3.functional.state_query.shader.program_validate_status
 dEQP-GLES3.functional.state_query.shader.program_attached_shaders
 dEQP-GLES3.functional.state_query.shader.program_active_uniform_name
+dEQP-GLES3.functional.state_query.shader.program_active_uniform_types
 dEQP-GLES3.functional.state_query.shader.program_active_uniform_blocks
 dEQP-GLES3.functional.state_query.shader.program_binary
 dEQP-GLES3.functional.state_query.shader.transform_feedback
 dEQP-GLES3.functional.state_query.shader.active_attributes
 dEQP-GLES3.functional.state_query.shader.vertex_attrib_size
+dEQP-GLES3.functional.state_query.shader.vertex_attrib_type
 dEQP-GLES3.functional.state_query.shader.vertex_attrib_stride
 dEQP-GLES3.functional.state_query.shader.vertex_attrib_normalized
+dEQP-GLES3.functional.state_query.shader.vertex_attrib_integer
 dEQP-GLES3.functional.state_query.shader.vertex_attrib_array_enabled
 dEQP-GLES3.functional.state_query.shader.vertex_attrib_array_divisor
 dEQP-GLES3.functional.state_query.shader.vertex_attrib_array_buffer_binding
diff --git a/android/cts/master/gles31-master.txt b/android/cts/master/gles31-master.txt
index b4f78d9..34db622 100644
--- a/android/cts/master/gles31-master.txt
+++ b/android/cts/master/gles31-master.txt
@@ -5584,6 +5584,49 @@
 dEQP-GLES31.functional.shaders.uniform_block.invalid.layout_std430_fragment
 dEQP-GLES31.functional.shaders.uniform_block.invalid.global_layout_std430_vertex
 dEQP-GLES31.functional.shaders.uniform_block.invalid.global_layout_std430_fragment
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.texel_fetch
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.last_frag_data
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.fragment_discard
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.multiple_assignment
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.multiple_render_targets
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.framebuffer_texture_level
+dEQP-GLES31.functional.shaders.framebuffer_fetch.basic.framebuffer_texture_layer
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba32i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba32ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba16i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba16ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba8
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba8i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba8ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.srgb8_alpha8
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgb10_a2
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgb10_a2ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba4
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgb5_a1
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgb8
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgb565
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg32i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg32ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg16i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg16ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg8
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg8i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg8ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r32i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r32ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r16i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r16ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r8
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r8i
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r8ui
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba32f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgba16f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r11f_g11f_b10f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg32f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rg16f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r32f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.r16f
+dEQP-GLES31.functional.shaders.framebuffer_fetch.framebuffer_format.rgb16f
 dEQP-GLES31.functional.compute.basic.empty
 dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_invocation
 dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_group
@@ -16477,6 +16520,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texstorage3d
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texstorage3d_invalid_binding
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texstorage3d_invalid_levels
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.srgb_decode_texparameteri
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.srgb_decode_texparameterf
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.srgb_decode_texparameteriv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.srgb_decode_texparameterfv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.srgb_decode_texparameterIiv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.srgb_decode_texparameterIuiv
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.create_shader
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.shader_source
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.compile_shader
@@ -16544,6 +16593,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.transform_feedback_varyings
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.compile_compute_shader
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.link_compute_shader
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.srgb_decode_samplerparameteri
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.srgb_decode_samplerparameterf
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.srgb_decode_samplerparameteriv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.srgb_decode_samplerparameterfv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.srgb_decode_samplerparameterIiv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader.srgb_decode_samplerparameterIuiv
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.fragment.scissor
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.fragment.depth_func
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.fragment.viewport
@@ -16590,6 +16645,7 @@
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_arrays_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_arrays_instanced
@@ -16599,10 +16655,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_elements_instanced_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.vertex_array.draw_range_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.state.enable
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.state.disable
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.state.get_booleanv
@@ -16786,6 +16844,31 @@
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.get_programiv
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_program_queries
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.tessellation_control_invalid_vertex_count
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.oes_sample_variables.write_to_read_only_types
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.oes_sample_variables.access_built_in_types_inside_other_shaders
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.oes_sample_variables.index_outside_sample_mask_range
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.oes_sample_variables.access_built_in_types_without_extension
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.oes_sample_variables.redeclare_built_in_types
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.program_not_active
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.invalid_program_query
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.invalid_dispatch_compute_indirect
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.invalid_maximum_work_group_counts
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.invalid_maximum_work_group_sizes
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.invalid_layout_qualifiers
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.invalid_write_built_in_constants
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_uniform_block_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_shader_storage_block_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_texture_image_units_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_image_uniforms_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_shared_memory_size_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_uniform_components_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_atomic_counter_buffer_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.compute.exceed_atomic_counters_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.framebuffer_fetch.last_frag_data_not_defined
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.framebuffer_fetch.last_frag_data_readonly
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.framebuffer_fetch.invalid_inout_version
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.framebuffer_fetch.invalid_redeclaration_inout
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.framebuffer_fetch.invalid_vertex_inout
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.gen_buffers
@@ -16935,6 +17018,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.log.texture.texstorage3d
 dEQP-GLES31.functional.debug.negative_coverage.log.texture.texstorage3d_invalid_binding
 dEQP-GLES31.functional.debug.negative_coverage.log.texture.texstorage3d_invalid_levels
+dEQP-GLES31.functional.debug.negative_coverage.log.texture.srgb_decode_texparameteri
+dEQP-GLES31.functional.debug.negative_coverage.log.texture.srgb_decode_texparameterf
+dEQP-GLES31.functional.debug.negative_coverage.log.texture.srgb_decode_texparameteriv
+dEQP-GLES31.functional.debug.negative_coverage.log.texture.srgb_decode_texparameterfv
+dEQP-GLES31.functional.debug.negative_coverage.log.texture.srgb_decode_texparameterIiv
+dEQP-GLES31.functional.debug.negative_coverage.log.texture.srgb_decode_texparameterIuiv
 dEQP-GLES31.functional.debug.negative_coverage.log.shader.create_shader
 dEQP-GLES31.functional.debug.negative_coverage.log.shader.shader_source
 dEQP-GLES31.functional.debug.negative_coverage.log.shader.compile_shader
@@ -17002,6 +17091,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.log.shader.transform_feedback_varyings
 dEQP-GLES31.functional.debug.negative_coverage.log.shader.compile_compute_shader
 dEQP-GLES31.functional.debug.negative_coverage.log.shader.link_compute_shader
+dEQP-GLES31.functional.debug.negative_coverage.log.shader.srgb_decode_samplerparameteri
+dEQP-GLES31.functional.debug.negative_coverage.log.shader.srgb_decode_samplerparameterf
+dEQP-GLES31.functional.debug.negative_coverage.log.shader.srgb_decode_samplerparameteriv
+dEQP-GLES31.functional.debug.negative_coverage.log.shader.srgb_decode_samplerparameterfv
+dEQP-GLES31.functional.debug.negative_coverage.log.shader.srgb_decode_samplerparameterIiv
+dEQP-GLES31.functional.debug.negative_coverage.log.shader.srgb_decode_samplerparameterIuiv
 dEQP-GLES31.functional.debug.negative_coverage.log.fragment.scissor
 dEQP-GLES31.functional.debug.negative_coverage.log.fragment.depth_func
 dEQP-GLES31.functional.debug.negative_coverage.log.fragment.viewport
@@ -17048,6 +17143,7 @@
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_arrays_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_arrays_instanced
@@ -17057,10 +17153,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_elements_instanced_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.log.vertex_array.draw_range_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.state.enable
 dEQP-GLES31.functional.debug.negative_coverage.log.state.disable
 dEQP-GLES31.functional.debug.negative_coverage.log.state.get_booleanv
@@ -17244,6 +17342,31 @@
 dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.get_programiv
 dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_program_queries
 dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.tessellation_control_invalid_vertex_count
+dEQP-GLES31.functional.debug.negative_coverage.log.oes_sample_variables.write_to_read_only_types
+dEQP-GLES31.functional.debug.negative_coverage.log.oes_sample_variables.access_built_in_types_inside_other_shaders
+dEQP-GLES31.functional.debug.negative_coverage.log.oes_sample_variables.index_outside_sample_mask_range
+dEQP-GLES31.functional.debug.negative_coverage.log.oes_sample_variables.access_built_in_types_without_extension
+dEQP-GLES31.functional.debug.negative_coverage.log.oes_sample_variables.redeclare_built_in_types
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.program_not_active
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.invalid_program_query
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.invalid_dispatch_compute_indirect
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.invalid_maximum_work_group_counts
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.invalid_maximum_work_group_sizes
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.invalid_layout_qualifiers
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.invalid_write_built_in_constants
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_uniform_block_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_shader_storage_block_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_texture_image_units_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_image_uniforms_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_shared_memory_size_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_uniform_components_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_atomic_counter_buffer_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.compute.exceed_atomic_counters_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.framebuffer_fetch.last_frag_data_not_defined
+dEQP-GLES31.functional.debug.negative_coverage.log.framebuffer_fetch.last_frag_data_readonly
+dEQP-GLES31.functional.debug.negative_coverage.log.framebuffer_fetch.invalid_inout_version
+dEQP-GLES31.functional.debug.negative_coverage.log.framebuffer_fetch.invalid_redeclaration_inout
+dEQP-GLES31.functional.debug.negative_coverage.log.framebuffer_fetch.invalid_vertex_inout
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.gen_buffers
@@ -17392,6 +17515,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texstorage3d
 dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texstorage3d_invalid_binding
 dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texstorage3d_invalid_levels
+dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.srgb_decode_texparameteri
+dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.srgb_decode_texparameterf
+dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.srgb_decode_texparameteriv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.srgb_decode_texparameterfv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.srgb_decode_texparameterIiv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.srgb_decode_texparameterIuiv
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.create_shader
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.shader_source
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.compile_shader
@@ -17459,6 +17588,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.transform_feedback_varyings
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.compile_compute_shader
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.link_compute_shader
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.srgb_decode_samplerparameteri
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.srgb_decode_samplerparameterf
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.srgb_decode_samplerparameteriv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.srgb_decode_samplerparameterfv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.srgb_decode_samplerparameterIiv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader.srgb_decode_samplerparameterIuiv
 dEQP-GLES31.functional.debug.negative_coverage.get_error.fragment.scissor
 dEQP-GLES31.functional.debug.negative_coverage.get_error.fragment.depth_func
 dEQP-GLES31.functional.debug.negative_coverage.get_error.fragment.viewport
@@ -17505,6 +17640,7 @@
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_arrays_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_arrays_instanced
@@ -17514,10 +17650,12 @@
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_elements_instanced_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_invalid_program
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_incomplete_primitive
 dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_base_vertex
+dEQP-GLES31.functional.debug.negative_coverage.get_error.vertex_array.draw_range_elements_base_vertex_primitive_mode_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.state.enable
 dEQP-GLES31.functional.debug.negative_coverage.get_error.state.disable
 dEQP-GLES31.functional.debug.negative_coverage.get_error.state.get_booleanv
@@ -17700,6 +17838,31 @@
 dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.get_programiv
 dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_program_queries
 dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.tessellation_control_invalid_vertex_count
+dEQP-GLES31.functional.debug.negative_coverage.get_error.oes_sample_variables.write_to_read_only_types
+dEQP-GLES31.functional.debug.negative_coverage.get_error.oes_sample_variables.access_built_in_types_inside_other_shaders
+dEQP-GLES31.functional.debug.negative_coverage.get_error.oes_sample_variables.index_outside_sample_mask_range
+dEQP-GLES31.functional.debug.negative_coverage.get_error.oes_sample_variables.access_built_in_types_without_extension
+dEQP-GLES31.functional.debug.negative_coverage.get_error.oes_sample_variables.redeclare_built_in_types
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.program_not_active
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.invalid_program_query
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.invalid_dispatch_compute_indirect
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.invalid_maximum_work_group_counts
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.invalid_maximum_work_group_sizes
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.invalid_layout_qualifiers
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.invalid_write_built_in_constants
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_uniform_block_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_shader_storage_block_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_texture_image_units_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_image_uniforms_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_shared_memory_size_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_uniform_components_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_atomic_counter_buffer_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.compute.exceed_atomic_counters_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.framebuffer_fetch.last_frag_data_not_defined
+dEQP-GLES31.functional.debug.negative_coverage.get_error.framebuffer_fetch.last_frag_data_readonly
+dEQP-GLES31.functional.debug.negative_coverage.get_error.framebuffer_fetch.invalid_inout_version
+dEQP-GLES31.functional.debug.negative_coverage.get_error.framebuffer_fetch.invalid_redeclaration_inout
+dEQP-GLES31.functional.debug.negative_coverage.get_error.framebuffer_fetch.invalid_vertex_inout
 dEQP-GLES31.functional.debug.externally_generated.application_messages
 dEQP-GLES31.functional.debug.externally_generated.third_party_messages
 dEQP-GLES31.functional.debug.externally_generated.push_pop_stack
@@ -17894,6 +18057,12 @@
 dEQP-GLES31.functional.fbo.no_attachments.maximums.samples
 dEQP-GLES31.functional.fbo.no_attachments.maximums.all
 dEQP-GLES31.functional.fbo.completeness.no_attachments
+dEQP-GLES31.functional.fbo.srgb_write_control.framebuffer_srgb_enabled
+dEQP-GLES31.functional.fbo.srgb_write_control.framebuffer_srgb_enabled_col_attach
+dEQP-GLES31.functional.fbo.srgb_write_control.framebuffer_srgb_enabled_blend
+dEQP-GLES31.functional.fbo.srgb_write_control.framebuffer_srgb_enabled_render_target_ignore
+dEQP-GLES31.functional.fbo.srgb_write_control.framebuffer_srgb_enabled_copy_to_linear
+dEQP-GLES31.functional.fbo.srgb_write_control.framebuffer_srgb_unsupported_enum
 dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_name_query
 dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_query
 dEQP-GLES31.functional.program_interface_query.uniform.resource_list.default_block.var
@@ -35564,3 +35733,117 @@
 dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.toggled
 dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.multiple_textures
 dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.using_sampler
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.indices.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.indices.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.indices.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_neg_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_neg_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.base_vertex.index_neg_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.builtin_variable.vertex_id
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.points.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangles.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_fan.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.triangle_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.lines.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.line_loop.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.indices.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.indices.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.indices.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_neg_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_neg_short
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.base_vertex.index_neg_int
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.builtin_variable.vertex_id
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.points.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangles.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_fan.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.triangle_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.lines.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.line_loop.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.indices.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.indices.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.indices.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_neg_byte
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_neg_short
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.base_vertex.index_neg_int
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.builtin_variable.vertex_id
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.points.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangles.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_fan.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.triangle_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.lines.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_strip.default_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.single_attribute
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.multiple_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.instanced_attributes
+dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.line_loop.default_attribute
diff --git a/android/cts/master/src/gles3-driver-issues.txt b/android/cts/master/src/gles3-driver-issues.txt
index 55962f4..99c22e6 100644
--- a/android/cts/master/src/gles3-driver-issues.txt
+++ b/android/cts/master/src/gles3-driver-issues.txt
@@ -24,55 +24,6 @@
 dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_out_of_bounds_min_reverse_src_dst_y
 
 # Bug 22760309
-dEQP-GLES3.functional.attribute_location.bind_hole.vec4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.float
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.vec2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.vec3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.vec4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.int
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.ivec2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.ivec3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.ivec4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.uint
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.uvec2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.uvec3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.uvec4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat2x4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3x2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3x3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat3x4
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4x2
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4x3
-dEQP-GLES3.functional.attribute_location.bind_relink_hole.mat4x4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.float
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.vec2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.vec3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.vec4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.int
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.ivec2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.ivec3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.ivec4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uint
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uvec2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uvec3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.uvec4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat2x4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3x2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3x3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat3x4
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4x2
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4x3
-dEQP-GLES3.functional.attribute_location.mixed_relink_hole.mat4x4
 dEQP-GLES3.functional.depth_stencil_clear.depth_stencil_scissored_masked
 dEQP-GLES3.functional.draw.random.50
 dEQP-GLES3.functional.fbo.completeness.renderable.texture.color0.red_unsigned_byte
@@ -157,29 +108,12 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.faceforward.highp_vertex.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.faceforward.highp_fragment.scalar
 dEQP-GLES3.functional.shaders.builtin_functions.precision.faceforward.highp_fragment.vec2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat3x2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat4x2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.lowp_fragment.mat4x3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat3x2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat4x2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.mediump_fragment.mat4x3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat3x2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat4x2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.matrixcompmult.highp_fragment.mat4x3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_vertex.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_fragment.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_vertex.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_fragment.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.highp_vertex.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.highp_fragment.vec2
-dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat2x3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat2x4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.lowp_fragment.mat3x4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat2x3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat2x4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.transpose.mediump_fragment.mat3x4
-dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_in_vertex
-dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_in_fragment
 dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_out_vertex
 dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_out_fragment
 dEQP-GLES3.functional.shaders.declarations.invalid_declarations.uniform_block_const_vertex
@@ -455,8 +389,6 @@
 dEQP-GLES3.functional.shaders.linkage.uniform.basic.precision_conflict_2
 dEQP-GLES3.functional.shaders.linkage.uniform.basic.precision_conflict_3
 dEQP-GLES3.functional.shaders.linkage.uniform.basic.precision_conflict_4
-dEQP-GLES3.functional.shaders.linkage.varying.rules.struct_type_mismatch_1
-dEQP-GLES3.functional.shaders.linkage.varying.struct.float_uvec2_vec3
 dEQP-GLES3.functional.shaders.operator.unary_operator.pre_decrement_effect.lowp_uint_vertex
 dEQP-GLES3.functional.shaders.operator.unary_operator.pre_decrement_effect.lowp_uint_fragment
 dEQP-GLES3.functional.shaders.operator.unary_operator.pre_decrement_effect.mediump_uint_vertex
@@ -529,8 +461,6 @@
 dEQP-GLES3.functional.shaders.operator.unary_operator.pre_decrement_result.mediump_uvec4_fragment
 dEQP-GLES3.functional.shaders.operator.unary_operator.pre_decrement_result.highp_uvec4_vertex
 dEQP-GLES3.functional.shaders.operator.unary_operator.pre_decrement_result.highp_uvec4_fragment
-dEQP-GLES3.functional.shaders.preprocessor.basic.identifier_with_double_underscore_vertex
-dEQP-GLES3.functional.shaders.preprocessor.basic.identifier_with_double_underscore_fragment
 dEQP-GLES3.functional.shaders.preprocessor.comments.backslash_in_a_comment_1_vertex
 dEQP-GLES3.functional.shaders.preprocessor.comments.backslash_in_a_comment_1_fragment
 dEQP-GLES3.functional.shaders.random.all_features.fragment.48
@@ -561,28 +491,6 @@
 dEQP-GLES3.functional.shaders.struct.uniform.array_member_dynamic_index_vertex
 dEQP-GLES3.functional.shaders.struct.uniform.dynamic_loop_nested_struct_array_fragment
 dEQP-GLES3.functional.shaders.struct.uniform.sampler_nested_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_fixed_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_fixed_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_float_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2d_float_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2d_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2d_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_fixed_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_fixed_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_float_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler2darray_float_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2darray_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler2darray_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler2darray_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler2darray_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_fixed_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_fixed_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_float_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.sampler3d_float_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler3d_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.isampler3d_fragment
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler3d_vertex
-dEQP-GLES3.functional.shaders.texture_functions.texelfetchoffset.usampler3d_fragment
 dEQP-GLES3.functional.shaders.texture_functions.invalid.texture_sampler2darrayshadow_vec4_float_vertex
 dEQP-GLES3.functional.shaders.texture_functions.invalid.texture_sampler2darrayshadow_vec4_float_fragment
 dEQP-GLES3.functional.shaders.uniform_block.valid.member_layout_row_major_vec4_vertex
@@ -612,42 +520,10 @@
 dEQP-GLES3.functional.state_query.integers.draw_buffer_getinteger
 dEQP-GLES3.functional.state_query.integers.draw_buffer_getinteger64
 dEQP-GLES3.functional.state_query.integers.draw_buffer_getfloat
-dEQP-GLES3.functional.state_query.floats.depth_range_getinteger64
-dEQP-GLES3.functional.state_query.floats.line_width_getinteger
-dEQP-GLES3.functional.state_query.floats.line_width_getinteger64
-dEQP-GLES3.functional.state_query.floats.polygon_offset_factor_getinteger
-dEQP-GLES3.functional.state_query.floats.polygon_offset_factor_getinteger64
-dEQP-GLES3.functional.state_query.floats.polygon_offset_units_getinteger
-dEQP-GLES3.functional.state_query.floats.polygon_offset_units_getinteger64
-dEQP-GLES3.functional.state_query.floats.sample_coverage_value_getinteger
-dEQP-GLES3.functional.state_query.floats.sample_coverage_value_getinteger64
-dEQP-GLES3.functional.state_query.sampler.sampler_texture_min_lod_getsamplerparameterf
-dEQP-GLES3.functional.state_query.sampler.sampler_texture_max_lod_getsamplerparameterf
-dEQP-GLES3.functional.state_query.fbo.framebuffer_unspecified_attachment_x_size_rbo
-dEQP-GLES3.functional.state_query.shader.program_active_uniform_types
-dEQP-GLES3.functional.state_query.shader.vertex_attrib_type
-dEQP-GLES3.functional.state_query.shader.vertex_attrib_integer
 dEQP-GLES3.functional.state_query.shader.uniform_value_boolean
 dEQP-GLES3.functional.state_query.internal_format.rgba_samples
 dEQP-GLES3.functional.state_query.internal_format.rgb_samples
 dEQP-GLES3.functional.state_query.string.extensions
-dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_linear_linear_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_linear_linear_clamp_mirror
-dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_linear_nearest_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_nearest_linear_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d.combinations.linear_mipmap_nearest_nearest_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_linear_linear_mirror_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_linear_nearest_mirror_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_clamp_mirror
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_mirror_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_linear_mirror_mirror
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_clamp_mirror
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_mirror_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.linear_mipmap_nearest_nearest_mirror_mirror
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_linear_linear_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_linear_nearest_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_nearest_linear_clamp_clamp
-dEQP-GLES3.functional.texture.filtering.2d_array.combinations.nearest_mipmap_nearest_nearest_clamp_clamp
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_linear_linear_clamp_clamp_clamp
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_linear_linear_clamp_clamp_mirror
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_linear_linear_clamp_mirror_clamp
@@ -669,121 +545,12 @@
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_nearest_nearest_clamp_mirror_mirror
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_nearest_nearest_clamp_repeat_clamp
 dEQP-GLES3.functional.texture.filtering.3d.combinations.linear_mipmap_nearest_nearest_clamp_repeat_mirror
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16f_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r16ui_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32f_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32i_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r32ui_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8_snorm_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.r8i_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg16ui_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rg8i_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb10_a2_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb10_a2ui_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8i_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgb8ui_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba16i_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.rgba32f_3d
-dEQP-GLES3.functional.texture.specification.basic_teximage3d.srgb8_alpha8_3d
 dEQP-GLES3.functional.texture.specification.teximage3d_depth_pbo.depth_component16_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth24_stencil8_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth32f_stencil8_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component16_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component24_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.depth_component32f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r11f_g11f_b10f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r16i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r32i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8_snorm_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.r8ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg16ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg32ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8_snorm_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rg8i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb10_a2_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb10_a2ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb16ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb32ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgb8ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba16ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32f_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba32i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8_snorm_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8i_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.rgba8ui_2d
-dEQP-GLES3.functional.texture.specification.texstorage2d.format.srgb8_alpha8_2d
 dEQP-GLES3.functional.texture.specification.texstorage2d.size.2d_57x63_6_levels
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.depth32f_stencil8_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r11f_g11f_b10f_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16f_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r16ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32f_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r32ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8_snorm_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8_snorm_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.r8ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg16i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32f_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg32ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8_snorm_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8_snorm_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rg8ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb10_a2_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb10_a2_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16f_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb16ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb32i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb8_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb8i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgb8ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16f_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16i_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba16ui_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba32f_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba32ui_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8_snorm_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8i_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8ui_2d_array
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.rgba8ui_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.srgb8_3d
-dEQP-GLES3.functional.texture.specification.texstorage3d.format.srgb8_alpha8_3d
 dEQP-GLES3.functional.transform_feedback.random.separate.triangles.1
 dEQP-GLES3.functional.transform_feedback.random.interleaved.lines.3
 dEQP-GLES3.functional.transform_feedback.random.interleaved.triangles.7
 dEQP-GLES3.functional.transform_feedback.random.interleaved.triangles.8
 dEQP-GLES3.functional.transform_feedback.random.interleaved.triangles.10
 dEQP-GLES3.functional.ubo.random.all_per_block_buffers.35
-dEQP-GLES3.functional.ubo.random.all_shared_buffer.37
-dEQP-GLES3.functional.ubo.random.basic_arrays.15
 dEQP-GLES3.functional.ubo.random.nested_structs_arrays.9
-dEQP-GLES3.functional.ubo.random.nested_structs_arrays.14
diff --git a/android/package/Android.mk b/android/package/Android.mk
index 00db989..210ac5b 100644
--- a/android/package/Android.mk
+++ b/android/package/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_JNI_SHARED_LIBRARIES := libdeqp
diff --git a/data/gles3/shaders/large_constant_arrays.test b/data/gles3/shaders/large_constant_arrays.test
new file mode 100644
index 0000000..52fa3b6
--- /dev/null
+++ b/data/gles3/shaders/large_constant_arrays.test
@@ -0,0 +1,687 @@
+# WARNING: This file is auto-generated. Do NOT modify it manually, but rather
+# modify the generating script file. Otherwise changes will be lost!
+
+group indexing "Large constant array indexing"
+
+	case float_16
+		version 300 es
+		values
+		{
+			input int in0 = [ 13 | 5 | 3 | 1 | 14 | 12 | 9 | 8 | 7 | 10 ];
+			output float out0 = [ 0.468418 | 0.886325 | 0.625848 | -0.419144 | 0.091143 | -0.549422 | -0.818481 | 0.844853 | -0.916329 | -0.430844 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const float array[16] = float[](
+				0.820844,
+				-0.419144,
+				-0.977806,
+				0.625848,
+				-0.879658,
+				0.886325,
+				0.920155,
+				-0.916329,
+				0.844853,
+				-0.818481,
+				-0.430844,
+				-0.102321,
+				-0.549422,
+				0.468418,
+				0.091143,
+				-0.391751);
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case float_32
+		version 300 es
+		values
+		{
+			input int in0 = [ 21 | 27 | 30 | 26 | 24 | 14 | 28 | 1 | 3 | 13 ];
+			output float out0 = [ 0.889334 | 0.03372 | 0.542691 | 0.947655 | 0.464199 | 0.971569 | 0.697548 | 0.130332 | 0.811221 | 0.135418 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const float array[32] = float[](
+				0.051622,
+				0.130332,
+				-0.545011,
+				0.811221,
+				-0.133496,
+				-0.747309,
+				-0.232863,
+				-0.989304,
+				-0.383455,
+				-0.64868,
+				-0.007918,
+				-0.440069,
+				-0.805934,
+				0.135418,
+				0.971569,
+				-0.84199,
+				-0.84687,
+				-0.818401,
+				-0.20169,
+				0.397021,
+				0.900357,
+				0.889334,
+				0.913348,
+				0.282212,
+				0.464199,
+				-0.300277,
+				0.947655,
+				0.03372,
+				0.697548,
+				-0.904883,
+				0.542691,
+				-0.00454);
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case float_64
+		version 300 es
+		values
+		{
+			input int in0 = [ 24 | 51 | 33 | 58 | 23 | 26 | 49 | 36 | 29 | 9 ];
+			output float out0 = [ -0.165325 | 0.915027 | -0.93891 | -0.720483 | 0.630692 | -0.183465 | -0.091696 | 0.271041 | 0.000966 | 0.043076 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const float array[64] = float[](
+				-0.155153,
+				-0.691893,
+				-0.621229,
+				0.760603,
+				0.088916,
+				-0.524295,
+				0.113903,
+				0.476223,
+				-0.876719,
+				0.043076,
+				0.226183,
+				0.793424,
+				0.975524,
+				0.356928,
+				-0.091224,
+				-0.115697,
+				0.211775,
+				-0.156547,
+				0.109569,
+				-0.008558,
+				-0.399851,
+				0.041094,
+				-0.215708,
+				0.630692,
+				-0.165325,
+				0.133704,
+				-0.183465,
+				-0.693101,
+				0.165356,
+				0.000966,
+				0.325663,
+				-0.949325,
+				-0.641681,
+				-0.93891,
+				-0.382354,
+				-0.336639,
+				0.271041,
+				-0.555445,
+				0.634963,
+				0.208943,
+				0.04329,
+				-0.408225,
+				-0.188936,
+				-0.495692,
+				-0.660485,
+				-0.023267,
+				0.342354,
+				-0.304884,
+				0.994079,
+				-0.091696,
+				0.104488,
+				0.915027,
+				-0.778301,
+				0.015887,
+				-0.309334,
+				0.047039,
+				-0.874582,
+				0.412231,
+				-0.720483,
+				0.773809,
+				-0.965339,
+				-0.712545,
+				0.680373,
+				-0.468491);
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case float_128
+		version 300 es
+		values
+		{
+			input int in0 = [ 74 | 100 | 64 | 110 | 37 | 98 | 40 | 2 | 60 | 125 ];
+			output float out0 = [ -0.761249 | -0.069156 | 0.226429 | 0.601557 | 0.371274 | 0.215692 | -0.674008 | 0.615323 | 0.190409 | 0.212482 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const float array[128] = float[](
+				-0.606065,
+				0.585311,
+				0.615323,
+				0.605568,
+				0.325339,
+				0.582551,
+				0.202606,
+				0.114549,
+				0.191475,
+				0.374646,
+				0.960984,
+				-0.292771,
+				0.956747,
+				0.734036,
+				0.096515,
+				0.535036,
+				-0.98915,
+				-0.191685,
+				-0.106254,
+				-0.643042,
+				-0.454891,
+				-0.315775,
+				0.110321,
+				0.64039,
+				0.900433,
+				0.013303,
+				0.446101,
+				-0.724773,
+				0.872389,
+				0.967503,
+				-0.286729,
+				0.604424,
+				-0.248435,
+				-0.663876,
+				-0.401537,
+				-0.008831,
+				0.332312,
+				0.371274,
+				0.838556,
+				-0.505901,
+				-0.674008,
+				0.651268,
+				0.305334,
+				0.043057,
+				-0.846835,
+				0.465127,
+				0.13647,
+				-0.933798,
+				0.245198,
+				-0.448103,
+				-0.830984,
+				-0.595662,
+				0.932601,
+				0.941371,
+				-0.552377,
+				-0.565168,
+				0.094688,
+				0.227978,
+				-0.048074,
+				0.859927,
+				0.190409,
+				-0.40713,
+				-0.207751,
+				-0.730053,
+				0.226429,
+				-0.304911,
+				-0.340919,
+				-0.237864,
+				-0.141297,
+				0.740117,
+				0.327007,
+				0.931855,
+				-0.966676,
+				-0.405333,
+				-0.761249,
+				0.414494,
+				-0.625865,
+				-0.822929,
+				0.852507,
+				0.63237,
+				0.117329,
+				0.251459,
+				-0.892533,
+				-0.861027,
+				0.474994,
+				0.15425,
+				0.410844,
+				0.252524,
+				0.59348,
+				-0.384798,
+				0.887143,
+				-0.60691,
+				-0.867488,
+				0.86186,
+				0.179197,
+				-0.61976,
+				-0.627032,
+				-0.517259,
+				0.215692,
+				0.247583,
+				-0.069156,
+				0.27504,
+				-0.416217,
+				-0.601742,
+				0.005733,
+				-0.85614,
+				0.173415,
+				0.044441,
+				-0.04449,
+				0.409629,
+				0.601557,
+				-0.696671,
+				-0.154054,
+				-0.436629,
+				0.791761,
+				0.800219,
+				0.669122,
+				0.905657,
+				0.053525,
+				-0.379138,
+				-0.970811,
+				0.933257,
+				0.777627,
+				-0.7471,
+				0.888404,
+				0.212482,
+				-0.340208,
+				-0.521818);
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case vec4_16
+		version 300 es
+		values
+		{
+			input int in0 = [ 6 | 2 | 4 | 3 | 7 | 14 | 10 | 11 | 9 | 5 ];
+			output vec4 out0 = [ vec4(0.378924, -0.127814, 0.330945, -0.27653) | vec4(-0.247838, -0.090046, 0.141822, -0.946729) | vec4(-0.096116, 0.684352, -0.761391, -0.576026) | vec4(-0.020481, 0.68827, -0.465826, 0.021883) | vec4(0.773114, 0.865765, 0.336626, -0.153597) | vec4(0.151689, 0.702867, -0.74982, -0.817309) | vec4(-0.988044, -0.973138, -0.378991, 0.959731) | vec4(-0.335106, -0.996349, -0.091219, 0.257548) | vec4(0.761714, 0.487718, 0.880316, 0.168774) | vec4(0.218481, 0.833123, 0.405688, 0.097803) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const vec4 array[16] = vec4[](
+				vec4(0.702379, 0.931642, 0.571117, 0.741301),
+				vec4(-0.964841, -0.979497, -0.360118, -0.600566),
+				vec4(-0.247838, -0.090046, 0.141822, -0.946729),
+				vec4(-0.020481, 0.68827, -0.465826, 0.021883),
+				vec4(-0.096116, 0.684352, -0.761391, -0.576026),
+				vec4(0.218481, 0.833123, 0.405688, 0.097803),
+				vec4(0.378924, -0.127814, 0.330945, -0.27653),
+				vec4(0.773114, 0.865765, 0.336626, -0.153597),
+				vec4(-0.566026, -0.282675, -0.698072, 0.440076),
+				vec4(0.761714, 0.487718, 0.880316, 0.168774),
+				vec4(-0.988044, -0.973138, -0.378991, 0.959731),
+				vec4(-0.335106, -0.996349, -0.091219, 0.257548),
+				vec4(0.108932, 0.902995, 0.18808, -0.627335),
+				vec4(-0.832395, 0.44453, 0.552096, 0.950837),
+				vec4(0.151689, 0.702867, -0.74982, -0.817309),
+				vec4(-0.445073, 0.936425, 0.895915, 0.288802));
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case vec4_32
+		version 300 es
+		values
+		{
+			input int in0 = [ 4 | 13 | 20 | 10 | 23 | 12 | 19 | 2 | 30 | 11 ];
+			output vec4 out0 = [ vec4(0.234251, -0.965779, 0.158729, -0.965185) | vec4(-0.132707, 0.610324, 0.116332, 0.816963) | vec4(0.37494, 0.211193, 0.079682, -0.573136) | vec4(-0.926896, -0.193718, 0.919353, -0.261054) | vec4(-0.224023, -0.116632, -0.705967, 0.328828) | vec4(-0.966802, 0.892944, 0.350637, -0.000857) | vec4(0.219963, 0.520628, 0.267869, 0.845337) | vec4(0.386404, 0.849264, 0.678119, 0.729645) | vec4(0.111928, 0.213155, -0.872381, 0.72469) | vec4(0.45802, 0.729006, 0.156691, 0.931424) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const vec4 array[32] = vec4[](
+				vec4(0.746262, 0.047635, 0.1152, 0.95654),
+				vec4(-0.980698, 0.866032, -0.016573, -0.68077),
+				vec4(0.386404, 0.849264, 0.678119, 0.729645),
+				vec4(0.610655, 0.250881, 0.738948, -0.867151),
+				vec4(0.234251, -0.965779, 0.158729, -0.965185),
+				vec4(-0.327633, 0.832239, 0.745245, -0.695431),
+				vec4(-0.028568, -0.98534, -0.840921, -0.071501),
+				vec4(0.818859, -0.609353, -0.902915, 0.743332),
+				vec4(-0.647141, -0.164404, -0.00065, 0.340666),
+				vec4(0.630666, 0.648155, -0.793757, 0.9653),
+				vec4(-0.926896, -0.193718, 0.919353, -0.261054),
+				vec4(0.45802, 0.729006, 0.156691, 0.931424),
+				vec4(-0.966802, 0.892944, 0.350637, -0.000857),
+				vec4(-0.132707, 0.610324, 0.116332, 0.816963),
+				vec4(0.922649, 0.823922, -0.023737, 0.862443),
+				vec4(-0.587344, -0.028909, -0.384425, -0.292115),
+				vec4(0.466302, 0.681084, -0.418924, -0.955053),
+				vec4(0.642952, 0.663277, -0.658365, 0.503144),
+				vec4(-0.868831, -0.791933, 0.008615, 0.621668),
+				vec4(0.219963, 0.520628, 0.267869, 0.845337),
+				vec4(0.37494, 0.211193, 0.079682, -0.573136),
+				vec4(-0.302229, 0.867697, -0.261632, -0.099338),
+				vec4(-0.291822, -0.611533, 0.791703, -0.961155),
+				vec4(-0.224023, -0.116632, -0.705967, 0.328828),
+				vec4(-0.826241, 0.073009, -0.563931, -0.564878),
+				vec4(-0.001856, 0.668955, 0.773383, 0.572741),
+				vec4(0.851707, 0.44545, 0.216004, 0.565875),
+				vec4(-0.261423, 0.519932, -0.25264, 0.817994),
+				vec4(-0.314797, -0.517587, 0.226457, 0.629556),
+				vec4(-0.280022, 0.018478, 0.269514, 0.361096),
+				vec4(0.111928, 0.213155, -0.872381, 0.72469),
+				vec4(0.890298, 0.016925, 0.864494, -0.736341));
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case vec4_64
+		version 300 es
+		values
+		{
+			input int in0 = [ 4 | 21 | 57 | 59 | 34 | 55 | 44 | 39 | 10 | 31 ];
+			output vec4 out0 = [ vec4(0.413679, -0.588393, -0.917377, -0.945484) | vec4(0.529861, 0.595711, -0.37219, -0.663102) | vec4(0.95924, -0.862079, -0.968311, 0.536199) | vec4(0.997116, 0.589927, 0.349899, 0.604469) | vec4(0.079967, -0.817781, -0.00389, 0.038084) | vec4(0.894091, -0.23182, 0.653183, -0.849151) | vec4(-0.596059, -0.650775, -0.122874, -0.673995) | vec4(-0.284478, 0.429867, 0.090923, -0.3685) | vec4(-0.889621, 0.262221, -0.601158, -0.165562) | vec4(-0.398228, 0.281876, -0.282784, -0.256016) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const vec4 array[64] = vec4[](
+				vec4(-0.480146, 0.488133, -0.596212, 0.0368),
+				vec4(0.111078, 0.509359, -0.235293, -0.578438),
+				vec4(0.135706, 0.648087, 0.441842, 0.116671),
+				vec4(0.124006, -0.059068, -0.606559, 0.050443),
+				vec4(0.413679, -0.588393, -0.917377, -0.945484),
+				vec4(0.422634, -0.441916, 0.107329, -0.273781),
+				vec4(0.425519, -0.038142, -0.023987, 0.992765),
+				vec4(0.857748, -0.828656, -0.987976, -0.389911),
+				vec4(-0.869591, 0.048031, -0.367579, -0.025289),
+				vec4(0.363748, -0.413528, 0.723353, -0.017295),
+				vec4(-0.889621, 0.262221, -0.601158, -0.165562),
+				vec4(-0.609124, -0.342082, -0.268213, 0.050068),
+				vec4(0.828537, -0.183152, 0.408507, 0.007535),
+				vec4(0.408017, -0.115262, 0.393138, 0.024297),
+				vec4(0.97793, 0.555998, -0.220581, 0.011588),
+				vec4(-0.886087, 0.425181, 0.868147, -0.549629),
+				vec4(-0.50603, -0.246514, -0.037877, 0.657885),
+				vec4(0.611792, 0.550694, 0.399424, 0.903954),
+				vec4(0.148127, 0.628768, -0.935913, 0.087541),
+				vec4(-0.658525, -0.533425, -0.635972, 0.810969),
+				vec4(0.156667, 0.178831, -0.115309, -0.303525),
+				vec4(0.529861, 0.595711, -0.37219, -0.663102),
+				vec4(0.533462, 0.680434, 0.376217, 0.533146),
+				vec4(0.861562, 0.806064, -0.980503, 0.395841),
+				vec4(-0.081845, -0.140139, 0.897804, 0.283262),
+				vec4(0.135971, 0.719622, -0.54009, -0.570697),
+				vec4(-0.658123, -0.390202, -0.393324, 0.048424),
+				vec4(-0.445823, 0.463386, 0.066676, 0.138665),
+				vec4(0.00455, 0.547296, 0.81213, -0.725805),
+				vec4(0.79715, 0.651829, 0.04855, 0.854804),
+				vec4(0.350284, 0.561782, -0.214693, -0.224041),
+				vec4(-0.398228, 0.281876, -0.282784, -0.256016),
+				vec4(-0.315469, -0.932084, 0.663378, 0.298112),
+				vec4(-0.288229, -0.128671, 0.147874, 0.475918),
+				vec4(0.079967, -0.817781, -0.00389, 0.038084),
+				vec4(-0.69381, -0.966723, 0.823463, 0.046353),
+				vec4(0.031383, -0.948433, 0.232904, -0.592879),
+				vec4(0.351552, -0.046135, 0.668205, -0.489609),
+				vec4(0.809815, -0.036727, -0.75659, -0.669761),
+				vec4(-0.284478, 0.429867, 0.090923, -0.3685),
+				vec4(0.640377, -0.775249, 0.650625, 0.442851),
+				vec4(0.468475, -0.175155, -0.473131, 0.910253),
+				vec4(-0.858185, -0.682824, -0.170344, -0.132026),
+				vec4(0.296971, 0.846515, 0.086111, -0.339669),
+				vec4(-0.596059, -0.650775, -0.122874, -0.673995),
+				vec4(-0.381965, 0.882521, -0.393034, 0.059749),
+				vec4(0.807728, -0.560089, -0.716643, 0.608183),
+				vec4(-0.836518, 0.721956, 0.881924, -0.914307),
+				vec4(0.782346, -0.564062, 0.948654, 0.907281),
+				vec4(0.449519, -0.460615, -0.180337, -0.565051),
+				vec4(-0.833486, -0.992801, 0.754353, -0.792533),
+				vec4(-0.323334, -0.999663, -0.43783, 0.903025),
+				vec4(-0.747918, 0.807199, -0.629008, 0.474276),
+				vec4(0.087617, 0.113212, 0.495957, 0.497932),
+				vec4(-0.175527, -0.927756, -0.43963, 0.178476),
+				vec4(0.894091, -0.23182, 0.653183, -0.849151),
+				vec4(-0.732546, -0.69909, 0.173024, -0.148884),
+				vec4(0.95924, -0.862079, -0.968311, 0.536199),
+				vec4(-0.563604, 0.854396, -0.917465, -0.060678),
+				vec4(0.997116, 0.589927, 0.349899, 0.604469),
+				vec4(-0.557417, 0.292507, 0.01601, -0.671221),
+				vec4(-0.647461, -0.423871, 0.329662, -0.817252),
+				vec4(-0.756303, -0.570313, -0.98811, 0.870433),
+				vec4(-0.607177, 0.486721, -0.364198, 0.40236));
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+	case vec4_128
+		version 300 es
+		values
+		{
+			input int in0 = [ 29 | 32 | 55 | 86 | 36 | 111 | 47 | 24 | 41 | 35 ];
+			output vec4 out0 = [ vec4(0.185822, -0.913471, -0.575667, -0.007955) | vec4(0.498087, 0.236408, 0.333385, -0.460987) | vec4(-0.345533, -0.37199, -0.411307, -0.795871) | vec4(0.653324, 0.742875, 0.100787, -0.730804) | vec4(-0.793916, -0.826062, 0.373936, 0.747619) | vec4(-0.621498, 0.924617, -0.249821, 0.537011) | vec4(-0.476626, 0.599014, 0.741966, 0.770093) | vec4(-0.275002, -0.525221, -0.015751, -0.056602) | vec4(-0.053926, 0.818767, 0.972056, -0.820966) | vec4(0.512801, 0.481098, 0.118826, -0.862755) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				const vec4 array[128] = vec4[](
+				vec4(0.842836, -0.363564, 0.520257, 0.10905),
+				vec4(-0.903618, 0.037251, 0.911375, -0.441012),
+				vec4(0.166032, -0.30338, -0.668911, -0.479533),
+				vec4(0.380743, 0.469773, 0.544907, 0.659974),
+				vec4(0.281295, -0.066993, 0.642936, 0.069625),
+				vec4(0.986712, -0.515945, 0.444003, 0.032566),
+				vec4(-0.397769, 0.000779, -0.443045, -0.546691),
+				vec4(0.582351, -0.620597, 0.632682, -0.817857),
+				vec4(0.765554, 0.158256, -0.957538, 0.285925),
+				vec4(-0.866527, -0.967477, -0.766937, 0.965938),
+				vec4(0.01059, 0.782249, 0.241295, -0.188475),
+				vec4(-0.85145, -0.470437, 0.506059, -0.3513),
+				vec4(-0.867736, 0.183432, 0.06569, -0.63488),
+				vec4(0.988198, -0.051591, -0.991153, -0.997269),
+				vec4(-0.729309, -0.821781, 0.329051, -0.419516),
+				vec4(0.491436, 0.830255, 0.894415, 0.441036),
+				vec4(-0.219224, 0.262158, -0.869032, -0.736425),
+				vec4(-0.657224, 0.406889, -0.635384, 0.669912),
+				vec4(-0.787681, 0.850956, -0.521237, -0.028796),
+				vec4(-0.38085, 0.119221, 0.157224, 0.012491),
+				vec4(-0.370375, 0.416307, -0.424604, -0.026106),
+				vec4(-0.506551, 0.111284, -0.307273, 0.634551),
+				vec4(0.687287, -0.46419, 0.110053, 0.69171),
+				vec4(0.110063, 0.235795, 0.970394, -0.31602),
+				vec4(-0.275002, -0.525221, -0.015751, -0.056602),
+				vec4(-0.750295, 0.175323, 0.009521, -0.386032),
+				vec4(-0.652183, -0.820997, 0.035078, -0.0278),
+				vec4(-0.465724, 0.983265, 0.827534, -0.005277),
+				vec4(-0.004708, -0.885227, -0.536755, -0.585531),
+				vec4(0.185822, -0.913471, -0.575667, -0.007955),
+				vec4(0.44255, 0.209638, -0.329841, 0.886842),
+				vec4(-0.203633, 0.641963, 0.744789, 0.635332),
+				vec4(0.498087, 0.236408, 0.333385, -0.460987),
+				vec4(0.705059, -0.255996, -0.773135, -0.389827),
+				vec4(0.50557, 0.582894, -0.913518, 0.809565),
+				vec4(0.512801, 0.481098, 0.118826, -0.862755),
+				vec4(-0.793916, -0.826062, 0.373936, 0.747619),
+				vec4(-0.75007, 0.09755, 0.281934, 0.210534),
+				vec4(0.78102, 0.867441, -0.702406, -0.001592),
+				vec4(0.43672, -0.404394, 0.411154, -0.505835),
+				vec4(0.383875, -0.752196, -0.084493, -0.024631),
+				vec4(-0.053926, 0.818767, 0.972056, -0.820966),
+				vec4(0.7769, 0.612362, 0.864866, 0.18249),
+				vec4(-0.872748, 0.930558, -0.401342, -0.549771),
+				vec4(0.479798, -0.013824, 0.922094, -0.678146),
+				vec4(-0.443224, -0.106084, 0.779373, 0.267014),
+				vec4(0.127066, -0.388646, -0.079058, -0.801055),
+				vec4(-0.476626, 0.599014, 0.741966, 0.770093),
+				vec4(0.027274, 0.431394, -0.234384, 0.341312),
+				vec4(-0.564585, 0.267136, -0.752188, 0.177374),
+				vec4(0.274006, 0.561503, 0.018388, 0.298662),
+				vec4(-0.193345, -0.884309, -0.30153, -0.276064),
+				vec4(-0.280861, -0.153023, 0.01675, 0.185445),
+				vec4(-0.690369, 0.509338, -0.846314, 0.345576),
+				vec4(0.068857, 0.950949, 0.285692, -0.605988),
+				vec4(-0.345533, -0.37199, -0.411307, -0.795871),
+				vec4(0.37715, -0.981474, 0.399323, -0.040061),
+				vec4(0.945189, -0.417953, -0.402613, 0.137985),
+				vec4(-0.703233, 0.317338, 0.010111, -0.95507),
+				vec4(0.787971, -0.451228, -0.428692, 0.175322),
+				vec4(0.656471, 0.137505, -0.581568, 0.563938),
+				vec4(0.334699, -0.528726, 0.622861, 0.564449),
+				vec4(-0.678301, -0.380204, -0.957709, 0.053429),
+				vec4(-0.597281, 0.722759, -0.71853, -0.865472),
+				vec4(-0.886436, 0.237729, -0.139967, -0.341931),
+				vec4(-0.938893, 0.659686, -0.143541, -0.509807),
+				vec4(-0.708534, -0.248793, -0.517719, 0.06884),
+				vec4(0.161891, -0.356068, -0.658876, 0.598824),
+				vec4(0.516694, 0.613815, -0.259727, -0.103706),
+				vec4(-0.774757, -0.599329, -0.811326, -0.245557),
+				vec4(0.963414, 0.675019, -0.071324, -0.361359),
+				vec4(0.696972, -0.930883, -0.212146, 0.183298),
+				vec4(0.547432, 0.486902, 0.25397, -0.846169),
+				vec4(0.507235, 0.980468, 0.613327, 0.167817),
+				vec4(-0.232448, 0.366919, 0.909552, -0.302138),
+				vec4(0.852591, 0.26435, -0.962982, -0.167924),
+				vec4(0.850581, 0.531167, -0.880981, -0.836251),
+				vec4(-0.298502, 0.47741, -0.568424, -0.186629),
+				vec4(0.433289, -0.107088, -0.431082, 0.348714),
+				vec4(0.312214, 0.941496, 0.512817, 0.723704),
+				vec4(0.366237, 0.263534, 0.944327, 0.53526),
+				vec4(-0.809848, 0.690145, -0.67335, 0.129199),
+				vec4(0.274245, 0.331532, -0.523098, 0.823656),
+				vec4(-0.016114, -0.185143, -0.514904, -0.330019),
+				vec4(-0.981275, 0.513983, -0.719175, 0.447463),
+				vec4(0.798987, -0.144184, 0.359325, -0.96724),
+				vec4(0.653324, 0.742875, 0.100787, -0.730804),
+				vec4(-0.381067, 0.341247, -0.958466, 0.573912),
+				vec4(0.306367, -0.154333, -0.549316, -0.833556),
+				vec4(0.793927, -0.974721, 0.136743, 0.139208),
+				vec4(-0.744128, 0.951207, -0.060684, -0.705715),
+				vec4(0.009366, 0.824768, -0.750502, 0.315864),
+				vec4(0.513749, 0.753087, 0.153459, -0.69295),
+				vec4(0.800838, 0.110549, 0.109575, 0.662356),
+				vec4(-0.293183, -0.088746, 0.577868, 0.269121),
+				vec4(-0.085005, 0.922185, -0.131908, 0.342865),
+				vec4(0.54346, 0.038911, -0.978638, 0.567109),
+				vec4(0.738807, 0.694076, 0.080795, 0.61307),
+				vec4(-0.471535, 0.490946, -0.052903, -0.334397),
+				vec4(0.829076, 0.758111, 0.335747, -0.260365),
+				vec4(-0.798087, -0.874586, 0.731774, 0.641365),
+				vec4(-0.860042, -0.244401, 0.447415, 0.149045),
+				vec4(0.379891, -0.107563, -0.899203, 0.962102),
+				vec4(0.034895, -0.389343, -0.160569, 0.730961),
+				vec4(-0.818613, -0.929147, -0.661238, -0.725143),
+				vec4(-0.904621, 0.829872, -0.354523, 0.039496),
+				vec4(-0.177426, 0.305898, 0.273389, -0.326031),
+				vec4(0.798147, 0.352917, 0.404206, 0.982926),
+				vec4(0.63269, -0.587404, 0.404303, 0.173164),
+				vec4(-0.41732, 0.841763, 0.752854, -0.765204),
+				vec4(-0.311183, 0.873934, 0.138971, 0.742761),
+				vec4(-0.621498, 0.924617, -0.249821, 0.537011),
+				vec4(0.505364, 0.651079, 0.251369, -0.780289),
+				vec4(-0.751458, -0.410518, 0.338219, 0.8951),
+				vec4(0.763002, 0.154308, 0.303164, 0.103052),
+				vec4(0.380686, 0.691856, -0.16408, -0.315851),
+				vec4(0.062813, 0.056525, -0.682853, -0.212878),
+				vec4(-0.06117, -0.774491, 0.424474, -0.682144),
+				vec4(-0.365712, -0.829378, -0.314134, -0.4523),
+				vec4(-0.998439, -0.441518, -0.125719, -0.713296),
+				vec4(0.014668, 0.948852, -0.760891, 0.657154),
+				vec4(0.498474, 0.958696, -0.742513, 0.054638),
+				vec4(-0.3969, -0.310351, -0.48657, -0.942015),
+				vec4(0.798607, 0.325691, -0.253755, 0.296882),
+				vec4(-0.010759, -0.316011, -0.906818, -0.455447),
+				vec4(-0.631907, 0.292569, -0.193719, -0.771571),
+				vec4(0.72405, 0.371067, -0.846457, 0.280322),
+				vec4(0.840775, 0.260059, 0.23114, -0.7314));
+
+				${SETUP}
+				out0 = array[in0];
+				${OUTPUT}
+			}
+		""
+	end
+
+
+end # indexing
diff --git a/data/gles3/shaders/swizzle_math_operations.test b/data/gles3/shaders/swizzle_math_operations.test
new file mode 100644
index 0000000..7a17199
--- /dev/null
+++ b/data/gles3/shaders/swizzle_math_operations.test
@@ -0,0 +1,6547 @@
+# WARNING: This file is auto-generated. Do NOT modify it manually, but rather
+# modify the generating script file. Otherwise changes will be lost!
+
+group vector_add "Vector swizzle math operations"
+
+	case mediump_vec2_x_x
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output float out0 = [ 0.2 | 2.0 | -1.0 | -64.0 | -1.5 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x + in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xx_xx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.2, 0.2) | vec2(2.0, 2.0) | vec2(-1.0, -1.0) | vec2(-64.0, -64.0) | vec2(-1.5, -1.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx + in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xy_yx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.6, 0.6) | vec2(2.25, 2.25) | vec2(-2.75, -2.75) | vec2(32.0, 32.0) | vec2(-0.782258064516, -0.782258064516) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy + in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yx_xy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.6, 0.6) | vec2(2.25, 2.25) | vec2(-2.75, -2.75) | vec2(32.0, 32.0) | vec2(-0.782258064516, -0.782258064516) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx + in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec3 out0 = [ vec3(0.6, 0.6, 1.0) | vec3(2.25, 2.25, 2.5) | vec3(-2.75, -2.75, -4.5) | vec3(32.0, 32.0, 128.0) | vec3(-0.782258064516, -0.782258064516, -0.0645161290323) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy + in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(0.6, 0.6, 0.2, 0.2) | vec4(2.25, 2.25, 2.0, 2.0) | vec4(-2.75, -2.75, -1.0, -1.0) | vec4(32.0, 32.0, -64.0, -64.0) | vec4(-0.782258064516, -0.782258064516, -1.5, -1.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx + in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(0.6, 0.6, 0.6, 0.6) | vec4(2.25, 2.25, 2.25, 2.25) | vec4(-2.75, -2.75, -2.75, -2.75) | vec4(32.0, 32.0, 32.0, 32.0) | vec4(-0.782258064516, -0.782258064516, -0.782258064516, -0.782258064516) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx + in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_x_x
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 0.2 | 2.0 | -1.0 | -64.0 | -1.5 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x + in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_z_z
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 1.5 | 2.25 | -9.75 | -102.0 | 0.105263157895 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z + in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xz_zx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(0.85, 0.85) | vec2(2.125, 2.125) | vec2(-5.375, -5.375) | vec2(-83.0, -83.0) | vec2(-0.697368421053, -0.697368421053) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz + in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zz_zz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(1.5, 1.5) | vec2(2.25, 2.25) | vec2(-9.75, -9.75) | vec2(-102.0, -102.0) | vec2(0.105263157895, 0.105263157895) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz + in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.6, 1.25, 0.85) | vec3(2.25, 2.375, 2.125) | vec3(-2.75, -7.125, -5.375) | vec3(32.0, 13.0, -83.0) | vec3(-0.782258064516, 0.0203735144312, -0.697368421053) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz + in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.25, 0.6, 0.85) | vec3(2.375, 2.25, 2.125) | vec3(-7.125, -2.75, -5.375) | vec3(13.0, 32.0, -83.0) | vec3(0.0203735144312, -0.782258064516, -0.697368421053) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx + in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.2, 0.2, 0.2) | vec3(2.0, 2.0, 2.0) | vec3(-1.0, -1.0, -1.0) | vec3(-64.0, -64.0, -64.0) | vec3(-1.5, -1.5, -1.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx + in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.5, 1.5, 1.5) | vec3(2.25, 2.25, 2.25) | vec3(-9.75, -9.75, -9.75) | vec3(-102.0, -102.0, -102.0) | vec3(0.105263157895, 0.105263157895, 0.105263157895) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz + in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.5, 1.25, 1.25) | vec3(2.25, 2.375, 2.375) | vec3(-9.75, -7.125, -7.125) | vec3(-102.0, 13.0, 13.0) | vec3(0.105263157895, 0.0203735144312, 0.0203735144312) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy + in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.6, 0.6, 1.0) | vec3(2.25, 2.25, 2.5) | vec3(-2.75, -2.75, -4.5) | vec3(32.0, 32.0, 128.0) | vec3(-0.782258064516, -0.782258064516, -0.0645161290323) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy + in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.85, 0.85, 0.2) | vec3(2.125, 2.125, 2.0) | vec3(-5.375, -5.375, -1.0) | vec3(-83.0, -83.0, -64.0) | vec3(-0.697368421053, -0.697368421053, -1.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx + in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(0.6, 1.0, 0.6, 0.2) | vec4(2.25, 2.5, 2.25, 2.0) | vec4(-2.75, -4.5, -2.75, -1.0) | vec4(32.0, 128.0, 32.0, -64.0) | vec4(-0.782258064516, -0.0645161290323, -0.782258064516, -1.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx + in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(0.85, 0.6, 1.25, 1.5) | vec4(2.125, 2.25, 2.375, 2.25) | vec4(-5.375, -2.75, -7.125, -9.75) | vec4(-83.0, 32.0, 13.0, -102.0) | vec4(-0.697368421053, -0.782258064516, 0.0203735144312, 0.105263157895) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz + in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_x_x
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 0.2 | 2.0 | -1.0 | -64.0 | -1.5 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x + in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_w_w
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 1.65 | 3.5 | 18.0 | 48.0 | 0.5 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w + in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wx_xw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(0.925, 0.925) | vec2(2.75, 2.75) | vec2(8.5, 8.5) | vec2(-8.0, -8.0) | vec2(-0.5, -0.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx + in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wz_zw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(1.575, 1.575) | vec2(2.875, 2.875) | vec2(4.125, 4.125) | vec2(-27.0, -27.0) | vec2(0.302631578947, 0.302631578947) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz + in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_www_www
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(1.65, 1.65, 1.65) | vec3(3.5, 3.5, 3.5) | vec3(18.0, 18.0, 18.0) | vec3(48.0, 48.0, 48.0) | vec3(0.5, 0.5, 0.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www + in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(1.0, 1.325, 1.325) | vec3(2.5, 3.0, 3.0) | vec3(-4.5, 6.75, 6.75) | vec3(128.0, 88.0, 88.0) | vec3(-0.0645161290323, 0.217741935484, 0.217741935484) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw + in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(1.575, 1.25, 1.325) | vec3(2.875, 2.375, 3.0) | vec3(4.125, -7.125, 6.75) | vec3(-27.0, 13.0, 88.0) | vec3(0.302631578947, 0.0203735144312, 0.217741935484) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy + in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.6, 1.25, 1.575, 0.925) | vec4(2.25, 2.375, 2.875, 2.75) | vec4(-2.75, -7.125, 4.125, 8.5) | vec4(32.0, 13.0, -27.0, -8.0) | vec4(-0.782258064516, 0.0203735144312, 0.302631578947, -0.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw + in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(1.575, 1.25, 0.6, 0.925) | vec4(2.875, 2.375, 2.25, 2.75) | vec4(4.125, -7.125, -2.75, 8.5) | vec4(-27.0, 13.0, 32.0, -8.0) | vec4(0.302631578947, 0.0203735144312, -0.782258064516, -0.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx + in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.6, 0.6, 0.6, 0.6) | vec4(2.25, 2.25, 2.25, 2.25) | vec4(-2.75, -2.75, -2.75, -2.75) | vec4(32.0, 32.0, 32.0, 32.0) | vec4(-0.782258064516, -0.782258064516, -0.782258064516, -0.782258064516) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy + in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(1.25, 1.5, 1.25, 1.0) | vec4(2.375, 2.25, 2.375, 2.5) | vec4(-7.125, -9.75, -7.125, -4.5) | vec4(13.0, -102.0, 13.0, 128.0) | vec4(0.0203735144312, 0.105263157895, 0.0203735144312, -0.0645161290323) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy + in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.925, 0.925, 1.65, 1.65) | vec4(2.75, 2.75, 3.5, 3.5) | vec4(8.5, 8.5, 18.0, 18.0) | vec4(-8.0, -8.0, 48.0, 48.0) | vec4(-0.5, -0.5, 0.5, 0.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww + in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.6, 0.6, 0.2, 0.2) | vec4(2.25, 2.25, 2.0, 2.0) | vec4(-2.75, -2.75, -1.0, -1.0) | vec4(32.0, 32.0, -64.0, -64.0) | vec4(-0.782258064516, -0.782258064516, -1.5, -1.5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx + in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(1.5, 1.5, 1.5, 1.5) | vec4(2.25, 2.25, 2.25, 2.25) | vec4(-9.75, -9.75, -9.75, -9.75) | vec4(-102.0, -102.0, -102.0, -102.0) | vec4(0.105263157895, 0.105263157895, 0.105263157895, 0.105263157895) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz + in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_x_x
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output int out0 = [ -2 | 2 | -2 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x + in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xx_xx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(-2, -2) | ivec2(2, 2) | ivec2(-2, -2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx + in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xy_yx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(3, 3) | ivec2(-3, -3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy + in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yx_xy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(3, 3) | ivec2(-3, -3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx + in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec3 out0 = [ ivec3(0, 0, 2) | ivec3(3, 3, 4) | ivec3(-3, -3, -4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy + in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(0, 0, -2, -2) | ivec4(3, 3, 2, 2) | ivec4(-3, -3, -2, -2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx + in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(0, 0, 0, 0) | ivec4(3, 3, 3, 3) | ivec4(-3, -3, -3, -3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx + in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_x_x
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ -2 | 2 | -2 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x + in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_z_z
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ -2 | 6 | -8 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z + in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xz_zx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(-2, -2) | ivec2(4, 4) | ivec2(-5, -5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz + in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zz_zz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(-2, -2) | ivec2(6, 6) | ivec2(-8, -8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz + in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, 0, -2) | ivec3(3, 5, 4) | ivec3(-3, -6, -5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz + in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, 0, -2) | ivec3(5, 3, 4) | ivec3(-6, -3, -5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx + in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-2, -2, -2) | ivec3(2, 2, 2) | ivec3(-2, -2, -2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx + in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-2, -2, -2) | ivec3(6, 6, 6) | ivec3(-8, -8, -8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz + in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-2, 0, 0) | ivec3(6, 5, 5) | ivec3(-8, -6, -6) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy + in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, 0, 2) | ivec3(3, 3, 4) | ivec3(-3, -3, -4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy + in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-2, -2, -2) | ivec3(4, 4, 2) | ivec3(-5, -5, -2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx + in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(0, 2, 0, -2) | ivec4(3, 4, 3, 2) | ivec4(-3, -4, -3, -2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx + in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(-2, 0, 0, -2) | ivec4(4, 3, 5, 6) | ivec4(-5, -3, -6, -8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz + in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_x_x
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ -2 | 2 | -2 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x + in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_w_w
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 2 | 8 | -18 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w + in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wx_xw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(5, 5) | ivec2(-10, -10) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx + in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wz_zw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(7, 7) | ivec2(-13, -13) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz + in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_www_www
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(2, 2, 2) | ivec3(8, 8, 8) | ivec3(-18, -18, -18) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www + in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(2, 2, 2) | ivec3(4, 6, 6) | ivec3(-4, -11, -11) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw + in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(0, 0, 2) | ivec3(7, 5, 6) | ivec3(-13, -6, -11) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy + in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, 0, 0, 0) | ivec4(3, 5, 7, 5) | ivec4(-3, -6, -13, -10) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw + in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, 0, 0, 0) | ivec4(7, 5, 3, 5) | ivec4(-13, -6, -3, -10) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx + in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, 0, 0, 0) | ivec4(3, 3, 3, 3) | ivec4(-3, -3, -3, -3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy + in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, -2, 0, 2) | ivec4(5, 6, 5, 4) | ivec4(-6, -8, -6, -4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy + in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, 0, 2, 2) | ivec4(5, 5, 8, 8) | ivec4(-10, -10, -18, -18) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww + in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, 0, -2, -2) | ivec4(3, 3, 2, 2) | ivec4(-3, -3, -2, -2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx + in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-2, -2, -2, -2) | ivec4(6, 6, 6, 6) | ivec4(-8, -8, -8, -8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz + in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+
+end # vector_add
+group vector_subtract "Vector swizzle math operations"
+
+	case mediump_vec2_x_x
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output float out0 = [ 0.0 | 0.0 | 0.0 | 0.0 | 0.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x - in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xx_xx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.0, 0.0) | vec2(0.0, 0.0) | vec2(0.0, 0.0) | vec2(0.0, 0.0) | vec2(0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx - in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xy_yx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(-0.4, 0.4) | vec2(-0.25, 0.25) | vec2(1.75, -1.75) | vec2(-96.0, 96.0) | vec2(-0.717741935484, 0.717741935484) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy - in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yx_xy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.4, -0.4) | vec2(0.25, -0.25) | vec2(-1.75, 1.75) | vec2(96.0, -96.0) | vec2(0.717741935484, -0.717741935484) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx - in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec3 out0 = [ vec3(0.4, -0.4, 0.0) | vec3(0.25, -0.25, 0.0) | vec3(-1.75, 1.75, 0.0) | vec3(96.0, -96.0, 0.0) | vec3(0.717741935484, -0.717741935484, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy - in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(-0.4, 0.4, 0.0, 0.0) | vec4(-0.25, 0.25, 0.0, 0.0) | vec4(1.75, -1.75, 0.0, 0.0) | vec4(-96.0, 96.0, 0.0, 0.0) | vec4(-0.717741935484, 0.717741935484, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx - in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(0.4, -0.4, 0.4, -0.4) | vec4(0.25, -0.25, 0.25, -0.25) | vec4(-1.75, 1.75, -1.75, 1.75) | vec4(96.0, -96.0, 96.0, -96.0) | vec4(0.717741935484, -0.717741935484, 0.717741935484, -0.717741935484) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx - in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_x_x
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 0.0 | 0.0 | 0.0 | 0.0 | 0.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x - in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_z_z
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 0.0 | 0.0 | 0.0 | 0.0 | 0.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z - in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xz_zx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(-0.65, 0.65) | vec2(-0.125, 0.125) | vec2(4.375, -4.375) | vec2(19.0, -19.0) | vec2(-0.802631578947, 0.802631578947) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz - in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zz_zz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(0.0, 0.0) | vec2(0.0, 0.0) | vec2(0.0, 0.0) | vec2(0.0, 0.0) | vec2(0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz - in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(-0.4, -0.25, 0.65) | vec3(-0.25, 0.125, 0.125) | vec3(1.75, 2.625, -4.375) | vec3(-96.0, 115.0, -19.0) | vec3(-0.717741935484, -0.0848896434635, 0.802631578947) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz - in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.25, 0.4, -0.65) | vec3(-0.125, 0.25, -0.125) | vec3(-2.625, -1.75, 4.375) | vec3(-115.0, 96.0, 19.0) | vec3(0.0848896434635, 0.717741935484, -0.802631578947) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx - in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx - in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz - in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.0, 0.25, -0.25) | vec3(0.0, -0.125, 0.125) | vec3(0.0, -2.625, 2.625) | vec3(0.0, -115.0, 115.0) | vec3(0.0, 0.0848896434635, -0.0848896434635) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy - in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.4, -0.4, 0.0) | vec3(0.25, -0.25, 0.0) | vec3(-1.75, 1.75, 0.0) | vec3(96.0, -96.0, 0.0) | vec3(0.717741935484, -0.717741935484, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy - in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(-0.65, 0.65, 0.0) | vec3(-0.125, 0.125, 0.0) | vec3(4.375, -4.375, 0.0) | vec3(19.0, -19.0, 0.0) | vec3(-0.802631578947, 0.802631578947, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx - in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(-0.4, 0.0, 0.4, 0.0) | vec4(-0.25, 0.0, 0.25, 0.0) | vec4(1.75, 0.0, -1.75, 0.0) | vec4(-96.0, 0.0, 96.0, 0.0) | vec4(-0.717741935484, 0.0, 0.717741935484, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx - in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(0.65, -0.4, -0.25, 0.0) | vec4(0.125, -0.25, 0.125, 0.0) | vec4(-4.375, 1.75, 2.625, 0.0) | vec4(-19.0, -96.0, 115.0, 0.0) | vec4(0.802631578947, -0.717741935484, -0.0848896434635, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz - in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_x_x
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 0.0 | 0.0 | 0.0 | 0.0 | 0.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x - in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_w_w
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 0.0 | 0.0 | 0.0 | 0.0 | 0.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w - in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wx_xw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(0.725, -0.725) | vec2(0.75, -0.75) | vec2(9.5, -9.5) | vec2(56.0, -56.0) | vec2(1.0, -1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx - in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wz_zw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(0.075, -0.075) | vec2(0.625, -0.625) | vec2(13.875, -13.875) | vec2(75.0, -75.0) | vec2(0.197368421053, -0.197368421053) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz - in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_www_www
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) | vec3(0.0, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www - in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(0.0, -0.325, 0.325) | vec3(0.0, -0.5, 0.5) | vec3(0.0, -11.25, 11.25) | vec3(0.0, 40.0, -40.0) | vec3(0.0, -0.282258064516, 0.282258064516) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw - in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(0.075, 0.25, -0.325) | vec3(0.625, -0.125, -0.5) | vec3(13.875, -2.625, -11.25) | vec3(75.0, -115.0, 40.0) | vec3(0.197368421053, 0.0848896434635, -0.282258064516) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy - in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(-0.4, -0.25, -0.075, 0.725) | vec4(-0.25, 0.125, -0.625, 0.75) | vec4(1.75, 2.625, -13.875, 9.5) | vec4(-96.0, 115.0, -75.0, 56.0) | vec4(-0.717741935484, -0.0848896434635, -0.197368421053, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw - in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.075, 0.25, 0.4, -0.725) | vec4(0.625, -0.125, 0.25, -0.75) | vec4(13.875, -2.625, -1.75, -9.5) | vec4(75.0, -115.0, 96.0, -56.0) | vec4(0.197368421053, 0.0848896434635, 0.717741935484, -1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx - in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(-0.4, 0.4, -0.4, 0.4) | vec4(-0.25, 0.25, -0.25, 0.25) | vec4(1.75, -1.75, 1.75, -1.75) | vec4(-96.0, 96.0, -96.0, 96.0) | vec4(-0.717741935484, 0.717741935484, -0.717741935484, 0.717741935484) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy - in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(-0.25, 0.0, 0.25, 0.0) | vec4(0.125, 0.0, -0.125, 0.0) | vec4(2.625, 0.0, -2.625, 0.0) | vec4(115.0, 0.0, -115.0, 0.0) | vec4(-0.0848896434635, 0.0, 0.0848896434635, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy - in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.725, -0.725, 0.0, 0.0) | vec4(0.75, -0.75, 0.0, 0.0) | vec4(9.5, -9.5, 0.0, 0.0) | vec4(56.0, -56.0, 0.0, 0.0) | vec4(1.0, -1.0, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww - in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(-0.4, 0.4, 0.0, 0.0) | vec4(-0.25, 0.25, 0.0, 0.0) | vec4(1.75, -1.75, 0.0, 0.0) | vec4(-96.0, 96.0, 0.0, 0.0) | vec4(-0.717741935484, 0.717741935484, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx - in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.0, 0.0, 0.0, 0.0) | vec4(0.0, 0.0, 0.0, 0.0) | vec4(0.0, 0.0, 0.0, 0.0) | vec4(0.0, 0.0, 0.0, 0.0) | vec4(0.0, 0.0, 0.0, 0.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz - in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_x_x
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output int out0 = [ 0 | 0 | 0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x - in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xx_xx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(0, 0) | ivec2(0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx - in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xy_yx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(-2, 2) | ivec2(-1, 1) | ivec2(1, -1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy - in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yx_xy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(2, -2) | ivec2(1, -1) | ivec2(-1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx - in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec3 out0 = [ ivec3(2, -2, 0) | ivec3(1, -1, 0) | ivec3(-1, 1, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy - in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(-2, 2, 0, 0) | ivec4(-1, 1, 0, 0) | ivec4(1, -1, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx - in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(2, -2, 2, -2) | ivec4(1, -1, 1, -1) | ivec4(-1, 1, -1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx - in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_x_x
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ 0 | 0 | 0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x - in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_z_z
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ 0 | 0 | 0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z - in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xz_zx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(-2, 2) | ivec2(3, -3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz - in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zz_zz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(0, 0) | ivec2(0, 0) | ivec2(0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz - in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-2, 2, 0) | ivec3(-1, -1, 2) | ivec3(1, 2, -3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz - in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-2, 2, 0) | ivec3(1, 1, -2) | ivec3(-2, -1, 3) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx - in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, 0, 0) | ivec3(0, 0, 0) | ivec3(0, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx - in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, 0, 0) | ivec3(0, 0, 0) | ivec3(0, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz - in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, -2, 2) | ivec3(0, 1, -1) | ivec3(0, -2, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy - in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(2, -2, 0) | ivec3(1, -1, 0) | ivec3(-1, 1, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy - in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(0, 0, 0) | ivec3(-2, 2, 0) | ivec3(3, -3, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx - in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(-2, 0, 2, 0) | ivec4(-1, 0, 1, 0) | ivec4(1, 0, -1, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx - in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(0, -2, 2, 0) | ivec4(2, -1, -1, 0) | ivec4(-3, 1, 2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz - in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_x_x
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 0 | 0 | 0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x - in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_w_w
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 0 | 0 | 0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w - in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wx_xw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(2, -2) | ivec2(3, -3) | ivec2(-8, 8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx - in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wz_zw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(2, -2) | ivec2(1, -1) | ivec2(-5, 5) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz - in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_www_www
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(0, 0, 0) | ivec3(0, 0, 0) | ivec3(0, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www - in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(0, 0, 0) | ivec3(0, -2, 2) | ivec3(0, 7, -7) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw - in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(2, -2, 0) | ivec3(1, 1, -2) | ivec3(-5, -2, 7) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy - in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-2, 2, -2, 2) | ivec4(-1, -1, -1, 3) | ivec4(1, 2, 5, -8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw - in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(2, -2, 2, -2) | ivec4(1, 1, 1, -3) | ivec4(-5, -2, -1, 8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx - in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-2, 2, -2, 2) | ivec4(-1, 1, -1, 1) | ivec4(1, -1, 1, -1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy - in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(2, 0, -2, 0) | ivec4(-1, 0, 1, 0) | ivec4(2, 0, -2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy - in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(2, -2, 0, 0) | ivec4(3, -3, 0, 0) | ivec4(-8, 8, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww - in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-2, 2, 0, 0) | ivec4(-1, 1, 0, 0) | ivec4(1, -1, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx - in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(0, 0, 0, 0) | ivec4(0, 0, 0, 0) | ivec4(0, 0, 0, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz - in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+
+end # vector_subtract
+group vector_multiply "Vector swizzle math operations"
+
+	case mediump_vec2_x_x
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output float out0 = [ 0.01 | 1.0 | 0.25 | 1024.0 | 0.5625 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x * in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xx_xx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.01, 0.01) | vec2(1.0, 1.0) | vec2(0.25, 0.25) | vec2(1024.0, 1024.0) | vec2(0.5625, 0.5625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx * in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xy_yx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.05, 0.05) | vec2(1.25, 1.25) | vec2(1.125, 1.125) | vec2(-2048.0, -2048.0) | vec2(0.0241935483871, 0.0241935483871) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy * in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yx_xy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.05, 0.05) | vec2(1.25, 1.25) | vec2(1.125, 1.125) | vec2(-2048.0, -2048.0) | vec2(0.0241935483871, 0.0241935483871) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx * in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec3 out0 = [ vec3(0.05, 0.05, 0.25) | vec3(1.25, 1.25, 1.5625) | vec3(1.125, 1.125, 5.0625) | vec3(-2048.0, -2048.0, 4096.0) | vec3(0.0241935483871, 0.0241935483871, 0.00104058272633) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy * in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(0.05, 0.05, 0.01, 0.01) | vec4(1.25, 1.25, 1.0, 1.0) | vec4(1.125, 1.125, 0.25, 0.25) | vec4(-2048.0, -2048.0, 1024.0, 1024.0) | vec4(0.0241935483871, 0.0241935483871, 0.5625, 0.5625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx * in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(0.05, 0.05, 0.05, 0.05) | vec4(1.25, 1.25, 1.25, 1.25) | vec4(1.125, 1.125, 1.125, 1.125) | vec4(-2048.0, -2048.0, -2048.0, -2048.0) | vec4(0.0241935483871, 0.0241935483871, 0.0241935483871, 0.0241935483871) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx * in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_x_x
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 0.01 | 1.0 | 0.25 | 1024.0 | 0.5625 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x * in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_z_z
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 0.5625 | 1.265625 | 23.765625 | 2601.0 | 0.00277008310249 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z * in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xz_zx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(0.075, 0.075) | vec2(1.125, 1.125) | vec2(2.4375, 2.4375) | vec2(1632.0, 1632.0) | vec2(-0.0394736842105, -0.0394736842105) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz * in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zz_zz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(0.5625, 0.5625) | vec2(1.265625, 1.265625) | vec2(23.765625, 23.765625) | vec2(2601.0, 2601.0) | vec2(0.00277008310249, 0.00277008310249) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz * in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.05, 0.375, 0.075) | vec3(1.25, 1.40625, 1.125) | vec3(1.125, 10.96875, 2.4375) | vec3(-2048.0, -3264.0, 1632.0) | vec3(0.0241935483871, -0.00169779286927, -0.0394736842105) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz * in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.375, 0.05, 0.075) | vec3(1.40625, 1.25, 1.125) | vec3(10.96875, 1.125, 2.4375) | vec3(-3264.0, -2048.0, 1632.0) | vec3(-0.00169779286927, 0.0241935483871, -0.0394736842105) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx * in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.01, 0.01, 0.01) | vec3(1.0, 1.0, 1.0) | vec3(0.25, 0.25, 0.25) | vec3(1024.0, 1024.0, 1024.0) | vec3(0.5625, 0.5625, 0.5625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx * in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.5625, 0.5625, 0.5625) | vec3(1.265625, 1.265625, 1.265625) | vec3(23.765625, 23.765625, 23.765625) | vec3(2601.0, 2601.0, 2601.0) | vec3(0.00277008310249, 0.00277008310249, 0.00277008310249) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz * in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.5625, 0.375, 0.375) | vec3(1.265625, 1.40625, 1.40625) | vec3(23.765625, 10.96875, 10.96875) | vec3(2601.0, -3264.0, -3264.0) | vec3(0.00277008310249, -0.00169779286927, -0.00169779286927) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy * in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.05, 0.05, 0.25) | vec3(1.25, 1.25, 1.5625) | vec3(1.125, 1.125, 5.0625) | vec3(-2048.0, -2048.0, 4096.0) | vec3(0.0241935483871, 0.0241935483871, 0.00104058272633) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy * in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.075, 0.075, 0.01) | vec3(1.125, 1.125, 1.0) | vec3(2.4375, 2.4375, 0.25) | vec3(1632.0, 1632.0, 1024.0) | vec3(-0.0394736842105, -0.0394736842105, 0.5625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx * in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(0.05, 0.25, 0.05, 0.01) | vec4(1.25, 1.5625, 1.25, 1.0) | vec4(1.125, 5.0625, 1.125, 0.25) | vec4(-2048.0, 4096.0, -2048.0, 1024.0) | vec4(0.0241935483871, 0.00104058272633, 0.0241935483871, 0.5625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx * in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(0.075, 0.05, 0.375, 0.5625) | vec4(1.125, 1.25, 1.40625, 1.265625) | vec4(2.4375, 1.125, 10.96875, 23.765625) | vec4(1632.0, -2048.0, -3264.0, 2601.0) | vec4(-0.0394736842105, 0.0241935483871, -0.00169779286927, 0.00277008310249) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz * in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_x_x
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 0.01 | 1.0 | 0.25 | 1024.0 | 0.5625 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x * in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_w_w
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 0.680625 | 3.0625 | 81.0 | 576.0 | 0.0625 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w * in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wx_xw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(0.0825, 0.0825) | vec2(1.75, 1.75) | vec2(-4.5, -4.5) | vec2(-768.0, -768.0) | vec2(-0.1875, -0.1875) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx * in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wz_zw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(0.61875, 0.61875) | vec2(1.96875, 1.96875) | vec2(-43.875, -43.875) | vec2(-1224.0, -1224.0) | vec2(0.0131578947368, 0.0131578947368) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz * in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_www_www
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(0.680625, 0.680625, 0.680625) | vec3(3.0625, 3.0625, 3.0625) | vec3(81.0, 81.0, 81.0) | vec3(576.0, 576.0, 576.0) | vec3(0.0625, 0.0625, 0.0625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www * in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(0.25, 0.4125, 0.4125) | vec3(1.5625, 2.1875, 2.1875) | vec3(5.0625, -20.25, -20.25) | vec3(4096.0, 1536.0, 1536.0) | vec3(0.00104058272633, -0.00806451612903, -0.00806451612903) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw * in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(0.61875, 0.375, 0.4125) | vec3(1.96875, 1.40625, 2.1875) | vec3(-43.875, 10.96875, -20.25) | vec3(-1224.0, -3264.0, 1536.0) | vec3(0.0131578947368, -0.00169779286927, -0.00806451612903) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy * in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.05, 0.375, 0.61875, 0.0825) | vec4(1.25, 1.40625, 1.96875, 1.75) | vec4(1.125, 10.96875, -43.875, -4.5) | vec4(-2048.0, -3264.0, -1224.0, -768.0) | vec4(0.0241935483871, -0.00169779286927, 0.0131578947368, -0.1875) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw * in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.61875, 0.375, 0.05, 0.0825) | vec4(1.96875, 1.40625, 1.25, 1.75) | vec4(-43.875, 10.96875, 1.125, -4.5) | vec4(-1224.0, -3264.0, -2048.0, -768.0) | vec4(0.0131578947368, -0.00169779286927, 0.0241935483871, -0.1875) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx * in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.05, 0.05, 0.05, 0.05) | vec4(1.25, 1.25, 1.25, 1.25) | vec4(1.125, 1.125, 1.125, 1.125) | vec4(-2048.0, -2048.0, -2048.0, -2048.0) | vec4(0.0241935483871, 0.0241935483871, 0.0241935483871, 0.0241935483871) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy * in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.375, 0.5625, 0.375, 0.25) | vec4(1.40625, 1.265625, 1.40625, 1.5625) | vec4(10.96875, 23.765625, 10.96875, 5.0625) | vec4(-3264.0, 2601.0, -3264.0, 4096.0) | vec4(-0.00169779286927, 0.00277008310249, -0.00169779286927, 0.00104058272633) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy * in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.0825, 0.0825, 0.680625, 0.680625) | vec4(1.75, 1.75, 3.0625, 3.0625) | vec4(-4.5, -4.5, 81.0, 81.0) | vec4(-768.0, -768.0, 576.0, 576.0) | vec4(-0.1875, -0.1875, 0.0625, 0.0625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww * in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.05, 0.05, 0.01, 0.01) | vec4(1.25, 1.25, 1.0, 1.0) | vec4(1.125, 1.125, 0.25, 0.25) | vec4(-2048.0, -2048.0, 1024.0, 1024.0) | vec4(0.0241935483871, 0.0241935483871, 0.5625, 0.5625) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx * in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.5625, 0.5625, 0.5625, 0.5625) | vec4(1.265625, 1.265625, 1.265625, 1.265625) | vec4(23.765625, 23.765625, 23.765625, 23.765625) | vec4(2601.0, 2601.0, 2601.0, 2601.0) | vec4(0.00277008310249, 0.00277008310249, 0.00277008310249, 0.00277008310249) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz * in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_x_x
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x * in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xx_xx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(1, 1) | ivec2(1, 1) | ivec2(1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx * in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xy_yx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(2, 2) | ivec2(2, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy * in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yx_xy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(2, 2) | ivec2(2, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx * in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(2, 2, 4) | ivec3(2, 2, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy * in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(-1, -1, 1, 1) | ivec4(2, 2, 1, 1) | ivec4(2, 2, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx * in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(2, 2, 2, 2) | ivec4(2, 2, 2, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx * in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_x_x
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x * in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_z_z
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ 1 | 9 | 16 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z * in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xz_zx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(1, 1) | ivec2(3, 3) | ivec2(4, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz * in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zz_zz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(1, 1) | ivec2(9, 9) | ivec2(16, 16) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz * in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(2, 6, 3) | ivec3(2, 8, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz * in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(6, 2, 3) | ivec3(8, 2, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx * in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(1, 1, 1) | ivec3(1, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx * in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(9, 9, 9) | ivec3(16, 16, 16) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz * in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, -1, -1) | ivec3(9, 6, 6) | ivec3(16, 8, 8) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy * in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(2, 2, 4) | ivec3(2, 2, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy * in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(3, 3, 1) | ivec3(4, 4, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx * in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(-1, 1, -1, 1) | ivec4(2, 4, 2, 1) | ivec4(2, 4, 2, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx * in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(1, -1, -1, 1) | ivec4(3, 2, 6, 9) | ivec4(4, 2, 8, 16) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz * in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_x_x
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x * in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_w_w
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 1 | 16 | 81 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w * in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wx_xw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(4, 4) | ivec2(9, 9) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx * in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wz_zw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(12, 12) | ivec2(36, 36) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz * in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_www_www
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(16, 16, 16) | ivec3(81, 81, 81) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www * in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(4, 8, 8) | ivec3(4, 18, 18) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw * in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(12, 6, 8) | ivec3(36, 8, 18) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy * in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(2, 6, 12, 4) | ivec4(2, 8, 36, 9) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw * in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(12, 6, 2, 4) | ivec4(36, 8, 2, 9) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx * in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(2, 2, 2, 2) | ivec4(2, 2, 2, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy * in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, 1, -1, 1) | ivec4(6, 9, 6, 4) | ivec4(8, 16, 8, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy * in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, 1, 1) | ivec4(4, 4, 16, 16) | ivec4(9, 9, 81, 81) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww * in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, 1, 1) | ivec4(2, 2, 1, 1) | ivec4(2, 2, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx * in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(1, 1, 1, 1) | ivec4(9, 9, 9, 9) | ivec4(16, 16, 16, 16) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz * in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+
+end # vector_multiply
+group vector_divide "Vector swizzle math operations"
+
+	case mediump_vec2_x_x
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output float out0 = [ 1.0 | 1.0 | 1.0 | 1.0 | 1.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x / in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xx_xx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(1.0, 1.0) | vec2(1.0, 1.0) | vec2(1.0, 1.0) | vec2(1.0, 1.0) | vec2(1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx / in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xy_yx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(0.2, 5.0) | vec2(0.8, 1.25) | vec2(0.222222222222, 4.5) | vec2(-0.5, -2.0) | vec2(23.25, 0.0430107526882) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy / in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yx_xy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec2 out0 = [ vec2(5.0, 0.2) | vec2(1.25, 0.8) | vec2(4.5, 0.222222222222) | vec2(-2.0, -0.5) | vec2(0.0430107526882, 23.25) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx / in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec3 out0 = [ vec3(5.0, 0.2, 1.0) | vec3(1.25, 0.8, 1.0) | vec3(4.5, 0.222222222222, 1.0) | vec3(-2.0, -0.5, 1.0) | vec3(0.0430107526882, 23.25, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy / in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(0.2, 5.0, 1.0, 1.0) | vec4(0.8, 1.25, 1.0, 1.0) | vec4(0.222222222222, 4.5, 1.0, 1.0) | vec4(-0.5, -2.0, 1.0, 1.0) | vec4(23.25, 0.0430107526882, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx / in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input vec2 in0 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			input vec2 in1 = [ vec2(0.1, 0.5) | vec2(1.0, 1.25) | vec2(-0.5, -2.25) | vec2(-32.0, 64.0) | vec2(-0.75, -0.0322580645161) ];
+			output vec4 out0 = [ vec4(5.0, 0.2, 5.0, 0.2) | vec4(1.25, 0.8, 1.25, 0.8) | vec4(4.5, 0.222222222222, 4.5, 0.222222222222) | vec4(-2.0, -0.5, -2.0, -0.5) | vec4(0.0430107526882, 23.25, 0.0430107526882, 23.25) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx / in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_x_x
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 1.0 | 1.0 | 1.0 | 1.0 | 1.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x / in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_z_z
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output float out0 = [ 1.0 | 1.0 | 1.0 | 1.0 | 1.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z / in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xz_zx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(0.133333333333, 7.5) | vec2(0.888888888889, 1.125) | vec2(0.102564102564, 9.75) | vec2(0.627450980392, 1.59375) | vec2(-14.25, -0.0701754385965) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz / in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zz_zz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec2 out0 = [ vec2(1.0, 1.0) | vec2(1.0, 1.0) | vec2(1.0, 1.0) | vec2(1.0, 1.0) | vec2(1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz / in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.2, 0.666666666667, 7.5) | vec3(0.8, 1.11111111111, 1.125) | vec3(0.222222222222, 0.461538461538, 9.75) | vec3(-0.5, -1.25490196078, 1.59375) | vec3(23.25, -0.612903225806, -0.0701754385965) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz / in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.5, 5.0, 0.133333333333) | vec3(0.9, 1.25, 0.888888888889) | vec3(2.16666666667, 4.5, 0.102564102564) | vec3(-0.796875, -2.0, 0.627450980392) | vec3(-1.63157894737, 0.0430107526882, -14.25) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx / in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx / in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz / in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(1.0, 1.5, 0.666666666667) | vec3(1.0, 0.9, 1.11111111111) | vec3(1.0, 2.16666666667, 0.461538461538) | vec3(1.0, -0.796875, -1.25490196078) | vec3(1.0, -1.63157894737, -0.612903225806) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy / in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(5.0, 0.2, 1.0) | vec3(1.25, 0.8, 1.0) | vec3(4.5, 0.222222222222, 1.0) | vec3(-2.0, -0.5, 1.0) | vec3(0.0430107526882, 23.25, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy / in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec3 out0 = [ vec3(0.133333333333, 7.5, 1.0) | vec3(0.888888888889, 1.125, 1.0) | vec3(0.102564102564, 9.75, 1.0) | vec3(0.627450980392, 1.59375, 1.0) | vec3(-14.25, -0.0701754385965, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx / in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(0.2, 1.0, 5.0, 1.0) | vec4(0.8, 1.0, 1.25, 1.0) | vec4(0.222222222222, 1.0, 4.5, 1.0) | vec4(-0.5, 1.0, -2.0, 1.0) | vec4(23.25, 1.0, 0.0430107526882, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx / in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input vec3 in0 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			input vec3 in1 = [ vec3(0.1, 0.5, 0.75) | vec3(1.0, 1.25, 1.125) | vec3(-0.5, -2.25, -4.875) | vec3(-32.0, 64.0, -51.0) | vec3(-0.75, -0.0322580645161, 0.0526315789474) ];
+			output vec4 out0 = [ vec4(7.5, 0.2, 0.666666666667, 1.0) | vec4(1.125, 0.8, 1.11111111111, 1.0) | vec4(9.75, 0.222222222222, 0.461538461538, 1.0) | vec4(1.59375, -0.5, -1.25490196078, 1.0) | vec4(-0.0701754385965, 23.25, -0.612903225806, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz / in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_x_x
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 1.0 | 1.0 | 1.0 | 1.0 | 1.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x / in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_w_w
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output float out0 = [ 1.0 | 1.0 | 1.0 | 1.0 | 1.0 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w / in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wx_xw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(8.25, 0.121212121212) | vec2(1.75, 0.571428571429) | vec2(-18.0, -0.0555555555556) | vec2(-0.75, -1.33333333333) | vec2(-0.333333333333, -3.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx / in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wz_zw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec2 out0 = [ vec2(1.1, 0.909090909091) | vec2(1.55555555556, 0.642857142857) | vec2(-1.84615384615, -0.541666666667) | vec2(-0.470588235294, -2.125) | vec2(4.75, 0.210526315789) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz / in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_www_www
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) | vec3(1.0, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www / in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(1.0, 0.606060606061, 1.65) | vec3(1.0, 0.714285714286, 1.4) | vec3(1.0, -0.25, -4.0) | vec3(1.0, 2.66666666667, 0.375) | vec3(1.0, -0.129032258065, -7.75) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw / in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec3 out0 = [ vec3(1.1, 1.5, 0.606060606061) | vec3(1.55555555556, 0.9, 0.714285714286) | vec3(-1.84615384615, 2.16666666667, -0.25) | vec3(-0.470588235294, -0.796875, 2.66666666667) | vec3(4.75, -1.63157894737, -0.129032258065) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy / in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.2, 0.666666666667, 0.909090909091, 8.25) | vec4(0.8, 1.11111111111, 0.642857142857, 1.75) | vec4(0.222222222222, 0.461538461538, -0.541666666667, -18.0) | vec4(-0.5, -1.25490196078, -2.125, -0.75) | vec4(23.25, -0.612903225806, 0.210526315789, -0.333333333333) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw / in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(1.1, 1.5, 5.0, 0.121212121212) | vec4(1.55555555556, 0.9, 1.25, 0.571428571429) | vec4(-1.84615384615, 2.16666666667, 4.5, -0.0555555555556) | vec4(-0.470588235294, -0.796875, -2.0, -1.33333333333) | vec4(4.75, -1.63157894737, 0.0430107526882, -3.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx / in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.2, 5.0, 0.2, 5.0) | vec4(0.8, 1.25, 0.8, 1.25) | vec4(0.222222222222, 4.5, 0.222222222222, 4.5) | vec4(-0.5, -2.0, -0.5, -2.0) | vec4(23.25, 0.0430107526882, 23.25, 0.0430107526882) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy / in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.666666666667, 1.0, 1.5, 1.0) | vec4(1.11111111111, 1.0, 0.9, 1.0) | vec4(0.461538461538, 1.0, 2.16666666667, 1.0) | vec4(-1.25490196078, 1.0, -0.796875, 1.0) | vec4(-0.612903225806, 1.0, -1.63157894737, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy / in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(8.25, 0.121212121212, 1.0, 1.0) | vec4(1.75, 0.571428571429, 1.0, 1.0) | vec4(-18.0, -0.0555555555556, 1.0, 1.0) | vec4(-0.75, -1.33333333333, 1.0, 1.0) | vec4(-0.333333333333, -3.0, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww / in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(0.2, 5.0, 1.0, 1.0) | vec4(0.8, 1.25, 1.0, 1.0) | vec4(0.222222222222, 4.5, 1.0, 1.0) | vec4(-0.5, -2.0, 1.0, 1.0) | vec4(23.25, 0.0430107526882, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx / in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_vec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input vec4 in0 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			input vec4 in1 = [ vec4(0.1, 0.5, 0.75, 0.825) | vec4(1.0, 1.25, 1.125, 1.75) | vec4(-0.5, -2.25, -4.875, 9.0) | vec4(-32.0, 64.0, -51.0, 24.0) | vec4(-0.75, -0.0322580645161, 0.0526315789474, 0.25) ];
+			output vec4 out0 = [ vec4(1.0, 1.0, 1.0, 1.0) | vec4(1.0, 1.0, 1.0, 1.0) | vec4(1.0, 1.0, 1.0, 1.0) | vec4(1.0, 1.0, 1.0, 1.0) | vec4(1.0, 1.0, 1.0, 1.0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz / in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_x_x
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x / in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xx_xx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(1, 1) | ivec2(1, 1) | ivec2(1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xx / in1.xx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xy_yx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(0, 2) | ivec2(0, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xy / in1.yx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yx_xy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(2, 0) | ivec2(2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yx / in1.xy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(2, 0, 1) | ivec3(2, 0, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy / in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(-1, -1, 1, 1) | ivec4(0, 2, 1, 1) | ivec4(0, 2, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx / in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec2_yxyx_xyxy
+		version 300 es
+		values
+		{
+			input ivec2 in0 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			input ivec2 in1 = [ ivec2(-1, 1) | ivec2(1, 2) | ivec2(-1, -2) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(2, 0, 2, 0) | ivec4(2, 0, 2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxyx / in1.xyxy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_x_x
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x / in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_z_z
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.z / in1.z;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xz_zx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(1, 1) | ivec2(0, 3) | ivec2(0, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xz / in1.zx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zz_zz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec2 out0 = [ ivec2(1, 1) | ivec2(1, 1) | ivec2(1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zz / in1.zz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyz_yzx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(0, 0, 3) | ivec3(0, 0, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyz / in1.yzx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zyx_yxz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(1, 2, 0) | ivec3(2, 2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zyx / in1.yxz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xxx_xxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(1, 1, 1) | ivec3(1, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xxx / in1.xxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzz_zzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(1, 1, 1) | ivec3(1, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzz / in1.zzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zzy_zyz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, -1, -1) | ivec3(1, 1, 0) | ivec3(1, 2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzy / in1.zyz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_yxy_xyy
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(2, 0, 1) | ivec3(2, 0, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yxy / in1.xyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xzx_zxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(0, 3, 1) | ivec3(0, 4, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xzx / in1.zxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_xyyx_yyxx
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(-1, 1, -1, 1) | ivec4(0, 1, 2, 1) | ivec4(0, 1, 2, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyyx / in1.yyxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec3_zxyz_xyzz
+		version 300 es
+		values
+		{
+			input ivec3 in0 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			input ivec3 in1 = [ ivec3(-1, 1, -1) | ivec3(1, 2, 3) | ivec3(-1, -2, -4) ];
+			output ivec4 out0 = [ ivec4(1, -1, -1, 1) | ivec4(3, 0, 0, 1) | ivec4(4, 0, 0, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zxyz / in1.xyzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_x_x
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.x / in1.x;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_w_w
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output int out0 = [ 1 | 1 | 1 ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.w / in1.w;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wx_xw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(4, 0) | ivec2(9, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wx / in1.xw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wz_zw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec2 out0 = [ ivec2(-1, -1) | ivec2(1, 0) | ivec2(2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wz / in1.zw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_www_www
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(1, 1, 1) | ivec3(1, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.www / in1.www;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yyw_ywy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(1, 1, 1) | ivec3(1, 0, 2) | ivec3(1, 0, 4) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yyw / in1.ywy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzy_zyw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec3 out0 = [ ivec3(-1, -1, 1) | ivec3(1, 1, 0) | ivec3(2, 2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzy / in1.zyw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyzw_yzwx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(0, 0, 0, 4) | ivec4(0, 0, 0, 9) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyzw / in1.yzwx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wzyx_zyxw
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(1, 1, 2, 0) | ivec4(2, 2, 2, 0) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wzyx / in1.zyxw;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxy_yxyx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, -1, -1) | ivec4(0, 2, 0, 2) | ivec4(0, 2, 0, 2) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxy / in1.yxyx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_yzzy_zzyy
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, 1, -1, 1) | ivec4(0, 1, 1, 1) | ivec4(0, 1, 2, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.yzzy / in1.zzyy;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_wxww_xwww
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, 1, 1) | ivec4(4, 0, 1, 1) | ivec4(9, 0, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.wxww / in1.xwww;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_xyxx_yxxx
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(-1, -1, 1, 1) | ivec4(0, 2, 1, 1) | ivec4(0, 2, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.xyxx / in1.yxxx;
+				${OUTPUT}
+			}
+		""
+	end
+
+	case mediump_ivec4_zzzz_zzzz
+		version 300 es
+		values
+		{
+			input ivec4 in0 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			input ivec4 in1 = [ ivec4(-1, 1, -1, 1) | ivec4(1, 2, 3, 4) | ivec4(-1, -2, -4, -9) ];
+			output ivec4 out0 = [ ivec4(1, 1, 1, 1) | ivec4(1, 1, 1, 1) | ivec4(1, 1, 1, 1) ];
+		}
+
+		both ""
+			#version 300 es
+			precision mediump float;
+
+			${DECLARATIONS}
+
+			void main()
+			{
+				${SETUP}
+				out0 = in0.zzzz / in1.zzzz;
+				${OUTPUT}
+			}
+		""
+	end
+
+
+end # vector_divide
diff --git a/external/fetch_sources.py b/external/fetch_sources.py
index 2aa2b57..6376692 100644
--- a/external/fetch_sources.py
+++ b/external/fetch_sources.py
@@ -105,7 +105,7 @@
 		dstPath		= os.path.join(EXTERNAL_DIR, self.baseDir, self.archiveDir, self.filename)
 
 		if checksum != self.checksum:
-			raise Exception("Checksum mismatch for %s, exepected %s, got %s" % (self.filename, self.checksum, checksum))
+			raise Exception("Checksum mismatch for %s, expected %s, got %s" % (self.filename, self.checksum, checksum))
 
 		if not os.path.exists(os.path.dirname(dstPath)):
 			os.mkdir(os.path.dirname(dstPath))
diff --git a/framework/common/tcuApp.cpp b/framework/common/tcuApp.cpp
index 6227089..949f083 100644
--- a/framework/common/tcuApp.cpp
+++ b/framework/common/tcuApp.cpp
@@ -203,10 +203,10 @@
 	return platformOk && testExecOk;
 }
 
-void App::onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr)
+void App::onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr, qpTimeoutReason reason)
 {
 	DE_UNREF(watchDog);
-	static_cast<App*>(userPtr)->onWatchdogTimeout();
+	static_cast<App*>(userPtr)->onWatchdogTimeout(reason);
 }
 
 void App::onCrash (qpCrashHandler* crashHandler, void* userPtr)
@@ -215,7 +215,7 @@
 	static_cast<App*>(userPtr)->onCrash();
 }
 
-void App::onWatchdogTimeout (void)
+void App::onWatchdogTimeout (qpTimeoutReason reason)
 {
 	if (!m_crashLock.tryLock() || m_crashed)
 		return; // In crash handler already.
@@ -223,7 +223,7 @@
 	m_crashed = true;
 
 	m_testCtx->getLog().terminateCase(QP_TEST_RESULT_TIMEOUT);
-	die("Watchdog timer timeout");
+	die("Watchdog timer timeout for %s", (reason == QP_TIMEOUT_REASON_INTERVAL_LIMIT ? "touch interval" : "total time"));
 }
 
 static void writeCrashToLog (void* userPtr, const char* infoString)
diff --git a/framework/common/tcuApp.hpp b/framework/common/tcuApp.hpp
index 8233eb3..e714160 100644
--- a/framework/common/tcuApp.hpp
+++ b/framework/common/tcuApp.hpp
@@ -69,10 +69,10 @@
 protected:
 	void					cleanup				(void);
 
-	void					onWatchdogTimeout	(void);
+	void					onWatchdogTimeout	(qpTimeoutReason reason);
 	void					onCrash				(void);
 
-	static void				onWatchdogTimeout	(qpWatchDog* watchDog, void* userPtr);
+	static void				onWatchdogTimeout	(qpWatchDog* watchDog, void* userPtr, qpTimeoutReason reason);
 	static void				onCrash				(qpCrashHandler* crashHandler, void* userPtr);
 
 	Platform&				m_platform;
diff --git a/framework/egl/egluCallLogWrapper.inl b/framework/egl/egluCallLogWrapper.inl
index ee49459..cfab0cc 100644
--- a/framework/egl/egluCallLogWrapper.inl
+++ b/framework/egl/egluCallLogWrapper.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 
 eglw::EGLBoolean CallLogWrapper::eglBindAPI (eglw::EGLenum api)
diff --git a/framework/egl/egluCallLogWrapperApi.inl b/framework/egl/egluCallLogWrapperApi.inl
index 99df24b..1d51c25 100644
--- a/framework/egl/egluCallLogWrapperApi.inl
+++ b/framework/egl/egluCallLogWrapperApi.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 eglw::EGLBoolean								eglBindAPI							(eglw::EGLenum api);
 eglw::EGLBoolean								eglBindTexImage						(eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint buffer);
diff --git a/framework/egl/egluStaticES20Library.inl b/framework/egl/egluStaticES20Library.inl
index fe4f4dc..1e68aa2 100644
--- a/framework/egl/egluStaticES20Library.inl
+++ b/framework/egl/egluStaticES20Library.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 	{ "glActiveTexture",						(deFunctionPtr)glActiveTexture },
 	{ "glAttachShader",							(deFunctionPtr)glAttachShader },
diff --git a/framework/egl/egluStaticES30Library.inl b/framework/egl/egluStaticES30Library.inl
index c3cbc28..a6cdd6c 100644
--- a/framework/egl/egluStaticES30Library.inl
+++ b/framework/egl/egluStaticES30Library.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 	{ "glActiveTexture",						(deFunctionPtr)glActiveTexture },
 	{ "glAttachShader",							(deFunctionPtr)glAttachShader },
diff --git a/framework/egl/egluStrUtil.inl b/framework/egl/egluStrUtil.inl
index 2c563e5..02b3d1b 100644
--- a/framework/egl/egluStrUtil.inl
+++ b/framework/egl/egluStrUtil.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 
 const char* getBooleanName (int value)
diff --git a/framework/egl/egluStrUtilPrototypes.inl b/framework/egl/egluStrUtilPrototypes.inl
index 839837f..f7975aa 100644
--- a/framework/egl/egluStrUtilPrototypes.inl
+++ b/framework/egl/egluStrUtilPrototypes.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 const char*							getBooleanName				(int value);
 const char*							getBoolDontCareName			(int value);
diff --git a/framework/egl/wrapper/eglwApi.inl b/framework/egl/wrapper/eglwApi.inl
index fadb2a9..2d26cb9 100644
--- a/framework/egl/wrapper/eglwApi.inl
+++ b/framework/egl/wrapper/eglwApi.inl
@@ -1,7 +1,11 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
+<<<<<<< HEAD
  * Generated from Khronos EGL API description (egl.xml) revision 28861.
+=======
+ * Generated from Khronos EGL API description (egl.xml) revision 7fdf7d3a1ad50afa03968db889b68af211da6e27.
+>>>>>>> 2528a63a9... Fetch gl.xml, egl.xml from Github repos
  */
 #define										eglBindAPI							eglwBindAPI
 #define										eglBindTexImage						eglwBindTexImage
diff --git a/framework/egl/wrapper/eglwEnums.inl b/framework/egl/wrapper/eglwEnums.inl
index edb58c5..b0e51b6 100644
--- a/framework/egl/wrapper/eglwEnums.inl
+++ b/framework/egl/wrapper/eglwEnums.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 #define EGL_PBUFFER_BIT										0x0001
 #define EGL_PIXMAP_BIT										0x0002
@@ -124,9 +124,11 @@
 #define EGL_ALPHA_FORMAT									0x3088
 #define EGL_COLORSPACE_sRGB									0x3089
 #define EGL_GL_COLORSPACE_SRGB								0x3089
+#define EGL_GL_COLORSPACE_SRGB_KHR							0x3089
 #define EGL_VG_COLORSPACE_sRGB								0x3089
 #define EGL_COLORSPACE_LINEAR								0x308A
 #define EGL_GL_COLORSPACE_LINEAR							0x308A
+#define EGL_GL_COLORSPACE_LINEAR_KHR						0x308A
 #define EGL_VG_COLORSPACE_LINEAR							0x308A
 #define EGL_ALPHA_FORMAT_NONPRE								0x308B
 #define EGL_ALPHA_FORMAT_NONPRE								0x308B
@@ -151,6 +153,7 @@
 #define EGL_MULTISAMPLE_RESOLVE_BOX							0x309B
 #define EGL_CL_EVENT_HANDLE									0x309C
 #define EGL_GL_COLORSPACE									0x309D
+#define EGL_GL_COLORSPACE_KHR								0x309D
 #define EGL_OPENGL_ES_API									0x30A0
 #define EGL_OPENVG_API										0x30A1
 #define EGL_OPENGL_API										0x30A2
@@ -267,3 +270,9 @@
 #define EGL_COLOR_COMPONENT_TYPE_EXT						0x3339
 #define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT					0x333A
 #define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT					0x333B
+#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT					0x333F
+#define EGL_GL_COLORSPACE_BT2020_PQ_EXT						0x3340
+#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT					0x3350
+#define EGL_GL_COLORSPACE_SCRGB_EXT							0x3351
+#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT				0x3362
+#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT					0x3363
diff --git a/framework/egl/wrapper/eglwEnumsC.inl b/framework/egl/wrapper/eglwEnumsC.inl
new file mode 100644
index 0000000..5a1cf17
--- /dev/null
+++ b/framework/egl/wrapper/eglwEnumsC.inl
@@ -0,0 +1,278 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ *
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
+ */
+#define EGL_PBUFFER_BIT										0x0001
+#define EGL_PIXMAP_BIT										0x0002
+#define EGL_WINDOW_BIT										0x0004
+#define EGL_VG_COLORSPACE_LINEAR_BIT						0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT							0x0040
+#define EGL_LOCK_SURFACE_BIT_KHR							0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR							0x0100
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT						0x0200
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT						0x0400
+#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR					0x1000
+#define EGL_OPENGL_ES_BIT									0x0001
+#define EGL_OPENVG_BIT										0x0002
+#define EGL_OPENGL_ES2_BIT									0x0004
+#define EGL_OPENGL_BIT										0x0008
+#define EGL_OPENGL_ES3_BIT									0x00000040
+#define EGL_OPENGL_ES3_BIT_KHR								0x00000040
+#define EGL_READ_SURFACE_BIT_KHR							0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR							0x0002
+#define EGL_SYNC_FLUSH_COMMANDS_BIT							0x0001
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR						0x0001
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR					0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR		0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR			0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT					0x00000001
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR				0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT		0x00000002
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR	0x00000002
+#define EGL_FALSE											0
+#define EGL_TRUE											1
+#define EGL_DONT_CARE										((EGLint)-1)
+#define EGL_UNKNOWN											((EGLint)-1)
+#define EGL_NO_CONTEXT										((EGLContext)0)
+#define EGL_NO_DISPLAY										((EGLDisplay)0)
+#define EGL_NO_IMAGE										((EGLImage)0)
+#define EGL_NO_IMAGE_KHR									((EGLImageKHR)0)
+#define EGL_DEFAULT_DISPLAY									((EGLNativeDisplayType)0)
+#define EGL_NO_SURFACE										((EGLSurface)0)
+#define EGL_NO_SYNC											((EGLSync)0)
+#define EGL_NO_SYNC_KHR										((EGLSyncKHR)0)
+#define EGL_DISPLAY_SCALING									10000
+#define EGL_FOREVER											0xFFFFFFFFFFFFFFFFull
+#define EGL_FOREVER_KHR										0xFFFFFFFFFFFFFFFFull
+#define EGL_SUCCESS											0x3000
+#define EGL_NOT_INITIALIZED									0x3001
+#define EGL_BAD_ACCESS										0x3002
+#define EGL_BAD_ALLOC										0x3003
+#define EGL_BAD_ATTRIBUTE									0x3004
+#define EGL_BAD_CONFIG										0x3005
+#define EGL_BAD_CONTEXT										0x3006
+#define EGL_BAD_CURRENT_SURFACE								0x3007
+#define EGL_BAD_DISPLAY										0x3008
+#define EGL_BAD_MATCH										0x3009
+#define EGL_BAD_NATIVE_PIXMAP								0x300A
+#define EGL_BAD_NATIVE_WINDOW								0x300B
+#define EGL_BAD_PARAMETER									0x300C
+#define EGL_BAD_SURFACE										0x300D
+#define EGL_CONTEXT_LOST									0x300E
+#define EGL_BUFFER_SIZE										0x3020
+#define EGL_ALPHA_SIZE										0x3021
+#define EGL_BLUE_SIZE										0x3022
+#define EGL_GREEN_SIZE										0x3023
+#define EGL_RED_SIZE										0x3024
+#define EGL_DEPTH_SIZE										0x3025
+#define EGL_STENCIL_SIZE									0x3026
+#define EGL_CONFIG_CAVEAT									0x3027
+#define EGL_CONFIG_ID										0x3028
+#define EGL_LEVEL											0x3029
+#define EGL_MAX_PBUFFER_HEIGHT								0x302A
+#define EGL_MAX_PBUFFER_PIXELS								0x302B
+#define EGL_MAX_PBUFFER_WIDTH								0x302C
+#define EGL_NATIVE_RENDERABLE								0x302D
+#define EGL_NATIVE_VISUAL_ID								0x302E
+#define EGL_NATIVE_VISUAL_TYPE								0x302F
+#define EGL_SAMPLES											0x3031
+#define EGL_SAMPLE_BUFFERS									0x3032
+#define EGL_SURFACE_TYPE									0x3033
+#define EGL_TRANSPARENT_TYPE								0x3034
+#define EGL_TRANSPARENT_BLUE_VALUE							0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE							0x3036
+#define EGL_TRANSPARENT_RED_VALUE							0x3037
+#define EGL_NONE											0x3038
+#define EGL_BIND_TO_TEXTURE_RGB								0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA							0x303A
+#define EGL_MIN_SWAP_INTERVAL								0x303B
+#define EGL_MAX_SWAP_INTERVAL								0x303C
+#define EGL_LUMINANCE_SIZE									0x303D
+#define EGL_ALPHA_MASK_SIZE									0x303E
+#define EGL_COLOR_BUFFER_TYPE								0x303F
+#define EGL_RENDERABLE_TYPE									0x3040
+#define EGL_MATCH_NATIVE_PIXMAP								0x3041
+#define EGL_CONFORMANT										0x3042
+#define EGL_MATCH_FORMAT_KHR								0x3043
+#define EGL_SLOW_CONFIG										0x3050
+#define EGL_NON_CONFORMANT_CONFIG							0x3051
+#define EGL_TRANSPARENT_RGB									0x3052
+#define EGL_VENDOR											0x3053
+#define EGL_VERSION											0x3054
+#define EGL_EXTENSIONS										0x3055
+#define EGL_HEIGHT											0x3056
+#define EGL_WIDTH											0x3057
+#define EGL_LARGEST_PBUFFER									0x3058
+#define EGL_DRAW											0x3059
+#define EGL_READ											0x305A
+#define EGL_CORE_NATIVE_ENGINE								0x305B
+#define EGL_NO_TEXTURE										0x305C
+#define EGL_TEXTURE_RGB										0x305D
+#define EGL_TEXTURE_RGBA									0x305E
+#define EGL_TEXTURE_2D										0x305F
+#define EGL_TEXTURE_FORMAT									0x3080
+#define EGL_TEXTURE_TARGET									0x3081
+#define EGL_MIPMAP_TEXTURE									0x3082
+#define EGL_MIPMAP_LEVEL									0x3083
+#define EGL_BACK_BUFFER										0x3084
+#define EGL_SINGLE_BUFFER									0x3085
+#define EGL_RENDER_BUFFER									0x3086
+#define EGL_COLORSPACE										0x3087
+#define EGL_COLORSPACE										0x3087
+#define EGL_ALPHA_FORMAT									0x3088
+#define EGL_ALPHA_FORMAT									0x3088
+#define EGL_COLORSPACE_sRGB									0x3089
+#define EGL_GL_COLORSPACE_SRGB								0x3089
+#define EGL_GL_COLORSPACE_SRGB_KHR							0x3089
+#define EGL_VG_COLORSPACE_sRGB								0x3089
+#define EGL_COLORSPACE_LINEAR								0x308A
+#define EGL_GL_COLORSPACE_LINEAR							0x308A
+#define EGL_GL_COLORSPACE_LINEAR_KHR						0x308A
+#define EGL_VG_COLORSPACE_LINEAR							0x308A
+#define EGL_ALPHA_FORMAT_NONPRE								0x308B
+#define EGL_ALPHA_FORMAT_NONPRE								0x308B
+#define EGL_ALPHA_FORMAT_PRE								0x308C
+#define EGL_ALPHA_FORMAT_PRE								0x308C
+#define EGL_CLIENT_APIS										0x308D
+#define EGL_RGB_BUFFER										0x308E
+#define EGL_LUMINANCE_BUFFER								0x308F
+#define EGL_HORIZONTAL_RESOLUTION							0x3090
+#define EGL_VERTICAL_RESOLUTION								0x3091
+#define EGL_PIXEL_ASPECT_RATIO								0x3092
+#define EGL_SWAP_BEHAVIOR									0x3093
+#define EGL_BUFFER_PRESERVED								0x3094
+#define EGL_BUFFER_DESTROYED								0x3095
+#define EGL_OPENVG_IMAGE									0x3096
+#define EGL_CONTEXT_CLIENT_TYPE								0x3097
+#define EGL_CONTEXT_CLIENT_VERSION							0x3098
+#define EGL_CONTEXT_MAJOR_VERSION							0x3098
+#define EGL_CONTEXT_MAJOR_VERSION_KHR						0x3098
+#define EGL_MULTISAMPLE_RESOLVE								0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT						0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX							0x309B
+#define EGL_CL_EVENT_HANDLE									0x309C
+#define EGL_GL_COLORSPACE									0x309D
+#define EGL_GL_COLORSPACE_KHR								0x309D
+#define EGL_OPENGL_ES_API									0x30A0
+#define EGL_OPENVG_API										0x30A1
+#define EGL_OPENGL_API										0x30A2
+#define EGL_GL_TEXTURE_2D									0x30B1
+#define EGL_GL_TEXTURE_2D_KHR								0x30B1
+#define EGL_GL_TEXTURE_3D									0x30B2
+#define EGL_GL_TEXTURE_3D_KHR								0x30B2
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X					0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR				0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X					0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR				0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y					0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR				0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y					0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR				0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z					0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR				0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z					0x30B8
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR				0x30B8
+#define EGL_GL_RENDERBUFFER									0x30B9
+#define EGL_GL_RENDERBUFFER_KHR								0x30B9
+#define EGL_GL_TEXTURE_LEVEL								0x30BC
+#define EGL_GL_TEXTURE_LEVEL_KHR							0x30BC
+#define EGL_GL_TEXTURE_ZOFFSET								0x30BD
+#define EGL_GL_TEXTURE_ZOFFSET_KHR							0x30BD
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT				0x30BF
+#define EGL_FORMAT_RGB_565_EXACT_KHR						0x30C0
+#define EGL_FORMAT_RGB_565_KHR								0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR						0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR							0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR							0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR								0x30C5
+#define EGL_BITMAP_POINTER_KHR								0x30C6
+#define EGL_BITMAP_PITCH_KHR								0x30C7
+#define EGL_BITMAP_ORIGIN_KHR								0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR						0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR					0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR					0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR					0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR				0x30CD
+#define EGL_LOWER_LEFT_KHR									0x30CE
+#define EGL_UPPER_LEFT_KHR									0x30CF
+#define EGL_IMAGE_PRESERVED									0x30D2
+#define EGL_IMAGE_PRESERVED_KHR								0x30D2
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE					0x30F0
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR				0x30F0
+#define EGL_SYNC_STATUS										0x30F1
+#define EGL_SYNC_STATUS_KHR									0x30F1
+#define EGL_SIGNALED										0x30F2
+#define EGL_SIGNALED_KHR									0x30F2
+#define EGL_UNSIGNALED										0x30F3
+#define EGL_UNSIGNALED_KHR									0x30F3
+#define EGL_TIMEOUT_EXPIRED									0x30F5
+#define EGL_TIMEOUT_EXPIRED_KHR								0x30F5
+#define EGL_CONDITION_SATISFIED								0x30F6
+#define EGL_CONDITION_SATISFIED_KHR							0x30F6
+#define EGL_SYNC_TYPE										0x30F7
+#define EGL_SYNC_TYPE_KHR									0x30F7
+#define EGL_SYNC_CONDITION									0x30F8
+#define EGL_SYNC_CONDITION_KHR								0x30F8
+#define EGL_SYNC_FENCE										0x30F9
+#define EGL_SYNC_FENCE_KHR									0x30F9
+#define EGL_SYNC_REUSABLE_KHR								0x30FA
+#define EGL_CONTEXT_MINOR_VERSION							0x30FB
+#define EGL_CONTEXT_MINOR_VERSION_KHR						0x30FB
+#define EGL_CONTEXT_FLAGS_KHR								0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK						0x30FD
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR					0x30FD
+#define EGL_SYNC_CL_EVENT									0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE							0x30FF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT	0x3138
+#define EGL_BUFFER_AGE_KHR									0x313D
+#define EGL_BUFFER_AGE_EXT									0x313D
+#define EGL_NATIVE_BUFFER_ANDROID							0x3140
+#define EGL_CONTEXT_OPENGL_DEBUG							0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE				0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS					0x31B2
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR	0x31BD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR	0x31BD
+#define EGL_NO_RESET_NOTIFICATION							0x31BE
+#define EGL_NO_RESET_NOTIFICATION_KHR						0x31BE
+#define EGL_NO_RESET_NOTIFICATION_EXT						0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET							0x31BF
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR						0x31BF
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT						0x31BF
+#define EGL_PLATFORM_X11_EXT								0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT							0x31D6
+#define EGL_PLATFORM_WAYLAND_KHR							0x31D8
+#define EGL_YUV_BUFFER_EXT									0x3300
+#define EGL_YUV_ORDER_EXT									0x3301
+#define EGL_YUV_ORDER_YUV_EXT								0x3302
+#define EGL_YUV_ORDER_YVU_EXT								0x3303
+#define EGL_YUV_ORDER_YUYV_EXT								0x3304
+#define EGL_YUV_ORDER_UYVY_EXT								0x3305
+#define EGL_YUV_ORDER_YVYU_EXT								0x3306
+#define EGL_YUV_ORDER_VYUY_EXT								0x3307
+#define EGL_YUV_ORDER_AYUV_EXT								0x3308
+#define EGL_YUV_CSC_STANDARD_EXT							0x330A
+#define EGL_YUV_CSC_STANDARD_601_EXT						0x330B
+#define EGL_YUV_CSC_STANDARD_709_EXT						0x330C
+#define EGL_YUV_CSC_STANDARD_2020_EXT						0x330D
+#define EGL_YUV_NUMBER_OF_PLANES_EXT						0x3311
+#define EGL_YUV_SUBSAMPLE_EXT								0x3312
+#define EGL_YUV_SUBSAMPLE_4_2_0_EXT							0x3313
+#define EGL_YUV_SUBSAMPLE_4_2_2_EXT							0x3314
+#define EGL_YUV_SUBSAMPLE_4_4_4_EXT							0x3315
+#define EGL_YUV_DEPTH_RANGE_EXT								0x3317
+#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT						0x3318
+#define EGL_YUV_DEPTH_RANGE_FULL_EXT						0x3319
+#define EGL_YUV_PLANE_BPP_EXT								0x331A
+#define EGL_YUV_PLANE_BPP_0_EXT								0x331B
+#define EGL_YUV_PLANE_BPP_8_EXT								0x331C
+#define EGL_YUV_PLANE_BPP_10_EXT							0x331D
+#define EGL_COLOR_COMPONENT_TYPE_EXT						0x3339
+#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT					0x333A
+#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT					0x333B
+#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT					0x333F
+#define EGL_GL_COLORSPACE_BT2020_PQ_EXT						0x3340
+#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT					0x3350
+#define EGL_GL_COLORSPACE_SCRGB_EXT							0x3351
+#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT				0x3362
+#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT					0x3363
diff --git a/framework/egl/wrapper/eglwFuncPtrLibraryDecl.inl b/framework/egl/wrapper/eglwFuncPtrLibraryDecl.inl
index e7d1327..0b15ad0 100644
--- a/framework/egl/wrapper/eglwFuncPtrLibraryDecl.inl
+++ b/framework/egl/wrapper/eglwFuncPtrLibraryDecl.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 EGLBoolean									bindAPI							(EGLenum api) const;
 EGLBoolean									bindTexImage					(EGLDisplay dpy, EGLSurface surface, EGLint buffer) const;
diff --git a/framework/egl/wrapper/eglwFuncPtrLibraryImpl.inl b/framework/egl/wrapper/eglwFuncPtrLibraryImpl.inl
index 1678c71..913d464 100644
--- a/framework/egl/wrapper/eglwFuncPtrLibraryImpl.inl
+++ b/framework/egl/wrapper/eglwFuncPtrLibraryImpl.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 
 EGLBoolean FuncPtrLibrary::bindAPI (EGLenum api) const
diff --git a/framework/egl/wrapper/eglwFunctionTypes.inl b/framework/egl/wrapper/eglwFunctionTypes.inl
index d57105e..7beb1e9 100644
--- a/framework/egl/wrapper/eglwFunctionTypes.inl
+++ b/framework/egl/wrapper/eglwFunctionTypes.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 typedef EGLW_APICALL EGLBoolean									(EGLW_APIENTRY* eglBindAPIFunc)							(EGLenum api);
 typedef EGLW_APICALL EGLBoolean									(EGLW_APIENTRY* eglBindTexImageFunc)					(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
diff --git a/framework/egl/wrapper/eglwFunctions.inl b/framework/egl/wrapper/eglwFunctions.inl
index af0d1b2..aa8530a 100644
--- a/framework/egl/wrapper/eglwFunctions.inl
+++ b/framework/egl/wrapper/eglwFunctions.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 eglBindAPIFunc							bindAPI;
 eglBindTexImageFunc						bindTexImage;
diff --git a/framework/egl/wrapper/eglwImpl.inl b/framework/egl/wrapper/eglwImpl.inl
new file mode 100644
index 0000000..7f07b77
--- /dev/null
+++ b/framework/egl/wrapper/eglwImpl.inl
@@ -0,0 +1,357 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ *
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
+ */
+
+EGLBoolean eglwBindAPI (EGLenum api)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->bindAPI(api);
+}
+
+EGLBoolean eglwBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->bindTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglwChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->chooseConfig(dpy, attrib_list, configs, config_size, num_config);
+}
+
+EGLint eglwClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLint)0;
+	return egl->clientWaitSync(dpy, sync, flags, timeout);
+}
+
+EGLBoolean eglwCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->copyBuffers(dpy, surface, (void*)target);
+}
+
+EGLContext eglwCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLContext)0;
+	return egl->createContext(dpy, config, share_context, attrib_list);
+}
+
+EGLImage eglwCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLImage)0;
+	return egl->createImage(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLSurface eglwCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLSurface eglwCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPbufferSurface(dpy, config, attrib_list);
+}
+
+EGLSurface eglwCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPixmapSurface(dpy, config, (void*)pixmap, attrib_list);
+}
+
+EGLSurface eglwCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPlatformPixmapSurface(dpy, config, native_pixmap, attrib_list);
+}
+
+EGLSurface eglwCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPlatformWindowSurface(dpy, config, native_window, attrib_list);
+}
+
+EGLSync eglwCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSync)0;
+	return egl->createSync(dpy, type, attrib_list);
+}
+
+EGLSurface eglwCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createWindowSurface(dpy, config, (void*)win, attrib_list);
+}
+
+EGLBoolean eglwDestroyContext (EGLDisplay dpy, EGLContext ctx)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->destroyContext(dpy, ctx);
+}
+
+EGLBoolean eglwDestroyImage (EGLDisplay dpy, EGLImage image)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->destroyImage(dpy, image);
+}
+
+EGLBoolean eglwDestroySurface (EGLDisplay dpy, EGLSurface surface)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->destroySurface(dpy, surface);
+}
+
+EGLBoolean eglwDestroySync (EGLDisplay dpy, EGLSync sync)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->destroySync(dpy, sync);
+}
+
+EGLBoolean eglwGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->getConfigAttrib(dpy, config, attribute, value);
+}
+
+EGLBoolean eglwGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->getConfigs(dpy, configs, config_size, num_config);
+}
+
+EGLContext eglwGetCurrentContext (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLContext)0;
+	return egl->getCurrentContext();
+}
+
+EGLDisplay eglwGetCurrentDisplay (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLDisplay)0;
+	return egl->getCurrentDisplay();
+}
+
+EGLSurface eglwGetCurrentSurface (EGLint readdraw)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->getCurrentSurface(readdraw);
+}
+
+EGLDisplay eglwGetDisplay (EGLNativeDisplayType display_id)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLDisplay)0;
+	return egl->getDisplay((void*)display_id);
+}
+
+EGLint eglwGetError (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLint)0;
+	return egl->getError();
+}
+
+EGLDisplay eglwGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLDisplay)0;
+	return egl->getPlatformDisplay(platform, native_display, attrib_list);
+}
+
+__eglMustCastToProperFunctionPointerType eglwGetProcAddress (const char *procname)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (__eglMustCastToProperFunctionPointerType)0;
+	return egl->getProcAddress(procname);
+}
+
+EGLBoolean eglwGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->getSyncAttrib(dpy, sync, attribute, value);
+}
+
+EGLBoolean eglwInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->initialize(dpy, major, minor);
+}
+
+EGLBoolean eglwMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->makeCurrent(dpy, draw, read, ctx);
+}
+
+EGLenum eglwQueryAPI (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLenum)0;
+	return egl->queryAPI();
+}
+
+EGLBoolean eglwQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->queryContext(dpy, ctx, attribute, value);
+}
+
+const char * eglwQueryString (EGLDisplay dpy, EGLint name)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (const char *)0;
+	return egl->queryString(dpy, name);
+}
+
+EGLBoolean eglwQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->querySurface(dpy, surface, attribute, value);
+}
+
+EGLBoolean eglwReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->releaseTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglwReleaseThread (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->releaseThread();
+}
+
+EGLBoolean eglwSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->surfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLBoolean eglwSwapBuffers (EGLDisplay dpy, EGLSurface surface)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->swapBuffers(dpy, surface);
+}
+
+EGLBoolean eglwSwapInterval (EGLDisplay dpy, EGLint interval)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->swapInterval(dpy, interval);
+}
+
+EGLBoolean eglwTerminate (EGLDisplay dpy)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->terminate(dpy);
+}
+
+EGLBoolean eglwWaitClient (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->waitClient();
+}
+
+EGLBoolean eglwWaitGL (void)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->waitGL();
+}
+
+EGLBoolean eglwWaitNative (EGLint engine)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->waitNative(engine);
+}
+
+EGLBoolean eglwWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->waitSync(dpy, sync, flags);
+}
diff --git a/framework/egl/wrapper/eglwImplExt.inl b/framework/egl/wrapper/eglwImplExt.inl
new file mode 100644
index 0000000..95015c6
--- /dev/null
+++ b/framework/egl/wrapper/eglwImplExt.inl
@@ -0,0 +1,125 @@
+/* WARNING: This is auto-generated file. Do not modify, since changes will
+ * be lost! Modify the generating script instead.
+ *
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
+ */
+
+EGLint eglwClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+									const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLint)0;
+		return egl->clientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLImageKHR eglwCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLImageKHR)0;
+	return egl->createImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLSurface eglwCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPlatformPixmapSurfaceEXT(dpy, config, native_pixmap, attrib_list);
+}
+
+EGLSurface eglwCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
+{
+	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSurface)0;
+	return egl->createPlatformWindowSurfaceEXT(dpy, config, native_window, attrib_list);
+}
+
+EGLSyncKHR eglwCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+												const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLSyncKHR)0;
+	return egl->createSyncKHR(dpy, type, attrib_list);
+}
+
+EGLBoolean eglwDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image)
+{
+																	const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->destroyImageKHR(dpy, image);
+}
+
+EGLBoolean eglwDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync)
+{
+																		const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->destroySyncKHR(dpy, sync);
+}
+
+EGLDisplay eglwGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+							const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLDisplay)0;
+	return egl->getPlatformDisplayEXT(platform, native_display, attrib_list);
+}
+
+EGLBoolean eglwGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+									const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->getSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+EGLBoolean eglwLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list)
+{
+										const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->lockSurfaceKHR(dpy, surface, attrib_list);
+}
+
+EGLBoolean eglwSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects)
+{
+								const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->setDamageRegionKHR(dpy, surface, rects, n_rects);
+}
+
+EGLBoolean eglwSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+														const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->signalSyncKHR(dpy, sync, mode);
+}
+
+EGLBoolean eglwSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects)
+{
+							const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->swapBuffersWithDamageKHR(dpy, surface, rects, n_rects);
+}
+
+EGLBoolean eglwUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface)
+{
+																const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLBoolean)0;
+	return egl->unlockSurfaceKHR(dpy, surface);
+}
+
+EGLint eglwWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
+{
+																const eglw::Library* egl = eglw::getCurrentThreadLibrary();
+	if (!egl)
+		return (EGLint)0;
+		return egl->waitSyncKHR(dpy, sync, flags);
+}
diff --git a/framework/egl/wrapper/eglwInitCore.inl b/framework/egl/wrapper/eglwInitCore.inl
index 15f941d..5e360f6 100644
--- a/framework/egl/wrapper/eglwInitCore.inl
+++ b/framework/egl/wrapper/eglwInitCore.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 dst->bindAPI						= (eglBindAPIFunc)							loader->get("eglBindAPI");
 dst->bindTexImage					= (eglBindTexImageFunc)						loader->get("eglBindTexImage");
diff --git a/framework/egl/wrapper/eglwInitExtensions.inl b/framework/egl/wrapper/eglwInitExtensions.inl
index 90d00a1..ed56617 100644
--- a/framework/egl/wrapper/eglwInitExtensions.inl
+++ b/framework/egl/wrapper/eglwInitExtensions.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 dst->clientWaitSyncKHR				= (eglClientWaitSyncKHRFunc)				loader->get("eglClientWaitSyncKHR");
 dst->createImageKHR					= (eglCreateImageKHRFunc)					loader->get("eglCreateImageKHR");
diff --git a/framework/egl/wrapper/eglwLibrary.inl b/framework/egl/wrapper/eglwLibrary.inl
index a3d617d..e942a47 100644
--- a/framework/egl/wrapper/eglwLibrary.inl
+++ b/framework/egl/wrapper/eglwLibrary.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 virtual EGLBoolean									bindAPI							(EGLenum api) const																								= 0;
 virtual EGLBoolean									bindTexImage					(EGLDisplay dpy, EGLSurface surface, EGLint buffer) const														= 0;
diff --git a/framework/egl/wrapper/eglwStaticLibrary14.inl b/framework/egl/wrapper/eglwStaticLibrary14.inl
index 22a2c5c..6d20919 100644
--- a/framework/egl/wrapper/eglwStaticLibrary14.inl
+++ b/framework/egl/wrapper/eglwStaticLibrary14.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 	{ "eglBindAPI",							(deFunctionPtr)eglBindAPI },
 	{ "eglBindTexImage",					(deFunctionPtr)eglBindTexImage },
diff --git a/framework/egl/wrapper/eglwStaticLibrary15.inl b/framework/egl/wrapper/eglwStaticLibrary15.inl
index a44c589..5ba62f0 100644
--- a/framework/egl/wrapper/eglwStaticLibrary15.inl
+++ b/framework/egl/wrapper/eglwStaticLibrary15.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 	{ "eglBindAPI",							(deFunctionPtr)eglBindAPI },
 	{ "eglBindTexImage",					(deFunctionPtr)eglBindTexImage },
diff --git a/framework/opengl/gluCallLogUtil.inl b/framework/opengl/gluCallLogUtil.inl
index 7df1a37..9ca34af 100644
--- a/framework/opengl/gluCallLogUtil.inl
+++ b/framework/opengl/gluCallLogUtil.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 int getTextureParamNumArgs (int pname)
diff --git a/framework/opengl/gluCallLogWrapper.inl b/framework/opengl/gluCallLogWrapper.inl
index 13ce84c..0743712 100644
--- a/framework/opengl/gluCallLogWrapper.inl
+++ b/framework/opengl/gluCallLogWrapper.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 void CallLogWrapper::glActiveShaderProgram (glw::GLuint pipeline, glw::GLuint program)
@@ -423,11 +423,11 @@
 	m_gl.clearNamedBufferSubData(buffer, internalformat, offset, size, format, type, data);
 }
 
-void CallLogWrapper::glClearNamedFramebufferfi (glw::GLuint framebuffer, glw::GLenum buffer, const glw::GLfloat depth, glw::GLint stencil)
+void CallLogWrapper::glClearNamedFramebufferfi (glw::GLuint framebuffer, glw::GLenum buffer, glw::GLint drawbuffer, glw::GLfloat depth, glw::GLint stencil)
 {
 	if (m_enableLog)
-		m_log << TestLog::Message << "glClearNamedFramebufferfi(" << framebuffer << ", " << toHex(buffer) << ", " << depth << ", " << stencil << ");" << TestLog::EndMessage;
-	m_gl.clearNamedFramebufferfi(framebuffer, buffer, depth, stencil);
+		m_log << TestLog::Message << "glClearNamedFramebufferfi(" << framebuffer << ", " << toHex(buffer) << ", " << drawbuffer << ", " << depth << ", " << stencil << ");" << TestLog::EndMessage;
+	m_gl.clearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil);
 }
 
 void CallLogWrapper::glClearNamedFramebufferfv (glw::GLuint framebuffer, glw::GLenum buffer, glw::GLint drawbuffer, const glw::GLfloat *value)
diff --git a/framework/opengl/gluCallLogWrapperApi.inl b/framework/opengl/gluCallLogWrapperApi.inl
index 5785d59..71bddd9 100644
--- a/framework/opengl/gluCallLogWrapperApi.inl
+++ b/framework/opengl/gluCallLogWrapperApi.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 void					glActiveShaderProgram							(glw::GLuint pipeline, glw::GLuint program);
 void					glActiveTexture									(glw::GLenum texture);
@@ -62,7 +62,7 @@
 void					glClearDepthf									(glw::GLfloat d);
 void					glClearNamedBufferData							(glw::GLuint buffer, glw::GLenum internalformat, glw::GLenum format, glw::GLenum type, const void *data);
 void					glClearNamedBufferSubData						(glw::GLuint buffer, glw::GLenum internalformat, glw::GLintptr offset, glw::GLsizeiptr size, glw::GLenum format, glw::GLenum type, const void *data);
-void					glClearNamedFramebufferfi						(glw::GLuint framebuffer, glw::GLenum buffer, const glw::GLfloat depth, glw::GLint stencil);
+void					glClearNamedFramebufferfi						(glw::GLuint framebuffer, glw::GLenum buffer, glw::GLint drawbuffer, glw::GLfloat depth, glw::GLint stencil);
 void					glClearNamedFramebufferfv						(glw::GLuint framebuffer, glw::GLenum buffer, glw::GLint drawbuffer, const glw::GLfloat *value);
 void					glClearNamedFramebufferiv						(glw::GLuint framebuffer, glw::GLenum buffer, glw::GLint drawbuffer, const glw::GLint *value);
 void					glClearNamedFramebufferuiv						(glw::GLuint framebuffer, glw::GLenum buffer, glw::GLint drawbuffer, const glw::GLuint *value);
diff --git a/framework/opengl/gluES3PlusWrapperFuncs.inl b/framework/opengl/gluES3PlusWrapperFuncs.inl
index bf4b095..c0d7607 100644
--- a/framework/opengl/gluES3PlusWrapperFuncs.inl
+++ b/framework/opengl/gluES3PlusWrapperFuncs.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 dst->activeShaderProgram					= src.activeShaderProgram;
 dst->activeTexture							= src.activeTexture;
diff --git a/framework/opengl/gluQueryUtil.inl b/framework/opengl/gluQueryUtil.inl
index 93a03c2..857af60 100644
--- a/framework/opengl/gluQueryUtil.inl
+++ b/framework/opengl/gluQueryUtil.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 int getBasicQueryNumArgsOut (int pname)
diff --git a/framework/opengl/gluStateReset.cpp b/framework/opengl/gluStateReset.cpp
index f91b921..7a0eba2 100644
--- a/framework/opengl/gluStateReset.cpp
+++ b/framework/opengl/gluStateReset.cpp
@@ -369,6 +369,11 @@
 
 		gl.enable		(GL_DITHER);
 
+		if (ctxInfo.isExtensionSupported("GL_EXT_sRGB_write_control"))
+		{
+			gl.enable		(GL_FRAMEBUFFER_SRGB);
+		}
+
 		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
 	}
 
diff --git a/framework/opengl/gluStrUtil.inl b/framework/opengl/gluStrUtil.inl
index f1504a6..b32e4ec 100644
--- a/framework/opengl/gluStrUtil.inl
+++ b/framework/opengl/gluStrUtil.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 const char* getErrorName (int value)
diff --git a/framework/opengl/gluStrUtilPrototypes.inl b/framework/opengl/gluStrUtilPrototypes.inl
index c0505ef..d5374c7 100644
--- a/framework/opengl/gluStrUtilPrototypes.inl
+++ b/framework/opengl/gluStrUtilPrototypes.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 const char*							getErrorName							(int value);
 const char*							getTypeName								(int value);
diff --git a/framework/opengl/wrapper/glwApi.inl b/framework/opengl/wrapper/glwApi.inl
index beb0940..befa4b9 100644
--- a/framework/opengl/wrapper/glwApi.inl
+++ b/framework/opengl/wrapper/glwApi.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 #define			glActiveShaderProgram							glwActiveShaderProgram
 #define			glActiveTexture									glwActiveTexture
@@ -722,7 +722,7 @@
 void			glwClearDepthf									(GLfloat d);
 void			glwClearNamedBufferData							(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
 void			glwClearNamedBufferSubData						(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
-void			glwClearNamedFramebufferfi						(GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil);
+void			glwClearNamedFramebufferfi						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
 void			glwClearNamedFramebufferfv						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);
 void			glwClearNamedFramebufferiv						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);
 void			glwClearNamedFramebufferuiv						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);
diff --git a/framework/opengl/wrapper/glwEnums.inl b/framework/opengl/wrapper/glwEnums.inl
index e0c4d6c..d6e51ab 100644
--- a/framework/opengl/wrapper/glwEnums.inl
+++ b/framework/opengl/wrapper/glwEnums.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 #define GL_DEPTH_BUFFER_BIT												0x00000100
 #define GL_STENCIL_BUFFER_BIT											0x00000400
diff --git a/framework/opengl/wrapper/glwFunctionTypes.inl b/framework/opengl/wrapper/glwFunctionTypes.inl
index 0b1f747..63adcec 100644
--- a/framework/opengl/wrapper/glwFunctionTypes.inl
+++ b/framework/opengl/wrapper/glwFunctionTypes.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 typedef GLW_APICALL void			(GLW_APIENTRY* glActiveShaderProgramFunc)							(GLuint pipeline, GLuint program);
 typedef GLW_APICALL void			(GLW_APIENTRY* glActiveTextureFunc)									(GLenum texture);
@@ -62,7 +62,7 @@
 typedef GLW_APICALL void			(GLW_APIENTRY* glClearDepthfFunc)									(GLfloat d);
 typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedBufferDataFunc)							(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
 typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedBufferSubDataFunc)						(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
-typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedFramebufferfiFunc)						(GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil);
+typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedFramebufferfiFunc)						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
 typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedFramebufferfvFunc)						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);
 typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedFramebufferivFunc)						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);
 typedef GLW_APICALL void			(GLW_APIENTRY* glClearNamedFramebufferuivFunc)						(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);
diff --git a/framework/opengl/wrapper/glwFunctions.inl b/framework/opengl/wrapper/glwFunctions.inl
index 80bbcb5..4d304eb 100644
--- a/framework/opengl/wrapper/glwFunctions.inl
+++ b/framework/opengl/wrapper/glwFunctions.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 glActiveShaderProgramFunc							activeShaderProgram;
 glActiveTextureFunc									activeTexture;
diff --git a/framework/opengl/wrapper/glwImpl.inl b/framework/opengl/wrapper/glwImpl.inl
index e521405..ed39d82 100644
--- a/framework/opengl/wrapper/glwImpl.inl
+++ b/framework/opengl/wrapper/glwImpl.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 void glwActiveShaderProgram (GLuint pipeline, GLuint program)
@@ -476,12 +476,12 @@
 	gl->clearNamedBufferSubData(buffer, internalformat, offset, size, format, type, data);
 }
 
-void glwClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil)
+void glwClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
 {
 	const glw::Functions* gl = glw::getCurrentThreadFunctions();
 	if (!gl)
 		return;
-	gl->clearNamedFramebufferfi(framebuffer, buffer, depth, stencil);
+	gl->clearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil);
 }
 
 void glwClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value)
diff --git a/framework/opengl/wrapper/glwInitES20.inl b/framework/opengl/wrapper/glwInitES20.inl
index 5dd6080..1a7fa9e 100644
--- a/framework/opengl/wrapper/glwInitES20.inl
+++ b/framework/opengl/wrapper/glwInitES20.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitES20Direct.inl b/framework/opengl/wrapper/glwInitES20Direct.inl
index 2af9a05..eb54931 100644
--- a/framework/opengl/wrapper/glwInitES20Direct.inl
+++ b/framework/opengl/wrapper/glwInitES20Direct.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= &glActiveTexture;
 gl->attachShader						= &glAttachShader;
diff --git a/framework/opengl/wrapper/glwInitES30.inl b/framework/opengl/wrapper/glwInitES30.inl
index 8d822f3..13beaa7 100644
--- a/framework/opengl/wrapper/glwInitES30.inl
+++ b/framework/opengl/wrapper/glwInitES30.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitES30Direct.inl b/framework/opengl/wrapper/glwInitES30Direct.inl
index a6c125e..71588dc 100644
--- a/framework/opengl/wrapper/glwInitES30Direct.inl
+++ b/framework/opengl/wrapper/glwInitES30Direct.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= &glActiveTexture;
 gl->attachShader						= &glAttachShader;
diff --git a/framework/opengl/wrapper/glwInitES31.inl b/framework/opengl/wrapper/glwInitES31.inl
index 9d8e175..e6a6fca 100644
--- a/framework/opengl/wrapper/glwInitES31.inl
+++ b/framework/opengl/wrapper/glwInitES31.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram					= (glActiveShaderProgramFunc)					loader->get("glActiveShaderProgram");
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
diff --git a/framework/opengl/wrapper/glwInitES31Direct.inl b/framework/opengl/wrapper/glwInitES31Direct.inl
index a1f1f5b..0b6e02a 100644
--- a/framework/opengl/wrapper/glwInitES31Direct.inl
+++ b/framework/opengl/wrapper/glwInitES31Direct.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram					= &glActiveShaderProgram;
 gl->activeTexture						= &glActiveTexture;
diff --git a/framework/opengl/wrapper/glwInitES32.inl b/framework/opengl/wrapper/glwInitES32.inl
index 376462d..674e242 100644
--- a/framework/opengl/wrapper/glwInitES32.inl
+++ b/framework/opengl/wrapper/glwInitES32.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram					= (glActiveShaderProgramFunc)					loader->get("glActiveShaderProgram");
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
diff --git a/framework/opengl/wrapper/glwInitES32Direct.inl b/framework/opengl/wrapper/glwInitES32Direct.inl
index f30b57e..cd12bdd 100644
--- a/framework/opengl/wrapper/glwInitES32Direct.inl
+++ b/framework/opengl/wrapper/glwInitES32Direct.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram					= &glActiveShaderProgram;
 gl->activeTexture						= &glActiveTexture;
diff --git a/framework/opengl/wrapper/glwInitExtES.inl b/framework/opengl/wrapper/glwInitExtES.inl
index 5e8005b..fc74f3b 100644
--- a/framework/opengl/wrapper/glwInitExtES.inl
+++ b/framework/opengl/wrapper/glwInitExtES.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 if (de::contains(extSet, "GL_KHR_blend_equation_advanced"))
@@ -121,3 +121,19 @@
 	gl->getnUniformuiv			= (glGetnUniformuivFunc)			loader->get("glGetnUniformuivKHR");
 	gl->readnPixels				= (glReadnPixelsFunc)				loader->get("glReadnPixelsKHR");
 }
+
+if (de::contains(extSet, "GL_EXT_draw_elements_base_vertex"))
+{
+	gl->drawElementsBaseVertex			= (glDrawElementsBaseVertexFunc)			loader->get("glDrawElementsBaseVertexEXT");
+	gl->drawElementsInstancedBaseVertex	= (glDrawElementsInstancedBaseVertexFunc)	loader->get("glDrawElementsInstancedBaseVertexEXT");
+	gl->drawRangeElementsBaseVertex		= (glDrawRangeElementsBaseVertexFunc)		loader->get("glDrawRangeElementsBaseVertexEXT");
+	gl->multiDrawElementsBaseVertex		= (glMultiDrawElementsBaseVertexFunc)		loader->get("glMultiDrawElementsBaseVertexEXT");
+}
+
+if (de::contains(extSet, "GL_OES_draw_elements_base_vertex"))
+{
+	gl->drawElementsBaseVertex			= (glDrawElementsBaseVertexFunc)			loader->get("glDrawElementsBaseVertexOES");
+	gl->drawElementsInstancedBaseVertex	= (glDrawElementsInstancedBaseVertexFunc)	loader->get("glDrawElementsInstancedBaseVertexOES");
+	gl->drawRangeElementsBaseVertex		= (glDrawRangeElementsBaseVertexFunc)		loader->get("glDrawRangeElementsBaseVertexOES");
+	gl->multiDrawElementsBaseVertex		= (glMultiDrawElementsBaseVertexFunc)		loader->get("glMultiDrawElementsBaseVertexOES");
+}
diff --git a/framework/opengl/wrapper/glwInitExtGL.inl b/framework/opengl/wrapper/glwInitExtGL.inl
index d044fa2..590ef0d 100644
--- a/framework/opengl/wrapper/glwInitExtGL.inl
+++ b/framework/opengl/wrapper/glwInitExtGL.inl
@@ -1,9 +1,14 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
+if (de::contains(extSet, "GL_KHR_blend_equation_advanced"))
+{
+	gl->blendBarrier	= (glBlendBarrierFunc)	loader->get("glBlendBarrierKHR");
+}
+
 if (de::contains(extSet, "GL_KHR_debug"))
 {
 	gl->debugMessageCallback	= (glDebugMessageCallbackFunc)	loader->get("glDebugMessageCallback");
@@ -18,6 +23,13 @@
 	gl->pushDebugGroup			= (glPushDebugGroupFunc)		loader->get("glPushDebugGroup");
 }
 
+if (de::contains(extSet, "GL_EXT_debug_marker"))
+{
+	gl->insertEventMarkerEXT	= (glInsertEventMarkerEXTFunc)	loader->get("glInsertEventMarkerEXT");
+	gl->popGroupMarkerEXT		= (glPopGroupMarkerEXTFunc)		loader->get("glPopGroupMarkerEXT");
+	gl->pushGroupMarkerEXT		= (glPushGroupMarkerEXTFunc)	loader->get("glPushGroupMarkerEXT");
+}
+
 if (de::contains(extSet, "GL_KHR_robustness"))
 {
 	gl->getGraphicsResetStatus	= (glGetGraphicsResetStatusFunc)	loader->get("glGetGraphicsResetStatus");
diff --git a/framework/opengl/wrapper/glwInitGL30.inl b/framework/opengl/wrapper/glwInitGL30.inl
index 9dc2897..6ee285d 100644
--- a/framework/opengl/wrapper/glwInitGL30.inl
+++ b/framework/opengl/wrapper/glwInitGL30.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitGL31.inl b/framework/opengl/wrapper/glwInitGL31.inl
index 92800d9..800bb4e 100644
--- a/framework/opengl/wrapper/glwInitGL31.inl
+++ b/framework/opengl/wrapper/glwInitGL31.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitGL32.inl b/framework/opengl/wrapper/glwInitGL32.inl
index 91f5db4..2199baa 100644
--- a/framework/opengl/wrapper/glwInitGL32.inl
+++ b/framework/opengl/wrapper/glwInitGL32.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitGL33.inl b/framework/opengl/wrapper/glwInitGL33.inl
index caa2e55..0225d86 100644
--- a/framework/opengl/wrapper/glwInitGL33.inl
+++ b/framework/opengl/wrapper/glwInitGL33.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitGL40.inl b/framework/opengl/wrapper/glwInitGL40.inl
index 2bf8865..35209c2 100644
--- a/framework/opengl/wrapper/glwInitGL40.inl
+++ b/framework/opengl/wrapper/glwInitGL40.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
 gl->attachShader						= (glAttachShaderFunc)							loader->get("glAttachShader");
diff --git a/framework/opengl/wrapper/glwInitGL41.inl b/framework/opengl/wrapper/glwInitGL41.inl
index cfcf02e..b3702fe 100644
--- a/framework/opengl/wrapper/glwInitGL41.inl
+++ b/framework/opengl/wrapper/glwInitGL41.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram					= (glActiveShaderProgramFunc)					loader->get("glActiveShaderProgram");
 gl->activeTexture						= (glActiveTextureFunc)							loader->get("glActiveTexture");
diff --git a/framework/opengl/wrapper/glwInitGL42.inl b/framework/opengl/wrapper/glwInitGL42.inl
index c9c21f3..40d0f21 100644
--- a/framework/opengl/wrapper/glwInitGL42.inl
+++ b/framework/opengl/wrapper/glwInitGL42.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram							= (glActiveShaderProgramFunc)							loader->get("glActiveShaderProgram");
 gl->activeTexture								= (glActiveTextureFunc)									loader->get("glActiveTexture");
diff --git a/framework/opengl/wrapper/glwInitGL43.inl b/framework/opengl/wrapper/glwInitGL43.inl
index 38ee658..eaed3a1 100644
--- a/framework/opengl/wrapper/glwInitGL43.inl
+++ b/framework/opengl/wrapper/glwInitGL43.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram							= (glActiveShaderProgramFunc)							loader->get("glActiveShaderProgram");
 gl->activeTexture								= (glActiveTextureFunc)									loader->get("glActiveTexture");
diff --git a/framework/opengl/wrapper/glwInitGL44.inl b/framework/opengl/wrapper/glwInitGL44.inl
index 31e26ef..fac353f 100644
--- a/framework/opengl/wrapper/glwInitGL44.inl
+++ b/framework/opengl/wrapper/glwInitGL44.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram							= (glActiveShaderProgramFunc)							loader->get("glActiveShaderProgram");
 gl->activeTexture								= (glActiveTextureFunc)									loader->get("glActiveTexture");
diff --git a/framework/opengl/wrapper/glwInitGL45.inl b/framework/opengl/wrapper/glwInitGL45.inl
index 3cb112c..fb0e831 100644
--- a/framework/opengl/wrapper/glwInitGL45.inl
+++ b/framework/opengl/wrapper/glwInitGL45.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram							= (glActiveShaderProgramFunc)							loader->get("glActiveShaderProgram");
 gl->activeTexture								= (glActiveTextureFunc)									loader->get("glActiveTexture");
diff --git a/framework/platform/null/tcuNullRenderContextFuncs.inl b/framework/platform/null/tcuNullRenderContextFuncs.inl
index bf2e720..8b39a19 100644
--- a/framework/platform/null/tcuNullRenderContextFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextFuncs.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 
 GLW_APICALL void GLW_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program)
@@ -478,10 +478,11 @@
 
 }
 
-GLW_APICALL void GLW_APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil)
+GLW_APICALL void GLW_APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
 {
 	DE_UNREF(framebuffer);
 	DE_UNREF(buffer);
+	DE_UNREF(drawbuffer);
 	DE_UNREF(depth);
 	DE_UNREF(stencil);
 
diff --git a/framework/platform/null/tcuNullRenderContextInitFuncs.inl b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
index dfc2256..a6c58fe 100644
--- a/framework/platform/null/tcuNullRenderContextInitFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos GL API description (gl.xml) revision 32093.
+ * Generated from Khronos GL API description (gl.xml) revision 7ac9c857db1e3a6065485e4e2144151f48a4f1c4.
  */
 gl->activeShaderProgram							= glActiveShaderProgram;
 gl->activeTexture								= glActiveTexture;
diff --git a/framework/qphelper/qpTestLog.h b/framework/qphelper/qpTestLog.h
index 807716e..1a9385b 100644
--- a/framework/qphelper/qpTestLog.h
+++ b/framework/qphelper/qpTestLog.h
@@ -30,7 +30,7 @@
  * Each function takes qpTestLog pointer. Operations are done on that log
  * instance.
  *
- * When function takes a 'name' parameter, that name is exepected to
+ * When function takes a 'name' parameter, that name is expected to
  * be a unique identifier within the scope of one test case. Test case
  * begins with a call to qpTestLog_startCase and ends with a call to
  * qpTestLog_endCase or qpTestLog_terminateCase. The human readable
diff --git a/framework/qphelper/qpWatchDog.c b/framework/qphelper/qpWatchDog.c
index 84957b8..c691aa2 100644
--- a/framework/qphelper/qpWatchDog.c
+++ b/framework/qphelper/qpWatchDog.c
@@ -69,11 +69,14 @@
 		deUint64	curTime					= deGetMicroseconds();
 		int			totalSecondsPassed		= (int)((curTime - dog->resetTime) / 1000000ull);
 		int			secondsSinceLastTouch	= (int)((curTime - dog->lastTouchTime) / 1000000ull);
+		deBool		overIntervalLimit		= secondsSinceLastTouch > dog->intervalTimeLimit;
+		deBool		overTotalLimit			= totalSecondsPassed > dog->totalTimeLimit;
 
-		if ((secondsSinceLastTouch > dog->intervalTimeLimit) || (totalSecondsPassed > dog->totalTimeLimit))
+		if (overIntervalLimit || overTotalLimit)
 		{
+		    qpTimeoutReason reason = overTotalLimit ? QP_TIMEOUT_REASON_TOTAL_LIMIT : QP_TIMEOUT_REASON_INTERVAL_LIMIT;
 			DBGPRINT(("watchDogThreadFunc(): call timeout func\n"));
-			dog->timeOutFunc(dog, dog->timeOutUserPtr);
+			dog->timeOutFunc(dog, dog->timeOutUserPtr, reason);
 			break;
 		}
 
diff --git a/framework/qphelper/qpWatchDog.h b/framework/qphelper/qpWatchDog.h
index 6ac8f6a..6247e66 100644
--- a/framework/qphelper/qpWatchDog.h
+++ b/framework/qphelper/qpWatchDog.h
@@ -27,7 +27,15 @@
 
 typedef struct qpWatchDog_s	qpWatchDog;
 
-typedef void		(*qpWatchDogFunc)		(qpWatchDog* dog, void* userPtr);
+typedef enum qpTimeoutReason_e
+{
+	QP_TIMEOUT_REASON_INTERVAL_LIMIT = 0,
+	QP_TIMEOUT_REASON_TOTAL_LIMIT,
+
+	QP_TIMEOUT_REASON_LAST
+} qpTimeoutReason;
+
+typedef void		(*qpWatchDogFunc)		(qpWatchDog* dog, void* userPtr, qpTimeoutReason reason);
 
 DE_BEGIN_EXTERN_C
 
diff --git a/modules/egl/CMakeLists.txt b/modules/egl/CMakeLists.txt
index 6772b48..ee3eca8 100644
--- a/modules/egl/CMakeLists.txt
+++ b/modules/egl/CMakeLists.txt
@@ -101,6 +101,8 @@
 	teglThreadCleanUpTests.cpp
 	teglRobustnessTests.hpp
 	teglRobustnessTests.cpp
+	teglWideColorTests.hpp
+	teglWideColorTests.cpp
 	)
 
 set(DEQP_EGL_LIBS
diff --git a/modules/egl/teglGLES2SharingThreadedTests.cpp b/modules/egl/teglGLES2SharingThreadedTests.cpp
index 7e0ef88..a51a674 100644
--- a/modules/egl/teglGLES2SharingThreadedTests.cpp
+++ b/modules/egl/teglGLES2SharingThreadedTests.cpp
@@ -3642,7 +3642,9 @@
 		int readyThreads = 0;
 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
 		{
-			if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
+			const tcu::ThreadUtil::Thread::ThreadStatus status = m_threads[threadNdx]->getStatus();
+
+			if (status != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING && status != tcu::ThreadUtil::Thread::THREADSTATUS_NOT_STARTED)
 				readyThreads++;
 		}
 
diff --git a/modules/egl/teglGetProcAddressTests.inl b/modules/egl/teglGetProcAddressTests.inl
index 33fde9b..53029fa 100644
--- a/modules/egl/teglGetProcAddressTests.inl
+++ b/modules/egl/teglGetProcAddressTests.inl
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 33315.
+ * Generated from Khronos EGL API description (egl.xml) revision 13a26984991216cbf9a44fbf390f95dc05b5493a.
  */
 
 static const char* s_EGL14[] =
@@ -541,6 +541,11 @@
 	"eglQueryDebugKHR",
 };
 
+static const char* s_EGL_KHR_display_reference[] =
+{
+	"eglQueryDisplayAttribKHR",
+};
+
 static const char* s_EGL_KHR_fence_sync[] =
 {
 	"eglClientWaitSyncKHR",
@@ -711,6 +716,17 @@
 	"eglGetSystemTimeNV",
 };
 
+static const char* s_EGL_EXT_compositor[] =
+{
+	"eglCompositorSetContextListEXT",
+	"eglCompositorSetContextAttributesEXT",
+	"eglCompositorSetWindowListEXT",
+	"eglCompositorSetWindowAttributesEXT",
+	"eglCompositorBindTexWindowEXT",
+	"eglCompositorSetSizeEXT",
+	"eglCompositorSwapPolicyEXT",
+};
+
 static const char* s_GL_APPLE_copy_texture_levels[] =
 {
 	"glCopyTextureLevelsAPPLE",
@@ -1039,6 +1055,12 @@
 	"glBufferStorageEXT",
 };
 
+static const char* s_GL_EXT_clear_texture[] =
+{
+	"glClearTexImageEXT",
+	"glClearTexSubImageEXT",
+};
+
 static const char* s_GL_EXT_copy_image[] =
 {
 	"glCopyImageSubDataEXT",
@@ -1103,6 +1125,18 @@
 	"glDrawElementsInstancedEXT",
 };
 
+static const char* s_GL_EXT_draw_transform_feedback[] =
+{
+	"glDrawTransformFeedbackEXT",
+	"glDrawTransformFeedbackInstancedEXT",
+};
+
+static const char* s_GL_EXT_external_buffer[] =
+{
+	"glBufferStorageExternalEXT",
+	"glNamedBufferStorageExternalEXT",
+};
+
 static const char* s_GL_EXT_geometry_shader[] =
 {
 	"glFramebufferTextureEXT",
@@ -1115,6 +1149,38 @@
 	"glVertexAttribDivisorEXT",
 };
 
+static const char* s_GL_EXT_memory_object[] =
+{
+	"glBufferStorageMemEXT",
+	"glCreateMemoryObjectsEXT",
+	"glDeleteMemoryObjectsEXT",
+	"glGetMemoryObjectParameterivEXT",
+	"glGetUnsignedBytevEXT",
+	"glGetUnsignedBytei_vEXT",
+	"glIsMemoryObjectEXT",
+	"glMemoryObjectParameterivEXT",
+	"glNamedBufferStorageMemEXT",
+	"glTexStorageMem2DEXT",
+	"glTexStorageMem2DMultisampleEXT",
+	"glTexStorageMem3DEXT",
+	"glTexStorageMem3DMultisampleEXT",
+	"glTextureStorageMem2DEXT",
+	"glTextureStorageMem2DMultisampleEXT",
+	"glTextureStorageMem3DEXT",
+	"glTextureStorageMem3DMultisampleEXT",
+};
+
+static const char* s_GL_EXT_memory_object_fd[] =
+{
+	"glImportMemoryFdEXT",
+};
+
+static const char* s_GL_EXT_memory_object_win32[] =
+{
+	"glImportMemoryWin32HandleEXT",
+	"glImportMemoryWin32NameEXT",
+};
+
 static const char* s_GL_EXT_multi_draw_indirect[] =
 {
 	"glMultiDrawArraysIndirectEXT",
@@ -1139,6 +1205,11 @@
 	"glIsQueryEXT",
 };
 
+static const char* s_GL_EXT_polygon_offset_clamp[] =
+{
+	"glPolygonOffsetClampEXT",
+};
+
 static const char* s_GL_EXT_primitive_bounding_box[] =
 {
 	"glPrimitiveBoundingBoxEXT",
@@ -1149,6 +1220,30 @@
 	"glRasterSamplesEXT",
 };
 
+static const char* s_GL_EXT_semaphore[] =
+{
+	"glDeleteSemaphoresEXT",
+	"glGenSemaphoresEXT",
+	"glGetSemaphoreParameterui64vEXT",
+	"glGetUnsignedBytevEXT",
+	"glGetUnsignedBytei_vEXT",
+	"glIsSemaphoreEXT",
+	"glSemaphoreParameterui64vEXT",
+	"glSignalSemaphoreEXT",
+	"glWaitSemaphoreEXT",
+};
+
+static const char* s_GL_EXT_semaphore_fd[] =
+{
+	"glImportSemaphoreFdEXT",
+};
+
+static const char* s_GL_EXT_semaphore_win32[] =
+{
+	"glImportSemaphoreWin32HandleEXT",
+	"glImportSemaphoreWin32NameEXT",
+};
+
 static const char* s_GL_EXT_separate_shader_objects[] =
 {
 	"glActiveShaderProgramEXT",
@@ -1197,6 +1292,13 @@
 	"glValidateProgramPipelineEXT",
 };
 
+static const char* s_GL_EXT_shader_pixel_local_storage2[] =
+{
+	"glClearPixelLocalStorageuiEXT",
+	"glFramebufferPixelLocalStorageSizeEXT",
+	"glGetFramebufferPixelLocalStorageSizeEXT",
+};
+
 static const char* s_GL_EXT_sparse_texture[] =
 {
 	"glTexPageCommitmentEXT",
@@ -1235,6 +1337,33 @@
 	"glTextureViewEXT",
 };
 
+static const char* s_GL_EXT_win32_keyed_mutex[] =
+{
+	"glAcquireKeyedMutexWin32EXT",
+	"glReleaseKeyedMutexWin32EXT",
+};
+
+static const char* s_GL_EXT_window_rectangles[] =
+{
+	"glWindowRectanglesEXT",
+};
+
+static const char* s_GL_IMG_bindless_texture[] =
+{
+	"glGetTextureHandleIMG",
+	"glGetTextureSamplerHandleIMG",
+	"glProgramUniformHandleui64IMG",
+	"glProgramUniformHandleui64vIMG",
+	"glUniformHandleui64IMG",
+	"glUniformHandleui64vIMG",
+};
+
+static const char* s_GL_IMG_framebuffer_downsample[] =
+{
+	"glFramebufferTexture2DDownsampleIMG",
+	"glFramebufferTextureLayerDownsampleIMG",
+};
+
 static const char* s_GL_INTEL_framebuffer_CMAA[] =
 {
 	"glApplyFramebufferAttachmentCMAAINTEL",
@@ -1317,6 +1446,11 @@
 	"glSubpixelPrecisionBiasNV",
 };
 
+static const char* s_GL_NV_conservative_raster_pre_snap_triangles[] =
+{
+	"glConservativeRasterParameteriNV",
+};
+
 static const char* s_GL_NV_copy_buffer[] =
 {
 	"glCopyBufferSubDataNV",
@@ -1339,6 +1473,15 @@
 	"glDrawElementsInstancedNV",
 };
 
+static const char* s_GL_NV_draw_vulkan_image[] =
+{
+	"glDrawVkImageNV",
+	"glGetVkProcAddrNV",
+	"glWaitVkSemaphoreNV",
+	"glSignalVkSemaphoreNV",
+	"glSignalVkFenceNV",
+};
+
 static const char* s_GL_NV_fragment_coverage_to_color[] =
 {
 	"glFragmentCoverageColorNV",
@@ -1362,6 +1505,43 @@
 	"glRenderbufferStorageMultisampleNV",
 };
 
+static const char* s_GL_NV_gpu_shader5[] =
+{
+	"glGetUniformi64vNV",
+	"glProgramUniform1i64NV",
+	"glProgramUniform1i64vNV",
+	"glProgramUniform1ui64NV",
+	"glProgramUniform1ui64vNV",
+	"glProgramUniform2i64NV",
+	"glProgramUniform2i64vNV",
+	"glProgramUniform2ui64NV",
+	"glProgramUniform2ui64vNV",
+	"glProgramUniform3i64NV",
+	"glProgramUniform3i64vNV",
+	"glProgramUniform3ui64NV",
+	"glProgramUniform3ui64vNV",
+	"glProgramUniform4i64NV",
+	"glProgramUniform4i64vNV",
+	"glProgramUniform4ui64NV",
+	"glProgramUniform4ui64vNV",
+	"glUniform1i64NV",
+	"glUniform1i64vNV",
+	"glUniform1ui64NV",
+	"glUniform1ui64vNV",
+	"glUniform2i64NV",
+	"glUniform2i64vNV",
+	"glUniform2ui64NV",
+	"glUniform2ui64vNV",
+	"glUniform3i64NV",
+	"glUniform3i64vNV",
+	"glUniform3ui64NV",
+	"glUniform3ui64vNV",
+	"glUniform4i64NV",
+	"glUniform4i64vNV",
+	"glUniform4ui64NV",
+	"glUniform4ui64vNV",
+};
+
 static const char* s_GL_NV_instanced_arrays[] =
 {
 	"glVertexAttribDivisorNV",
@@ -1476,6 +1656,11 @@
 	"glViewportIndexedfvNV",
 };
 
+static const char* s_GL_NV_viewport_swizzle[] =
+{
+	"glViewportSwizzleNV",
+};
+
 static const char* s_GL_OES_copy_image[] =
 {
 	"glCopyImageSubDataOES",
@@ -1565,16 +1750,48 @@
 	"glTextureViewOES",
 };
 
+static const char* s_GL_OES_viewport_array[] =
+{
+	"glDepthRangeArrayfvOES",
+	"glDepthRangeIndexedfOES",
+	"glDisableiOES",
+	"glEnableiOES",
+	"glGetFloati_vOES",
+	"glIsEnablediOES",
+	"glScissorArrayvOES",
+	"glScissorIndexedOES",
+	"glScissorIndexedvOES",
+	"glViewportArrayvOES",
+	"glViewportIndexedfOES",
+	"glViewportIndexedfvOES",
+};
+
 static const char* s_GL_OVR_multiview[] =
 {
 	"glFramebufferTextureMultiviewOVR",
 };
 
+static const char* s_GL_OVR_multiview_multisampled_render_to_texture[] =
+{
+	"glFramebufferTextureMultisampleMultiviewOVR",
+};
+
 static const char* s_GL_QCOM_alpha_test[] =
 {
 	"glAlphaFuncQCOM",
 };
 
+static const char* s_GL_QCOM_framebuffer_foveated[] =
+{
+	"glFramebufferFoveationConfigQCOM",
+	"glFramebufferFoveationParametersQCOM",
+};
+
+static const char* s_GL_QCOM_shader_framebuffer_fetch_noncoherent[] =
+{
+	"glFramebufferFetchBarrierQCOM",
+};
+
 static const struct
 {
 	const char*			name;
@@ -1582,147 +1799,172 @@
 	const char* const*	functions;
 } s_extensions[] =
 {
-	{ "EGL_ANDROID_blob_cache",							DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_blob_cache),						s_EGL_ANDROID_blob_cache						},
-	{ "EGL_ANDROID_create_native_client_buffer",		DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_create_native_client_buffer),		s_EGL_ANDROID_create_native_client_buffer		},
-	{ "EGL_ANDROID_native_fence_sync",					DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_native_fence_sync),				s_EGL_ANDROID_native_fence_sync					},
-	{ "EGL_ANDROID_presentation_time",					DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_presentation_time),				s_EGL_ANDROID_presentation_time					},
-	{ "EGL_ANGLE_query_surface_pointer",				DE_LENGTH_OF_ARRAY(s_EGL_ANGLE_query_surface_pointer),				s_EGL_ANGLE_query_surface_pointer				},
-	{ "EGL_EXT_device_base",							DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_base),							s_EGL_EXT_device_base							},
-	{ "EGL_EXT_device_enumeration",						DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_enumeration),					s_EGL_EXT_device_enumeration					},
-	{ "EGL_EXT_device_query",							DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_query),							s_EGL_EXT_device_query							},
-	{ "EGL_EXT_image_dma_buf_import_modifiers",			DE_LENGTH_OF_ARRAY(s_EGL_EXT_image_dma_buf_import_modifiers),		s_EGL_EXT_image_dma_buf_import_modifiers		},
-	{ "EGL_EXT_output_base",							DE_LENGTH_OF_ARRAY(s_EGL_EXT_output_base),							s_EGL_EXT_output_base							},
-	{ "EGL_EXT_platform_base",							DE_LENGTH_OF_ARRAY(s_EGL_EXT_platform_base),						s_EGL_EXT_platform_base							},
-	{ "EGL_EXT_stream_consumer_egloutput",				DE_LENGTH_OF_ARRAY(s_EGL_EXT_stream_consumer_egloutput),			s_EGL_EXT_stream_consumer_egloutput				},
-	{ "EGL_EXT_swap_buffers_with_damage",				DE_LENGTH_OF_ARRAY(s_EGL_EXT_swap_buffers_with_damage),				s_EGL_EXT_swap_buffers_with_damage				},
-	{ "EGL_HI_clientpixmap",							DE_LENGTH_OF_ARRAY(s_EGL_HI_clientpixmap),							s_EGL_HI_clientpixmap							},
-	{ "EGL_KHR_cl_event2",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_cl_event2),							s_EGL_KHR_cl_event2								},
-	{ "EGL_KHR_debug",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_debug),								s_EGL_KHR_debug									},
-	{ "EGL_KHR_fence_sync",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_fence_sync),							s_EGL_KHR_fence_sync							},
-	{ "EGL_KHR_image",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_image),								s_EGL_KHR_image									},
-	{ "EGL_KHR_image_base",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_image_base),							s_EGL_KHR_image_base							},
-	{ "EGL_KHR_lock_surface",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_lock_surface),							s_EGL_KHR_lock_surface							},
-	{ "EGL_KHR_lock_surface3",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_lock_surface3),						s_EGL_KHR_lock_surface3							},
-	{ "EGL_KHR_partial_update",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_partial_update),						s_EGL_KHR_partial_update						},
-	{ "EGL_KHR_reusable_sync",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_reusable_sync),						s_EGL_KHR_reusable_sync							},
-	{ "EGL_KHR_stream",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream),								s_EGL_KHR_stream								},
-	{ "EGL_KHR_stream_attrib",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_attrib),						s_EGL_KHR_stream_attrib							},
-	{ "EGL_KHR_stream_consumer_gltexture",				DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_consumer_gltexture),			s_EGL_KHR_stream_consumer_gltexture				},
-	{ "EGL_KHR_stream_cross_process_fd",				DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_cross_process_fd),				s_EGL_KHR_stream_cross_process_fd				},
-	{ "EGL_KHR_stream_fifo",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_fifo),							s_EGL_KHR_stream_fifo							},
-	{ "EGL_KHR_stream_producer_eglsurface",				DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_producer_eglsurface),			s_EGL_KHR_stream_producer_eglsurface			},
-	{ "EGL_KHR_swap_buffers_with_damage",				DE_LENGTH_OF_ARRAY(s_EGL_KHR_swap_buffers_with_damage),				s_EGL_KHR_swap_buffers_with_damage				},
-	{ "EGL_KHR_wait_sync",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_wait_sync),							s_EGL_KHR_wait_sync								},
-	{ "EGL_MESA_drm_image",								DE_LENGTH_OF_ARRAY(s_EGL_MESA_drm_image),							s_EGL_MESA_drm_image							},
-	{ "EGL_MESA_image_dma_buf_export",					DE_LENGTH_OF_ARRAY(s_EGL_MESA_image_dma_buf_export),				s_EGL_MESA_image_dma_buf_export					},
-	{ "EGL_NOK_swap_region",							DE_LENGTH_OF_ARRAY(s_EGL_NOK_swap_region),							s_EGL_NOK_swap_region							},
-	{ "EGL_NOK_swap_region2",							DE_LENGTH_OF_ARRAY(s_EGL_NOK_swap_region2),							s_EGL_NOK_swap_region2							},
-	{ "EGL_NV_native_query",							DE_LENGTH_OF_ARRAY(s_EGL_NV_native_query),							s_EGL_NV_native_query							},
-	{ "EGL_NV_post_sub_buffer",							DE_LENGTH_OF_ARRAY(s_EGL_NV_post_sub_buffer),						s_EGL_NV_post_sub_buffer						},
-	{ "EGL_NV_stream_consumer_gltexture_yuv",			DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_consumer_gltexture_yuv),			s_EGL_NV_stream_consumer_gltexture_yuv			},
-	{ "EGL_NV_stream_metadata",							DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_metadata),						s_EGL_NV_stream_metadata						},
-	{ "EGL_NV_stream_reset",							DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_reset),							s_EGL_NV_stream_reset							},
-	{ "EGL_NV_stream_sync",								DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_sync),							s_EGL_NV_stream_sync							},
-	{ "EGL_NV_sync",									DE_LENGTH_OF_ARRAY(s_EGL_NV_sync),									s_EGL_NV_sync									},
-	{ "EGL_NV_system_time",								DE_LENGTH_OF_ARRAY(s_EGL_NV_system_time),							s_EGL_NV_system_time							},
-	{ "GL_APPLE_copy_texture_levels",					DE_LENGTH_OF_ARRAY(s_GL_APPLE_copy_texture_levels),					s_GL_APPLE_copy_texture_levels					},
-	{ "GL_APPLE_framebuffer_multisample",				DE_LENGTH_OF_ARRAY(s_GL_APPLE_framebuffer_multisample),				s_GL_APPLE_framebuffer_multisample				},
-	{ "GL_APPLE_sync",									DE_LENGTH_OF_ARRAY(s_GL_APPLE_sync),								s_GL_APPLE_sync									},
-	{ "GL_EXT_discard_framebuffer",						DE_LENGTH_OF_ARRAY(s_GL_EXT_discard_framebuffer),					s_GL_EXT_discard_framebuffer					},
-	{ "GL_EXT_map_buffer_range",						DE_LENGTH_OF_ARRAY(s_GL_EXT_map_buffer_range),						s_GL_EXT_map_buffer_range						},
-	{ "GL_EXT_multi_draw_arrays",						DE_LENGTH_OF_ARRAY(s_GL_EXT_multi_draw_arrays),						s_GL_EXT_multi_draw_arrays						},
-	{ "GL_EXT_multisampled_render_to_texture",			DE_LENGTH_OF_ARRAY(s_GL_EXT_multisampled_render_to_texture),		s_GL_EXT_multisampled_render_to_texture			},
-	{ "GL_EXT_robustness",								DE_LENGTH_OF_ARRAY(s_GL_EXT_robustness),							s_GL_EXT_robustness								},
-	{ "GL_EXT_texture_storage",							DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_storage),						s_GL_EXT_texture_storage						},
-	{ "GL_IMG_multisampled_render_to_texture",			DE_LENGTH_OF_ARRAY(s_GL_IMG_multisampled_render_to_texture),		s_GL_IMG_multisampled_render_to_texture			},
-	{ "GL_IMG_user_clip_plane",							DE_LENGTH_OF_ARRAY(s_GL_IMG_user_clip_plane),						s_GL_IMG_user_clip_plane						},
-	{ "GL_NV_fence",									DE_LENGTH_OF_ARRAY(s_GL_NV_fence),									s_GL_NV_fence									},
-	{ "GL_OES_EGL_image",								DE_LENGTH_OF_ARRAY(s_GL_OES_EGL_image),								s_GL_OES_EGL_image								},
-	{ "GL_OES_blend_equation_separate",					DE_LENGTH_OF_ARRAY(s_GL_OES_blend_equation_separate),				s_GL_OES_blend_equation_separate				},
-	{ "GL_OES_blend_func_separate",						DE_LENGTH_OF_ARRAY(s_GL_OES_blend_func_separate),					s_GL_OES_blend_func_separate					},
-	{ "GL_OES_blend_subtract",							DE_LENGTH_OF_ARRAY(s_GL_OES_blend_subtract),						s_GL_OES_blend_subtract							},
-	{ "GL_OES_draw_texture",							DE_LENGTH_OF_ARRAY(s_GL_OES_draw_texture),							s_GL_OES_draw_texture							},
-	{ "GL_OES_fixed_point",								DE_LENGTH_OF_ARRAY(s_GL_OES_fixed_point),							s_GL_OES_fixed_point							},
-	{ "GL_OES_framebuffer_object",						DE_LENGTH_OF_ARRAY(s_GL_OES_framebuffer_object),					s_GL_OES_framebuffer_object						},
-	{ "GL_OES_mapbuffer",								DE_LENGTH_OF_ARRAY(s_GL_OES_mapbuffer),								s_GL_OES_mapbuffer								},
-	{ "GL_OES_matrix_palette",							DE_LENGTH_OF_ARRAY(s_GL_OES_matrix_palette),						s_GL_OES_matrix_palette							},
-	{ "GL_OES_point_size_array",						DE_LENGTH_OF_ARRAY(s_GL_OES_point_size_array),						s_GL_OES_point_size_array						},
-	{ "GL_OES_query_matrix",							DE_LENGTH_OF_ARRAY(s_GL_OES_query_matrix),							s_GL_OES_query_matrix							},
-	{ "GL_OES_single_precision",						DE_LENGTH_OF_ARRAY(s_GL_OES_single_precision),						s_GL_OES_single_precision						},
-	{ "GL_OES_texture_cube_map",						DE_LENGTH_OF_ARRAY(s_GL_OES_texture_cube_map),						s_GL_OES_texture_cube_map						},
-	{ "GL_OES_vertex_array_object",						DE_LENGTH_OF_ARRAY(s_GL_OES_vertex_array_object),					s_GL_OES_vertex_array_object					},
-	{ "GL_QCOM_driver_control",							DE_LENGTH_OF_ARRAY(s_GL_QCOM_driver_control),						s_GL_QCOM_driver_control						},
-	{ "GL_QCOM_extended_get",							DE_LENGTH_OF_ARRAY(s_GL_QCOM_extended_get),							s_GL_QCOM_extended_get							},
-	{ "GL_QCOM_extended_get2",							DE_LENGTH_OF_ARRAY(s_GL_QCOM_extended_get2),						s_GL_QCOM_extended_get2							},
-	{ "GL_QCOM_tiled_rendering",						DE_LENGTH_OF_ARRAY(s_GL_QCOM_tiled_rendering),						s_GL_QCOM_tiled_rendering						},
-	{ "GL_AMD_performance_monitor",						DE_LENGTH_OF_ARRAY(s_GL_AMD_performance_monitor),					s_GL_AMD_performance_monitor					},
-	{ "GL_ANGLE_framebuffer_blit",						DE_LENGTH_OF_ARRAY(s_GL_ANGLE_framebuffer_blit),					s_GL_ANGLE_framebuffer_blit						},
-	{ "GL_ANGLE_framebuffer_multisample",				DE_LENGTH_OF_ARRAY(s_GL_ANGLE_framebuffer_multisample),				s_GL_ANGLE_framebuffer_multisample				},
-	{ "GL_ANGLE_instanced_arrays",						DE_LENGTH_OF_ARRAY(s_GL_ANGLE_instanced_arrays),					s_GL_ANGLE_instanced_arrays						},
-	{ "GL_ANGLE_translated_shader_source",				DE_LENGTH_OF_ARRAY(s_GL_ANGLE_translated_shader_source),			s_GL_ANGLE_translated_shader_source				},
-	{ "GL_EXT_base_instance",							DE_LENGTH_OF_ARRAY(s_GL_EXT_base_instance),							s_GL_EXT_base_instance							},
-	{ "GL_EXT_blend_func_extended",						DE_LENGTH_OF_ARRAY(s_GL_EXT_blend_func_extended),					s_GL_EXT_blend_func_extended					},
-	{ "GL_EXT_buffer_storage",							DE_LENGTH_OF_ARRAY(s_GL_EXT_buffer_storage),						s_GL_EXT_buffer_storage							},
-	{ "GL_EXT_copy_image",								DE_LENGTH_OF_ARRAY(s_GL_EXT_copy_image),							s_GL_EXT_copy_image								},
-	{ "GL_EXT_debug_label",								DE_LENGTH_OF_ARRAY(s_GL_EXT_debug_label),							s_GL_EXT_debug_label							},
-	{ "GL_EXT_debug_marker",							DE_LENGTH_OF_ARRAY(s_GL_EXT_debug_marker),							s_GL_EXT_debug_marker							},
-	{ "GL_EXT_disjoint_timer_query",					DE_LENGTH_OF_ARRAY(s_GL_EXT_disjoint_timer_query),					s_GL_EXT_disjoint_timer_query					},
-	{ "GL_EXT_draw_buffers",							DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_buffers),							s_GL_EXT_draw_buffers							},
-	{ "GL_EXT_draw_buffers_indexed",					DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_buffers_indexed),					s_GL_EXT_draw_buffers_indexed					},
-	{ "GL_EXT_draw_elements_base_vertex",				DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_elements_base_vertex),				s_GL_EXT_draw_elements_base_vertex				},
-	{ "GL_EXT_draw_instanced",							DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_instanced),						s_GL_EXT_draw_instanced							},
-	{ "GL_EXT_geometry_shader",							DE_LENGTH_OF_ARRAY(s_GL_EXT_geometry_shader),						s_GL_EXT_geometry_shader						},
-	{ "GL_EXT_instanced_arrays",						DE_LENGTH_OF_ARRAY(s_GL_EXT_instanced_arrays),						s_GL_EXT_instanced_arrays						},
-	{ "GL_EXT_multi_draw_indirect",						DE_LENGTH_OF_ARRAY(s_GL_EXT_multi_draw_indirect),					s_GL_EXT_multi_draw_indirect					},
-	{ "GL_EXT_multiview_draw_buffers",					DE_LENGTH_OF_ARRAY(s_GL_EXT_multiview_draw_buffers),				s_GL_EXT_multiview_draw_buffers					},
-	{ "GL_EXT_occlusion_query_boolean",					DE_LENGTH_OF_ARRAY(s_GL_EXT_occlusion_query_boolean),				s_GL_EXT_occlusion_query_boolean				},
-	{ "GL_EXT_primitive_bounding_box",					DE_LENGTH_OF_ARRAY(s_GL_EXT_primitive_bounding_box),				s_GL_EXT_primitive_bounding_box					},
-	{ "GL_EXT_raster_multisample",						DE_LENGTH_OF_ARRAY(s_GL_EXT_raster_multisample),					s_GL_EXT_raster_multisample						},
-	{ "GL_EXT_separate_shader_objects",					DE_LENGTH_OF_ARRAY(s_GL_EXT_separate_shader_objects),				s_GL_EXT_separate_shader_objects				},
-	{ "GL_EXT_sparse_texture",							DE_LENGTH_OF_ARRAY(s_GL_EXT_sparse_texture),						s_GL_EXT_sparse_texture							},
-	{ "GL_EXT_tessellation_shader",						DE_LENGTH_OF_ARRAY(s_GL_EXT_tessellation_shader),					s_GL_EXT_tessellation_shader					},
-	{ "GL_EXT_texture_border_clamp",					DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_border_clamp),					s_GL_EXT_texture_border_clamp					},
-	{ "GL_EXT_texture_buffer",							DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_buffer),						s_GL_EXT_texture_buffer							},
-	{ "GL_EXT_texture_filter_minmax",					DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_filter_minmax),					s_GL_EXT_texture_filter_minmax					},
-	{ "GL_EXT_texture_view",							DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_view),							s_GL_EXT_texture_view							},
-	{ "GL_INTEL_framebuffer_CMAA",						DE_LENGTH_OF_ARRAY(s_GL_INTEL_framebuffer_CMAA),					s_GL_INTEL_framebuffer_CMAA						},
-	{ "GL_INTEL_performance_query",						DE_LENGTH_OF_ARRAY(s_GL_INTEL_performance_query),					s_GL_INTEL_performance_query					},
-	{ "GL_KHR_blend_equation_advanced",					DE_LENGTH_OF_ARRAY(s_GL_KHR_blend_equation_advanced),				s_GL_KHR_blend_equation_advanced				},
-	{ "GL_KHR_debug",									DE_LENGTH_OF_ARRAY(s_GL_KHR_debug),									s_GL_KHR_debug									},
-	{ "GL_KHR_robustness",								DE_LENGTH_OF_ARRAY(s_GL_KHR_robustness),							s_GL_KHR_robustness								},
-	{ "GL_NV_bindless_texture",							DE_LENGTH_OF_ARRAY(s_GL_NV_bindless_texture),						s_GL_NV_bindless_texture						},
-	{ "GL_NV_blend_equation_advanced",					DE_LENGTH_OF_ARRAY(s_GL_NV_blend_equation_advanced),				s_GL_NV_blend_equation_advanced					},
-	{ "GL_NV_conditional_render",						DE_LENGTH_OF_ARRAY(s_GL_NV_conditional_render),						s_GL_NV_conditional_render						},
-	{ "GL_NV_conservative_raster",						DE_LENGTH_OF_ARRAY(s_GL_NV_conservative_raster),					s_GL_NV_conservative_raster						},
-	{ "GL_NV_copy_buffer",								DE_LENGTH_OF_ARRAY(s_GL_NV_copy_buffer),							s_GL_NV_copy_buffer								},
-	{ "GL_NV_coverage_sample",							DE_LENGTH_OF_ARRAY(s_GL_NV_coverage_sample),						s_GL_NV_coverage_sample							},
-	{ "GL_NV_draw_buffers",								DE_LENGTH_OF_ARRAY(s_GL_NV_draw_buffers),							s_GL_NV_draw_buffers							},
-	{ "GL_NV_draw_instanced",							DE_LENGTH_OF_ARRAY(s_GL_NV_draw_instanced),							s_GL_NV_draw_instanced							},
-	{ "GL_NV_fragment_coverage_to_color",				DE_LENGTH_OF_ARRAY(s_GL_NV_fragment_coverage_to_color),				s_GL_NV_fragment_coverage_to_color				},
-	{ "GL_NV_framebuffer_blit",							DE_LENGTH_OF_ARRAY(s_GL_NV_framebuffer_blit),						s_GL_NV_framebuffer_blit						},
-	{ "GL_NV_framebuffer_mixed_samples",				DE_LENGTH_OF_ARRAY(s_GL_NV_framebuffer_mixed_samples),				s_GL_NV_framebuffer_mixed_samples				},
-	{ "GL_NV_framebuffer_multisample",					DE_LENGTH_OF_ARRAY(s_GL_NV_framebuffer_multisample),				s_GL_NV_framebuffer_multisample					},
-	{ "GL_NV_instanced_arrays",							DE_LENGTH_OF_ARRAY(s_GL_NV_instanced_arrays),						s_GL_NV_instanced_arrays						},
-	{ "GL_NV_internalformat_sample_query",				DE_LENGTH_OF_ARRAY(s_GL_NV_internalformat_sample_query),			s_GL_NV_internalformat_sample_query				},
-	{ "GL_NV_non_square_matrices",						DE_LENGTH_OF_ARRAY(s_GL_NV_non_square_matrices),					s_GL_NV_non_square_matrices						},
-	{ "GL_NV_path_rendering",							DE_LENGTH_OF_ARRAY(s_GL_NV_path_rendering),							s_GL_NV_path_rendering							},
-	{ "GL_NV_polygon_mode",								DE_LENGTH_OF_ARRAY(s_GL_NV_polygon_mode),							s_GL_NV_polygon_mode							},
-	{ "GL_NV_read_buffer",								DE_LENGTH_OF_ARRAY(s_GL_NV_read_buffer),							s_GL_NV_read_buffer								},
-	{ "GL_NV_sample_locations",							DE_LENGTH_OF_ARRAY(s_GL_NV_sample_locations),						s_GL_NV_sample_locations						},
-	{ "GL_NV_viewport_array",							DE_LENGTH_OF_ARRAY(s_GL_NV_viewport_array),							s_GL_NV_viewport_array							},
-	{ "GL_OES_copy_image",								DE_LENGTH_OF_ARRAY(s_GL_OES_copy_image),							s_GL_OES_copy_image								},
-	{ "GL_OES_draw_buffers_indexed",					DE_LENGTH_OF_ARRAY(s_GL_OES_draw_buffers_indexed),					s_GL_OES_draw_buffers_indexed					},
-	{ "GL_OES_draw_elements_base_vertex",				DE_LENGTH_OF_ARRAY(s_GL_OES_draw_elements_base_vertex),				s_GL_OES_draw_elements_base_vertex				},
-	{ "GL_OES_geometry_shader",							DE_LENGTH_OF_ARRAY(s_GL_OES_geometry_shader),						s_GL_OES_geometry_shader						},
-	{ "GL_OES_get_program_binary",						DE_LENGTH_OF_ARRAY(s_GL_OES_get_program_binary),					s_GL_OES_get_program_binary						},
-	{ "GL_OES_primitive_bounding_box",					DE_LENGTH_OF_ARRAY(s_GL_OES_primitive_bounding_box),				s_GL_OES_primitive_bounding_box					},
-	{ "GL_OES_sample_shading",							DE_LENGTH_OF_ARRAY(s_GL_OES_sample_shading),						s_GL_OES_sample_shading							},
-	{ "GL_OES_tessellation_shader",						DE_LENGTH_OF_ARRAY(s_GL_OES_tessellation_shader),					s_GL_OES_tessellation_shader					},
-	{ "GL_OES_texture_3D",								DE_LENGTH_OF_ARRAY(s_GL_OES_texture_3D),							s_GL_OES_texture_3D								},
-	{ "GL_OES_texture_border_clamp",					DE_LENGTH_OF_ARRAY(s_GL_OES_texture_border_clamp),					s_GL_OES_texture_border_clamp					},
-	{ "GL_OES_texture_buffer",							DE_LENGTH_OF_ARRAY(s_GL_OES_texture_buffer),						s_GL_OES_texture_buffer							},
-	{ "GL_OES_texture_storage_multisample_2d_array",	DE_LENGTH_OF_ARRAY(s_GL_OES_texture_storage_multisample_2d_array),	s_GL_OES_texture_storage_multisample_2d_array	},
-	{ "GL_OES_texture_view",							DE_LENGTH_OF_ARRAY(s_GL_OES_texture_view),							s_GL_OES_texture_view							},
-	{ "GL_OVR_multiview",								DE_LENGTH_OF_ARRAY(s_GL_OVR_multiview),								s_GL_OVR_multiview								},
-	{ "GL_QCOM_alpha_test",								DE_LENGTH_OF_ARRAY(s_GL_QCOM_alpha_test),							s_GL_QCOM_alpha_test							},
+	{ "EGL_ANDROID_blob_cache",								DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_blob_cache),							s_EGL_ANDROID_blob_cache							},
+	{ "EGL_ANDROID_create_native_client_buffer",			DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_create_native_client_buffer),			s_EGL_ANDROID_create_native_client_buffer			},
+	{ "EGL_ANDROID_native_fence_sync",						DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_native_fence_sync),					s_EGL_ANDROID_native_fence_sync						},
+	{ "EGL_ANDROID_presentation_time",						DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_presentation_time),					s_EGL_ANDROID_presentation_time						},
+	{ "EGL_ANGLE_query_surface_pointer",					DE_LENGTH_OF_ARRAY(s_EGL_ANGLE_query_surface_pointer),					s_EGL_ANGLE_query_surface_pointer					},
+	{ "EGL_EXT_device_base",								DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_base),								s_EGL_EXT_device_base								},
+	{ "EGL_EXT_device_enumeration",							DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_enumeration),						s_EGL_EXT_device_enumeration						},
+	{ "EGL_EXT_device_query",								DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_query),								s_EGL_EXT_device_query								},
+	{ "EGL_EXT_image_dma_buf_import_modifiers",				DE_LENGTH_OF_ARRAY(s_EGL_EXT_image_dma_buf_import_modifiers),			s_EGL_EXT_image_dma_buf_import_modifiers			},
+	{ "EGL_EXT_output_base",								DE_LENGTH_OF_ARRAY(s_EGL_EXT_output_base),								s_EGL_EXT_output_base								},
+	{ "EGL_EXT_platform_base",								DE_LENGTH_OF_ARRAY(s_EGL_EXT_platform_base),							s_EGL_EXT_platform_base								},
+	{ "EGL_EXT_stream_consumer_egloutput",					DE_LENGTH_OF_ARRAY(s_EGL_EXT_stream_consumer_egloutput),				s_EGL_EXT_stream_consumer_egloutput					},
+	{ "EGL_EXT_swap_buffers_with_damage",					DE_LENGTH_OF_ARRAY(s_EGL_EXT_swap_buffers_with_damage),					s_EGL_EXT_swap_buffers_with_damage					},
+	{ "EGL_HI_clientpixmap",								DE_LENGTH_OF_ARRAY(s_EGL_HI_clientpixmap),								s_EGL_HI_clientpixmap								},
+	{ "EGL_KHR_cl_event2",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_cl_event2),								s_EGL_KHR_cl_event2									},
+	{ "EGL_KHR_debug",										DE_LENGTH_OF_ARRAY(s_EGL_KHR_debug),									s_EGL_KHR_debug										},
+	{ "EGL_KHR_display_reference",							DE_LENGTH_OF_ARRAY(s_EGL_KHR_display_reference),						s_EGL_KHR_display_reference							},
+	{ "EGL_KHR_fence_sync",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_fence_sync),								s_EGL_KHR_fence_sync								},
+	{ "EGL_KHR_image",										DE_LENGTH_OF_ARRAY(s_EGL_KHR_image),									s_EGL_KHR_image										},
+	{ "EGL_KHR_image_base",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_image_base),								s_EGL_KHR_image_base								},
+	{ "EGL_KHR_lock_surface",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_lock_surface),								s_EGL_KHR_lock_surface								},
+	{ "EGL_KHR_lock_surface3",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_lock_surface3),							s_EGL_KHR_lock_surface3								},
+	{ "EGL_KHR_partial_update",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_partial_update),							s_EGL_KHR_partial_update							},
+	{ "EGL_KHR_reusable_sync",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_reusable_sync),							s_EGL_KHR_reusable_sync								},
+	{ "EGL_KHR_stream",										DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream),									s_EGL_KHR_stream									},
+	{ "EGL_KHR_stream_attrib",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_attrib),							s_EGL_KHR_stream_attrib								},
+	{ "EGL_KHR_stream_consumer_gltexture",					DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_consumer_gltexture),				s_EGL_KHR_stream_consumer_gltexture					},
+	{ "EGL_KHR_stream_cross_process_fd",					DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_cross_process_fd),					s_EGL_KHR_stream_cross_process_fd					},
+	{ "EGL_KHR_stream_fifo",								DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_fifo),								s_EGL_KHR_stream_fifo								},
+	{ "EGL_KHR_stream_producer_eglsurface",					DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_producer_eglsurface),				s_EGL_KHR_stream_producer_eglsurface				},
+	{ "EGL_KHR_swap_buffers_with_damage",					DE_LENGTH_OF_ARRAY(s_EGL_KHR_swap_buffers_with_damage),					s_EGL_KHR_swap_buffers_with_damage					},
+	{ "EGL_KHR_wait_sync",									DE_LENGTH_OF_ARRAY(s_EGL_KHR_wait_sync),								s_EGL_KHR_wait_sync									},
+	{ "EGL_MESA_drm_image",									DE_LENGTH_OF_ARRAY(s_EGL_MESA_drm_image),								s_EGL_MESA_drm_image								},
+	{ "EGL_MESA_image_dma_buf_export",						DE_LENGTH_OF_ARRAY(s_EGL_MESA_image_dma_buf_export),					s_EGL_MESA_image_dma_buf_export						},
+	{ "EGL_NOK_swap_region",								DE_LENGTH_OF_ARRAY(s_EGL_NOK_swap_region),								s_EGL_NOK_swap_region								},
+	{ "EGL_NOK_swap_region2",								DE_LENGTH_OF_ARRAY(s_EGL_NOK_swap_region2),								s_EGL_NOK_swap_region2								},
+	{ "EGL_NV_native_query",								DE_LENGTH_OF_ARRAY(s_EGL_NV_native_query),								s_EGL_NV_native_query								},
+	{ "EGL_NV_post_sub_buffer",								DE_LENGTH_OF_ARRAY(s_EGL_NV_post_sub_buffer),							s_EGL_NV_post_sub_buffer							},
+	{ "EGL_NV_stream_consumer_gltexture_yuv",				DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_consumer_gltexture_yuv),				s_EGL_NV_stream_consumer_gltexture_yuv				},
+	{ "EGL_NV_stream_metadata",								DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_metadata),							s_EGL_NV_stream_metadata							},
+	{ "EGL_NV_stream_reset",								DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_reset),								s_EGL_NV_stream_reset								},
+	{ "EGL_NV_stream_sync",									DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_sync),								s_EGL_NV_stream_sync								},
+	{ "EGL_NV_sync",										DE_LENGTH_OF_ARRAY(s_EGL_NV_sync),										s_EGL_NV_sync										},
+	{ "EGL_NV_system_time",									DE_LENGTH_OF_ARRAY(s_EGL_NV_system_time),								s_EGL_NV_system_time								},
+	{ "EGL_EXT_compositor",									DE_LENGTH_OF_ARRAY(s_EGL_EXT_compositor),								s_EGL_EXT_compositor								},
+	{ "GL_APPLE_copy_texture_levels",						DE_LENGTH_OF_ARRAY(s_GL_APPLE_copy_texture_levels),						s_GL_APPLE_copy_texture_levels						},
+	{ "GL_APPLE_framebuffer_multisample",					DE_LENGTH_OF_ARRAY(s_GL_APPLE_framebuffer_multisample),					s_GL_APPLE_framebuffer_multisample					},
+	{ "GL_APPLE_sync",										DE_LENGTH_OF_ARRAY(s_GL_APPLE_sync),									s_GL_APPLE_sync										},
+	{ "GL_EXT_discard_framebuffer",							DE_LENGTH_OF_ARRAY(s_GL_EXT_discard_framebuffer),						s_GL_EXT_discard_framebuffer						},
+	{ "GL_EXT_map_buffer_range",							DE_LENGTH_OF_ARRAY(s_GL_EXT_map_buffer_range),							s_GL_EXT_map_buffer_range							},
+	{ "GL_EXT_multi_draw_arrays",							DE_LENGTH_OF_ARRAY(s_GL_EXT_multi_draw_arrays),							s_GL_EXT_multi_draw_arrays							},
+	{ "GL_EXT_multisampled_render_to_texture",				DE_LENGTH_OF_ARRAY(s_GL_EXT_multisampled_render_to_texture),			s_GL_EXT_multisampled_render_to_texture				},
+	{ "GL_EXT_robustness",									DE_LENGTH_OF_ARRAY(s_GL_EXT_robustness),								s_GL_EXT_robustness									},
+	{ "GL_EXT_texture_storage",								DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_storage),							s_GL_EXT_texture_storage							},
+	{ "GL_IMG_multisampled_render_to_texture",				DE_LENGTH_OF_ARRAY(s_GL_IMG_multisampled_render_to_texture),			s_GL_IMG_multisampled_render_to_texture				},
+	{ "GL_IMG_user_clip_plane",								DE_LENGTH_OF_ARRAY(s_GL_IMG_user_clip_plane),							s_GL_IMG_user_clip_plane							},
+	{ "GL_NV_fence",										DE_LENGTH_OF_ARRAY(s_GL_NV_fence),										s_GL_NV_fence										},
+	{ "GL_OES_EGL_image",									DE_LENGTH_OF_ARRAY(s_GL_OES_EGL_image),									s_GL_OES_EGL_image									},
+	{ "GL_OES_blend_equation_separate",						DE_LENGTH_OF_ARRAY(s_GL_OES_blend_equation_separate),					s_GL_OES_blend_equation_separate					},
+	{ "GL_OES_blend_func_separate",							DE_LENGTH_OF_ARRAY(s_GL_OES_blend_func_separate),						s_GL_OES_blend_func_separate						},
+	{ "GL_OES_blend_subtract",								DE_LENGTH_OF_ARRAY(s_GL_OES_blend_subtract),							s_GL_OES_blend_subtract								},
+	{ "GL_OES_draw_texture",								DE_LENGTH_OF_ARRAY(s_GL_OES_draw_texture),								s_GL_OES_draw_texture								},
+	{ "GL_OES_fixed_point",									DE_LENGTH_OF_ARRAY(s_GL_OES_fixed_point),								s_GL_OES_fixed_point								},
+	{ "GL_OES_framebuffer_object",							DE_LENGTH_OF_ARRAY(s_GL_OES_framebuffer_object),						s_GL_OES_framebuffer_object							},
+	{ "GL_OES_mapbuffer",									DE_LENGTH_OF_ARRAY(s_GL_OES_mapbuffer),									s_GL_OES_mapbuffer									},
+	{ "GL_OES_matrix_palette",								DE_LENGTH_OF_ARRAY(s_GL_OES_matrix_palette),							s_GL_OES_matrix_palette								},
+	{ "GL_OES_point_size_array",							DE_LENGTH_OF_ARRAY(s_GL_OES_point_size_array),							s_GL_OES_point_size_array							},
+	{ "GL_OES_query_matrix",								DE_LENGTH_OF_ARRAY(s_GL_OES_query_matrix),								s_GL_OES_query_matrix								},
+	{ "GL_OES_single_precision",							DE_LENGTH_OF_ARRAY(s_GL_OES_single_precision),							s_GL_OES_single_precision							},
+	{ "GL_OES_texture_cube_map",							DE_LENGTH_OF_ARRAY(s_GL_OES_texture_cube_map),							s_GL_OES_texture_cube_map							},
+	{ "GL_OES_vertex_array_object",							DE_LENGTH_OF_ARRAY(s_GL_OES_vertex_array_object),						s_GL_OES_vertex_array_object						},
+	{ "GL_QCOM_driver_control",								DE_LENGTH_OF_ARRAY(s_GL_QCOM_driver_control),							s_GL_QCOM_driver_control							},
+	{ "GL_QCOM_extended_get",								DE_LENGTH_OF_ARRAY(s_GL_QCOM_extended_get),								s_GL_QCOM_extended_get								},
+	{ "GL_QCOM_extended_get2",								DE_LENGTH_OF_ARRAY(s_GL_QCOM_extended_get2),							s_GL_QCOM_extended_get2								},
+	{ "GL_QCOM_tiled_rendering",							DE_LENGTH_OF_ARRAY(s_GL_QCOM_tiled_rendering),							s_GL_QCOM_tiled_rendering							},
+	{ "GL_AMD_performance_monitor",							DE_LENGTH_OF_ARRAY(s_GL_AMD_performance_monitor),						s_GL_AMD_performance_monitor						},
+	{ "GL_ANGLE_framebuffer_blit",							DE_LENGTH_OF_ARRAY(s_GL_ANGLE_framebuffer_blit),						s_GL_ANGLE_framebuffer_blit							},
+	{ "GL_ANGLE_framebuffer_multisample",					DE_LENGTH_OF_ARRAY(s_GL_ANGLE_framebuffer_multisample),					s_GL_ANGLE_framebuffer_multisample					},
+	{ "GL_ANGLE_instanced_arrays",							DE_LENGTH_OF_ARRAY(s_GL_ANGLE_instanced_arrays),						s_GL_ANGLE_instanced_arrays							},
+	{ "GL_ANGLE_translated_shader_source",					DE_LENGTH_OF_ARRAY(s_GL_ANGLE_translated_shader_source),				s_GL_ANGLE_translated_shader_source					},
+	{ "GL_EXT_base_instance",								DE_LENGTH_OF_ARRAY(s_GL_EXT_base_instance),								s_GL_EXT_base_instance								},
+	{ "GL_EXT_blend_func_extended",							DE_LENGTH_OF_ARRAY(s_GL_EXT_blend_func_extended),						s_GL_EXT_blend_func_extended						},
+	{ "GL_EXT_buffer_storage",								DE_LENGTH_OF_ARRAY(s_GL_EXT_buffer_storage),							s_GL_EXT_buffer_storage								},
+	{ "GL_EXT_clear_texture",								DE_LENGTH_OF_ARRAY(s_GL_EXT_clear_texture),								s_GL_EXT_clear_texture								},
+	{ "GL_EXT_copy_image",									DE_LENGTH_OF_ARRAY(s_GL_EXT_copy_image),								s_GL_EXT_copy_image									},
+	{ "GL_EXT_debug_label",									DE_LENGTH_OF_ARRAY(s_GL_EXT_debug_label),								s_GL_EXT_debug_label								},
+	{ "GL_EXT_debug_marker",								DE_LENGTH_OF_ARRAY(s_GL_EXT_debug_marker),								s_GL_EXT_debug_marker								},
+	{ "GL_EXT_disjoint_timer_query",						DE_LENGTH_OF_ARRAY(s_GL_EXT_disjoint_timer_query),						s_GL_EXT_disjoint_timer_query						},
+	{ "GL_EXT_draw_buffers",								DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_buffers),								s_GL_EXT_draw_buffers								},
+	{ "GL_EXT_draw_buffers_indexed",						DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_buffers_indexed),						s_GL_EXT_draw_buffers_indexed						},
+	{ "GL_EXT_draw_elements_base_vertex",					DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_elements_base_vertex),					s_GL_EXT_draw_elements_base_vertex					},
+	{ "GL_EXT_draw_instanced",								DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_instanced),							s_GL_EXT_draw_instanced								},
+	{ "GL_EXT_draw_transform_feedback",						DE_LENGTH_OF_ARRAY(s_GL_EXT_draw_transform_feedback),					s_GL_EXT_draw_transform_feedback					},
+	{ "GL_EXT_external_buffer",								DE_LENGTH_OF_ARRAY(s_GL_EXT_external_buffer),							s_GL_EXT_external_buffer							},
+	{ "GL_EXT_geometry_shader",								DE_LENGTH_OF_ARRAY(s_GL_EXT_geometry_shader),							s_GL_EXT_geometry_shader							},
+	{ "GL_EXT_instanced_arrays",							DE_LENGTH_OF_ARRAY(s_GL_EXT_instanced_arrays),							s_GL_EXT_instanced_arrays							},
+	{ "GL_EXT_memory_object",								DE_LENGTH_OF_ARRAY(s_GL_EXT_memory_object),								s_GL_EXT_memory_object								},
+	{ "GL_EXT_memory_object_fd",							DE_LENGTH_OF_ARRAY(s_GL_EXT_memory_object_fd),							s_GL_EXT_memory_object_fd							},
+	{ "GL_EXT_memory_object_win32",							DE_LENGTH_OF_ARRAY(s_GL_EXT_memory_object_win32),						s_GL_EXT_memory_object_win32						},
+	{ "GL_EXT_multi_draw_indirect",							DE_LENGTH_OF_ARRAY(s_GL_EXT_multi_draw_indirect),						s_GL_EXT_multi_draw_indirect						},
+	{ "GL_EXT_multiview_draw_buffers",						DE_LENGTH_OF_ARRAY(s_GL_EXT_multiview_draw_buffers),					s_GL_EXT_multiview_draw_buffers						},
+	{ "GL_EXT_occlusion_query_boolean",						DE_LENGTH_OF_ARRAY(s_GL_EXT_occlusion_query_boolean),					s_GL_EXT_occlusion_query_boolean					},
+	{ "GL_EXT_polygon_offset_clamp",						DE_LENGTH_OF_ARRAY(s_GL_EXT_polygon_offset_clamp),						s_GL_EXT_polygon_offset_clamp						},
+	{ "GL_EXT_primitive_bounding_box",						DE_LENGTH_OF_ARRAY(s_GL_EXT_primitive_bounding_box),					s_GL_EXT_primitive_bounding_box						},
+	{ "GL_EXT_raster_multisample",							DE_LENGTH_OF_ARRAY(s_GL_EXT_raster_multisample),						s_GL_EXT_raster_multisample							},
+	{ "GL_EXT_semaphore",									DE_LENGTH_OF_ARRAY(s_GL_EXT_semaphore),									s_GL_EXT_semaphore									},
+	{ "GL_EXT_semaphore_fd",								DE_LENGTH_OF_ARRAY(s_GL_EXT_semaphore_fd),								s_GL_EXT_semaphore_fd								},
+	{ "GL_EXT_semaphore_win32",								DE_LENGTH_OF_ARRAY(s_GL_EXT_semaphore_win32),							s_GL_EXT_semaphore_win32							},
+	{ "GL_EXT_separate_shader_objects",						DE_LENGTH_OF_ARRAY(s_GL_EXT_separate_shader_objects),					s_GL_EXT_separate_shader_objects					},
+	{ "GL_EXT_shader_pixel_local_storage2",					DE_LENGTH_OF_ARRAY(s_GL_EXT_shader_pixel_local_storage2),				s_GL_EXT_shader_pixel_local_storage2				},
+	{ "GL_EXT_sparse_texture",								DE_LENGTH_OF_ARRAY(s_GL_EXT_sparse_texture),							s_GL_EXT_sparse_texture								},
+	{ "GL_EXT_tessellation_shader",							DE_LENGTH_OF_ARRAY(s_GL_EXT_tessellation_shader),						s_GL_EXT_tessellation_shader						},
+	{ "GL_EXT_texture_border_clamp",						DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_border_clamp),						s_GL_EXT_texture_border_clamp						},
+	{ "GL_EXT_texture_buffer",								DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_buffer),							s_GL_EXT_texture_buffer								},
+	{ "GL_EXT_texture_filter_minmax",						DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_filter_minmax),						s_GL_EXT_texture_filter_minmax						},
+	{ "GL_EXT_texture_view",								DE_LENGTH_OF_ARRAY(s_GL_EXT_texture_view),								s_GL_EXT_texture_view								},
+	{ "GL_EXT_win32_keyed_mutex",							DE_LENGTH_OF_ARRAY(s_GL_EXT_win32_keyed_mutex),							s_GL_EXT_win32_keyed_mutex							},
+	{ "GL_EXT_window_rectangles",							DE_LENGTH_OF_ARRAY(s_GL_EXT_window_rectangles),							s_GL_EXT_window_rectangles							},
+	{ "GL_IMG_bindless_texture",							DE_LENGTH_OF_ARRAY(s_GL_IMG_bindless_texture),							s_GL_IMG_bindless_texture							},
+	{ "GL_IMG_framebuffer_downsample",						DE_LENGTH_OF_ARRAY(s_GL_IMG_framebuffer_downsample),					s_GL_IMG_framebuffer_downsample						},
+	{ "GL_INTEL_framebuffer_CMAA",							DE_LENGTH_OF_ARRAY(s_GL_INTEL_framebuffer_CMAA),						s_GL_INTEL_framebuffer_CMAA							},
+	{ "GL_INTEL_performance_query",							DE_LENGTH_OF_ARRAY(s_GL_INTEL_performance_query),						s_GL_INTEL_performance_query						},
+	{ "GL_KHR_blend_equation_advanced",						DE_LENGTH_OF_ARRAY(s_GL_KHR_blend_equation_advanced),					s_GL_KHR_blend_equation_advanced					},
+	{ "GL_KHR_debug",										DE_LENGTH_OF_ARRAY(s_GL_KHR_debug),										s_GL_KHR_debug										},
+	{ "GL_KHR_robustness",									DE_LENGTH_OF_ARRAY(s_GL_KHR_robustness),								s_GL_KHR_robustness									},
+	{ "GL_NV_bindless_texture",								DE_LENGTH_OF_ARRAY(s_GL_NV_bindless_texture),							s_GL_NV_bindless_texture							},
+	{ "GL_NV_blend_equation_advanced",						DE_LENGTH_OF_ARRAY(s_GL_NV_blend_equation_advanced),					s_GL_NV_blend_equation_advanced						},
+	{ "GL_NV_conditional_render",							DE_LENGTH_OF_ARRAY(s_GL_NV_conditional_render),							s_GL_NV_conditional_render							},
+	{ "GL_NV_conservative_raster",							DE_LENGTH_OF_ARRAY(s_GL_NV_conservative_raster),						s_GL_NV_conservative_raster							},
+	{ "GL_NV_conservative_raster_pre_snap_triangles",		DE_LENGTH_OF_ARRAY(s_GL_NV_conservative_raster_pre_snap_triangles),		s_GL_NV_conservative_raster_pre_snap_triangles		},
+	{ "GL_NV_copy_buffer",									DE_LENGTH_OF_ARRAY(s_GL_NV_copy_buffer),								s_GL_NV_copy_buffer									},
+	{ "GL_NV_coverage_sample",								DE_LENGTH_OF_ARRAY(s_GL_NV_coverage_sample),							s_GL_NV_coverage_sample								},
+	{ "GL_NV_draw_buffers",									DE_LENGTH_OF_ARRAY(s_GL_NV_draw_buffers),								s_GL_NV_draw_buffers								},
+	{ "GL_NV_draw_instanced",								DE_LENGTH_OF_ARRAY(s_GL_NV_draw_instanced),								s_GL_NV_draw_instanced								},
+	{ "GL_NV_draw_vulkan_image",							DE_LENGTH_OF_ARRAY(s_GL_NV_draw_vulkan_image),							s_GL_NV_draw_vulkan_image							},
+	{ "GL_NV_fragment_coverage_to_color",					DE_LENGTH_OF_ARRAY(s_GL_NV_fragment_coverage_to_color),					s_GL_NV_fragment_coverage_to_color					},
+	{ "GL_NV_framebuffer_blit",								DE_LENGTH_OF_ARRAY(s_GL_NV_framebuffer_blit),							s_GL_NV_framebuffer_blit							},
+	{ "GL_NV_framebuffer_mixed_samples",					DE_LENGTH_OF_ARRAY(s_GL_NV_framebuffer_mixed_samples),					s_GL_NV_framebuffer_mixed_samples					},
+	{ "GL_NV_framebuffer_multisample",						DE_LENGTH_OF_ARRAY(s_GL_NV_framebuffer_multisample),					s_GL_NV_framebuffer_multisample						},
+	{ "GL_NV_gpu_shader5",									DE_LENGTH_OF_ARRAY(s_GL_NV_gpu_shader5),								s_GL_NV_gpu_shader5									},
+	{ "GL_NV_instanced_arrays",								DE_LENGTH_OF_ARRAY(s_GL_NV_instanced_arrays),							s_GL_NV_instanced_arrays							},
+	{ "GL_NV_internalformat_sample_query",					DE_LENGTH_OF_ARRAY(s_GL_NV_internalformat_sample_query),				s_GL_NV_internalformat_sample_query					},
+	{ "GL_NV_non_square_matrices",							DE_LENGTH_OF_ARRAY(s_GL_NV_non_square_matrices),						s_GL_NV_non_square_matrices							},
+	{ "GL_NV_path_rendering",								DE_LENGTH_OF_ARRAY(s_GL_NV_path_rendering),								s_GL_NV_path_rendering								},
+	{ "GL_NV_polygon_mode",									DE_LENGTH_OF_ARRAY(s_GL_NV_polygon_mode),								s_GL_NV_polygon_mode								},
+	{ "GL_NV_read_buffer",									DE_LENGTH_OF_ARRAY(s_GL_NV_read_buffer),								s_GL_NV_read_buffer									},
+	{ "GL_NV_sample_locations",								DE_LENGTH_OF_ARRAY(s_GL_NV_sample_locations),							s_GL_NV_sample_locations							},
+	{ "GL_NV_viewport_array",								DE_LENGTH_OF_ARRAY(s_GL_NV_viewport_array),								s_GL_NV_viewport_array								},
+	{ "GL_NV_viewport_swizzle",								DE_LENGTH_OF_ARRAY(s_GL_NV_viewport_swizzle),							s_GL_NV_viewport_swizzle							},
+	{ "GL_OES_copy_image",									DE_LENGTH_OF_ARRAY(s_GL_OES_copy_image),								s_GL_OES_copy_image									},
+	{ "GL_OES_draw_buffers_indexed",						DE_LENGTH_OF_ARRAY(s_GL_OES_draw_buffers_indexed),						s_GL_OES_draw_buffers_indexed						},
+	{ "GL_OES_draw_elements_base_vertex",					DE_LENGTH_OF_ARRAY(s_GL_OES_draw_elements_base_vertex),					s_GL_OES_draw_elements_base_vertex					},
+	{ "GL_OES_geometry_shader",								DE_LENGTH_OF_ARRAY(s_GL_OES_geometry_shader),							s_GL_OES_geometry_shader							},
+	{ "GL_OES_get_program_binary",							DE_LENGTH_OF_ARRAY(s_GL_OES_get_program_binary),						s_GL_OES_get_program_binary							},
+	{ "GL_OES_primitive_bounding_box",						DE_LENGTH_OF_ARRAY(s_GL_OES_primitive_bounding_box),					s_GL_OES_primitive_bounding_box						},
+	{ "GL_OES_sample_shading",								DE_LENGTH_OF_ARRAY(s_GL_OES_sample_shading),							s_GL_OES_sample_shading								},
+	{ "GL_OES_tessellation_shader",							DE_LENGTH_OF_ARRAY(s_GL_OES_tessellation_shader),						s_GL_OES_tessellation_shader						},
+	{ "GL_OES_texture_3D",									DE_LENGTH_OF_ARRAY(s_GL_OES_texture_3D),								s_GL_OES_texture_3D									},
+	{ "GL_OES_texture_border_clamp",						DE_LENGTH_OF_ARRAY(s_GL_OES_texture_border_clamp),						s_GL_OES_texture_border_clamp						},
+	{ "GL_OES_texture_buffer",								DE_LENGTH_OF_ARRAY(s_GL_OES_texture_buffer),							s_GL_OES_texture_buffer								},
+	{ "GL_OES_texture_storage_multisample_2d_array",		DE_LENGTH_OF_ARRAY(s_GL_OES_texture_storage_multisample_2d_array),		s_GL_OES_texture_storage_multisample_2d_array		},
+	{ "GL_OES_texture_view",								DE_LENGTH_OF_ARRAY(s_GL_OES_texture_view),								s_GL_OES_texture_view								},
+	{ "GL_OES_viewport_array",								DE_LENGTH_OF_ARRAY(s_GL_OES_viewport_array),							s_GL_OES_viewport_array								},
+	{ "GL_OVR_multiview",									DE_LENGTH_OF_ARRAY(s_GL_OVR_multiview),									s_GL_OVR_multiview									},
+	{ "GL_OVR_multiview_multisampled_render_to_texture",	DE_LENGTH_OF_ARRAY(s_GL_OVR_multiview_multisampled_render_to_texture),	s_GL_OVR_multiview_multisampled_render_to_texture	},
+	{ "GL_QCOM_alpha_test",									DE_LENGTH_OF_ARRAY(s_GL_QCOM_alpha_test),								s_GL_QCOM_alpha_test								},
+	{ "GL_QCOM_framebuffer_foveated",						DE_LENGTH_OF_ARRAY(s_GL_QCOM_framebuffer_foveated),						s_GL_QCOM_framebuffer_foveated						},
+	{ "GL_QCOM_shader_framebuffer_fetch_noncoherent",		DE_LENGTH_OF_ARRAY(s_GL_QCOM_shader_framebuffer_fetch_noncoherent),		s_GL_QCOM_shader_framebuffer_fetch_noncoherent		},
 };
diff --git a/modules/egl/teglRobustnessTests.cpp b/modules/egl/teglRobustnessTests.cpp
index e8a77f4..452777f 100644
--- a/modules/egl/teglRobustnessTests.cpp
+++ b/modules/egl/teglRobustnessTests.cpp
@@ -173,6 +173,13 @@
 				iter++;
 				break;
 
+			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
+				iter++;
+				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, "
+								 << eglResetNotificationStrategyToString(*iter) << ", ";
+				iter++;
+				break;
+
 			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
 				iter++;
 				attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";
@@ -1904,6 +1911,61 @@
 	}
 };
 
+class InvalidNotificationEnumCase : public RobustnessTestCase
+{
+public:
+	InvalidNotificationEnumCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+		: RobustnessTestCase (eglTestCtx, name, description) {}
+
+	TestCase::IterateResult	iterate	(void)
+	{
+		TestLog&		log		=	m_testCtx.getLog();
+		const Library&	egl		=	m_eglTestCtx.getLibrary();
+		bool			isOk	=	true;
+
+		log << tcu::TestLog::Message
+			<< "EGL_BAD_ATTRIBUTE is generated if EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR is used with EGL versions <= 1.4\n\n"
+			<< tcu::TestLog::EndMessage;
+
+		const EGLint attribList[] =
+		{
+			EGL_CONTEXT_CLIENT_VERSION, 3,
+			EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+			EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_NO_RESET_NOTIFICATION,
+			EGL_NONE
+		};
+
+		if (eglu::getVersion(egl, m_eglDisplay) >= eglu::Version(1, 5))
+		{
+			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL version to be under 1.5");
+			return STOP;
+		}
+
+		logAttribList(m_eglTestCtx, attribList);
+		EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
+
+		const EGLenum error = egl.getError();
+		if (error != EGL_BAD_ATTRIBUTE)
+		{
+			log << TestLog::Message
+				<< "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
+				<< TestLog::EndMessage;
+
+			isOk = false;
+		}
+
+		if (context != EGL_NO_CONTEXT)
+			egl.destroyContext(m_eglDisplay, context);
+
+		if (isOk)
+			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+		else
+			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+		return STOP;
+	}
+};
+
 class SharedContextResetCase : public RobustnessTestCase
 {
 public:
@@ -2417,8 +2479,9 @@
 
 	// invalid context creation cases
 	{
-		negativeContextTestGroup->addChild(new InvalidContextCase		(eglTestCtx, "invalid_robust_context_creation",			"Create a non-robust context but specify a reset notification strategy"));
-		negativeContextTestGroup->addChild(new InvalidShareContextCase	(eglTestCtx, "invalid_robust_shared_context_creation",	"Create a context share group with conflicting reset notification strategies"));
+		negativeContextTestGroup->addChild(new InvalidContextCase			(eglTestCtx, "invalid_robust_context_creation",			"Create a non-robust context but specify a reset notification strategy"));
+		negativeContextTestGroup->addChild(new InvalidShareContextCase		(eglTestCtx, "invalid_robust_shared_context_creation",	"Create a context share group with conflicting reset notification strategies"));
+		negativeContextTestGroup->addChild(new InvalidNotificationEnumCase	(eglTestCtx, "invalid_notification_strategy_enum",		"Create a robust context using EGL 1.5 only enum with EGL versions <= 1.4" ));
 	}
 
 	shadersTestGroup->addChild(infiniteLoopTestGroup);
diff --git a/modules/egl/teglTestPackage.cpp b/modules/egl/teglTestPackage.cpp
index 91a374b..91e1a4c 100644
--- a/modules/egl/teglTestPackage.cpp
+++ b/modules/egl/teglTestPackage.cpp
@@ -65,6 +65,7 @@
 #include "teglMutableRenderBufferTests.hpp"
 #include "teglGetFrameTimestampsTests.hpp"
 #include "teglRobustnessTests.hpp"
+#include "teglWideColorTests.hpp"
 
 namespace deqp
 {
@@ -142,6 +143,7 @@
 		addChild(new MutableRenderBufferTests	(m_eglTestCtx));
 		addChild(createGetFrameTimestampsTests	(m_eglTestCtx));
 		addChild(createRobustnessTests			(m_eglTestCtx));
+		addChild(createWideColorTests			(m_eglTestCtx));
 	}
 };
 
diff --git a/modules/egl/teglWideColorTests.cpp b/modules/egl/teglWideColorTests.cpp
new file mode 100644
index 0000000..20d4fff
--- /dev/null
+++ b/modules/egl/teglWideColorTests.cpp
@@ -0,0 +1,1353 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Test KHR_wide_color
+ *//*--------------------------------------------------------------------*/
+
+#include "teglWideColorTests.hpp"
+
+#include "tcuImageCompare.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuSurface.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "egluNativeWindow.hpp"
+#include "egluStrUtil.hpp"
+#include "egluUtil.hpp"
+#include "egluConfigFilter.hpp"
+
+#include "eglwLibrary.hpp"
+#include "eglwEnums.hpp"
+
+#include "gluDefs.hpp"
+#include "gluRenderContext.hpp"
+#include "gluShaderProgram.hpp"
+
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+
+#include "deMath.h"
+#include "deRandom.hpp"
+#include "deString.h"
+#include "deStringUtil.hpp"
+
+#include <string>
+#include <vector>
+#include <sstream>
+
+using std::string;
+using std::vector;
+using glw::GLubyte;
+using glw::GLfloat;
+using tcu::IVec2;
+
+using namespace eglw;
+
+namespace deqp
+{
+namespace egl
+{
+namespace
+{
+
+typedef tcu::Vec4 Color;
+
+class GLES2Renderer;
+
+class ReferenceRenderer;
+
+class WideColorTests : public TestCaseGroup
+{
+public:
+						WideColorTests		(EglTestContext& eglTestCtx);
+	void				init				(void);
+
+private:
+						WideColorTests		(const WideColorTests&);
+	WideColorTests&		operator=			(const WideColorTests&);
+};
+
+class WideColorTest : public TestCase
+{
+public:
+	enum DrawType
+	{
+		DRAWTYPE_GLES2_CLEAR,
+		DRAWTYPE_GLES2_RENDER
+	};
+
+						WideColorTest				(EglTestContext& eglTestCtx, const char* name, const char* description);
+						~WideColorTest				(void);
+
+	void				init						(void);
+	void				deinit						(void);
+	void				checkPixelFloatSupport		(void);
+	void				checkColorSpaceSupport		(void);
+	void				checkDisplayP3Support		(void);
+	void				checkDisplayP3LinearSupport (void);
+	void				check1010102Support			(void);
+	void				checkFP16Support			(void);
+	void				checkSCRGBSupport			(void);
+	void				checkSCRGBLinearSupport		(void);
+
+protected:
+	void				initEGLSurface				(EGLConfig config);
+	void				initEGLContext				(EGLConfig config);
+
+	EGLDisplay			m_eglDisplay;
+	glw::Functions		m_gl;
+};
+
+struct ColoredRect
+{
+public:
+			ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_);
+	IVec2	bottomLeft;
+	IVec2	topRight;
+	Color	color;
+};
+
+ColoredRect::ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_)
+	: bottomLeft	(bottomLeft_)
+	, topRight		(topRight_)
+	, color			(color_)
+{
+}
+
+void clearColorScreen (const glw::Functions& gl, const Color& clearColor)
+{
+	gl.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
+	gl.clear(GL_COLOR_BUFFER_BIT);
+}
+
+float windowToDeviceCoordinates (int x, int length)
+{
+	return (2.0f * float(x) / float(length)) - 1.0f;
+}
+
+class GLES2Renderer
+{
+public:
+							GLES2Renderer		(const glw::Functions& gl, int width, int height);
+							~GLES2Renderer		(void);
+	void					render				(const ColoredRect& coloredRect) const;
+
+private:
+							GLES2Renderer		(const GLES2Renderer&);
+	GLES2Renderer&			operator=			(const GLES2Renderer&);
+
+	const glw::Functions&	m_gl;
+	glu::ShaderProgram		m_glProgram;
+	glw::GLuint				m_coordLoc;
+	glw::GLuint				m_colorLoc;
+	glw::GLuint				m_bufWidth;
+	glw::GLuint				m_bufHeight;
+};
+
+// generate sources for vertex and fragment buffer
+glu::ProgramSources getSources (void)
+{
+	const char* const vertexShaderSource =
+		"attribute mediump vec2 a_pos;\n"
+		"attribute mediump vec4 a_color;\n"
+		"varying mediump vec4 v_color;\n"
+		"void main(void)\n"
+		"{\n"
+		"\tv_color = a_color;\n"
+		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
+		"}";
+
+	const char* const fragmentShaderSource =
+		"varying mediump vec4 v_color;\n"
+		"void main(void)\n"
+		"{\n"
+		"\tgl_FragColor = v_color;\n"
+		"}";
+
+	return glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource);
+}
+
+GLES2Renderer::GLES2Renderer (const glw::Functions& gl, int width, int height)
+	: m_gl				(gl)
+	, m_glProgram		(gl, getSources())
+	, m_coordLoc		((glw::GLuint)-1)
+	, m_colorLoc		((glw::GLuint)-1)
+	, m_bufWidth		(width)
+	, m_bufHeight		(height)
+{
+	m_colorLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_color");
+	m_coordLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_pos");
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to get attribute locations");
+}
+
+GLES2Renderer::~GLES2Renderer (void)
+{
+}
+
+void GLES2Renderer::render (const struct ColoredRect &coloredRect) const
+{
+	const float x1 = windowToDeviceCoordinates(coloredRect.bottomLeft.x(), m_bufWidth);
+	const float y1 = windowToDeviceCoordinates(coloredRect.bottomLeft.y(), m_bufHeight);
+	const float x2 = windowToDeviceCoordinates(coloredRect.topRight.x(), m_bufWidth);
+	const float y2 = windowToDeviceCoordinates(coloredRect.topRight.y(), m_bufHeight);
+
+	const glw::GLfloat coords[] =
+	{
+		x1, y1, 0.0f, 1.0f,
+		x1, y2, 0.0f, 1.0f,
+		x2, y2, 0.0f, 1.0f,
+
+		x2, y2, 0.0f, 1.0f,
+		x2, y1, 0.0f, 1.0f,
+		x1, y1, 0.0f, 1.0f
+	};
+
+	const glw::GLfloat colors[] =
+	{
+		coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
+		coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
+		coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
+
+		coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
+		coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
+		coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
+	};
+
+	m_gl.useProgram(m_glProgram.getProgram());
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
+
+	m_gl.enableVertexAttribArray(m_coordLoc);
+	m_gl.enableVertexAttribArray(m_colorLoc);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to enable attributes");
+
+	m_gl.vertexAttribPointer(m_coordLoc, 4, GL_FLOAT, GL_FALSE, 0, coords);
+	m_gl.vertexAttribPointer(m_colorLoc, 4, GL_FLOAT, GL_TRUE, 0, colors);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to set attribute pointers");
+
+	m_gl.drawArrays(GL_TRIANGLES, 0, DE_LENGTH_OF_ARRAY(coords)/4);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays(), failed");
+
+	m_gl.disableVertexAttribArray(m_coordLoc);
+	m_gl.disableVertexAttribArray(m_colorLoc);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to disable attributes");
+
+	m_gl.useProgram(0);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
+}
+
+class ReferenceRenderer
+{
+public:
+						ReferenceRenderer		(void);
+private:
+						ReferenceRenderer		(const ReferenceRenderer&);
+	ReferenceRenderer&	operator=				(const ReferenceRenderer&);
+};
+
+ReferenceRenderer::ReferenceRenderer (void)
+{
+}
+
+WideColorTest::WideColorTest (EglTestContext& eglTestCtx, const char* name, const char* description)
+	: TestCase				 (eglTestCtx, name, description)
+	, m_eglDisplay			 (EGL_NO_DISPLAY)
+{
+}
+
+WideColorTest::~WideColorTest (void)
+{
+	deinit();
+}
+
+void WideColorTest::init (void)
+{
+	m_eglDisplay		= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
+
+	m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0));
+}
+
+void WideColorTest::checkPixelFloatSupport (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_pixel_format_float"))
+		TCU_THROW(NotSupportedError, "EGL_EXT_pixel_format_float is not supported");
+}
+
+void WideColorTest::checkColorSpaceSupport (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_KHR_gl_colorspace"))
+		TCU_THROW(NotSupportedError, "EGL_KHR_gl_colorspace is not supported");
+}
+
+void WideColorTest::checkDisplayP3Support (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_display_p3"))
+		TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_display_p3 is not supported");
+}
+
+void WideColorTest::checkDisplayP3LinearSupport (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"))
+		TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_display_p3_linear is not supported");
+}
+
+void WideColorTest::checkSCRGBSupport (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_scrgb"))
+		TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_scrgb is not supported");
+}
+
+void WideColorTest::checkSCRGBLinearSupport (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_scrgb_linear"))
+		TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_scrgb_linear is not supported");
+}
+
+void WideColorTest::check1010102Support (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+	tcu::TestLog&	log	= m_testCtx.getLog();
+
+	const EGLint attribList[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_WINDOW_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					10,
+		EGL_GREEN_SIZE,					10,
+		EGL_BLUE_SIZE,					10,
+		EGL_ALPHA_SIZE,					2,
+		EGL_NONE,						EGL_NONE
+	};
+	EGLint numConfigs = 0;
+	EGLConfig config;
+
+	// Query from EGL implementation
+	EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &attribList[0], DE_NULL, 0, &numConfigs));
+
+	if (numConfigs <= 0)
+	{
+		log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
+		TCU_THROW(NotSupportedError, "10:10:10:2 pixel format is not supported");
+	}
+
+	log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
+
+	EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &attribList[0], &config, 1, &numConfigs));
+	if (numConfigs > 1)
+	{
+		log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
+		TCU_FAIL("Too many configs returned");
+	}
+
+	EGLint components[4];
+
+	EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &components[0]));
+	EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &components[1]));
+	EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &components[2]));
+	EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &components[3]));
+
+	TCU_CHECK_MSG(components[0] == 10, "Missing 10bit deep red channel");
+	TCU_CHECK_MSG(components[1] == 10, "Missing 10bit deep green channel");
+	TCU_CHECK_MSG(components[2] == 10, "Missing 10bit deep blue channel");
+	TCU_CHECK_MSG(components[3] == 2, "Missing 2bit deep alpha channel");
+}
+
+void WideColorTest::checkFP16Support (void)
+{
+	const Library&	egl			= m_eglTestCtx.getLibrary();
+	tcu::TestLog&	log			= m_testCtx.getLog();
+	EGLint			numConfigs	= 0;
+	EGLConfig		config;
+
+	const EGLint attribList[] =
+	{
+		EGL_SURFACE_TYPE,			  EGL_WINDOW_BIT,
+		EGL_RENDERABLE_TYPE,		  EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,				  16,
+		EGL_GREEN_SIZE,				  16,
+		EGL_BLUE_SIZE,				  16,
+		EGL_ALPHA_SIZE,				  16,
+		EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+		EGL_NONE,					  EGL_NONE
+	};
+
+	// Query from EGL implementation
+	EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &attribList[0], DE_NULL, 0, &numConfigs));
+
+	if (numConfigs <= 0)
+	{
+		log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
+		TCU_THROW(NotSupportedError, "10:10:10:2 pixel format is not supported");
+	}
+
+	log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
+
+	EGLBoolean success = egl.chooseConfig(m_eglDisplay, &attribList[0], &config, 1, &numConfigs);
+	if (success != EGL_TRUE)
+	{
+		log << tcu::TestLog::Message << "Fail, eglChooseConfig returned an error." << tcu::TestLog::EndMessage;
+		TCU_FAIL("eglChooseConfig failed");
+	}
+	if (numConfigs > 1)
+	{
+		log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
+		TCU_FAIL("Too many configs returned");
+	}
+
+	EGLint components[4];
+
+	success = egl.getConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &components[0]);
+	TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
+	EGLU_CHECK(egl);
+	success = egl.getConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &components[1]);
+	TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
+	EGLU_CHECK(egl);
+	success = egl.getConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &components[2]);
+	TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
+	EGLU_CHECK(egl);
+	success = egl.getConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
+	TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
+	EGLU_CHECK(egl);
+
+	TCU_CHECK_MSG(components[0] == 16, "Missing 16bit deep red channel");
+	TCU_CHECK_MSG(components[1] == 16, "Missing 16bit deep green channel");
+	TCU_CHECK_MSG(components[2] == 16, "Missing 16bit deep blue channel");
+	TCU_CHECK_MSG(components[3] == 16, "Missing 16bit deep alpha channel");
+}
+
+void WideColorTest::deinit (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+
+	if (m_eglDisplay != EGL_NO_DISPLAY)
+	{
+		egl.terminate(m_eglDisplay);
+		m_eglDisplay = EGL_NO_DISPLAY;
+	}
+}
+
+class WideColorFP16Test : public WideColorTest
+{
+public:
+						WideColorFP16Test		(EglTestContext& eglTestCtx, const char* name, const char* description);
+
+	void				init					(void);
+	void				executeTest				(void);
+	IterateResult		iterate					(void);
+};
+
+WideColorFP16Test::WideColorFP16Test (EglTestContext&	eglTestCtx,
+									  const char*		name,
+									  const char*		description)
+	: WideColorTest(eglTestCtx, name, description)
+{
+}
+
+
+void WideColorFP16Test::executeTest (void)
+{
+	checkPixelFloatSupport();
+	checkFP16Support();
+}
+
+TestCase::IterateResult WideColorFP16Test::iterate (void)
+{
+	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+	executeTest();
+	return STOP;
+}
+
+void WideColorFP16Test::init (void)
+{
+	WideColorTest::init();
+}
+
+class WideColor1010102Test : public WideColorTest
+{
+public:
+						WideColor1010102Test	(EglTestContext&	eglTestCtx,
+												 const char*		name,
+												 const char*		description);
+
+	void				executeTest				(void);
+	IterateResult		iterate					(void);
+};
+
+WideColor1010102Test::WideColor1010102Test (EglTestContext& eglTestCtx, const char* name, const char* description)
+	: WideColorTest(eglTestCtx, name, description)
+{
+}
+
+void WideColor1010102Test::executeTest (void)
+{
+	check1010102Support();
+}
+
+TestCase::IterateResult WideColor1010102Test::iterate (void)
+{
+	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+	executeTest();
+	return STOP;
+}
+
+struct Iteration
+{
+	float	start;
+	float	increment;
+	int		iterationCount;
+	Iteration(float s, float i, int c)
+		: start(s), increment(i), iterationCount(c) {}
+};
+
+class WideColorSurfaceTest : public WideColorTest
+{
+public:
+						WideColorSurfaceTest	(EglTestContext&				eglTestCtx,
+												 const char*					name,
+												 const char*					description,
+												 const EGLint*					attribList,
+												 EGLint							colorSpace,
+												 const std::vector<Iteration>&	iterations);
+
+	void				init					(void);
+	void				executeTest				(void);
+	IterateResult		iterate					(void);
+
+protected:
+	void				readPixels				(const glw::Functions& gl, float* dataPtr);
+	void				readPixels				(const glw::Functions& gl, deUint32* dataPtr);
+	void				readPixels				(const glw::Functions& gl, deUint8* dataPtr);
+	deUint32			expectedUint10			(float reference);
+	deUint32			expectedUint2			(float reference);
+	deUint8				expectedUint8			(float reference);
+	deUint8				expectedAlpha8			(float reference);
+	bool				checkWithThreshold8		(deUint8 value, deUint8 reference, deUint8 threshold = 1);
+	bool				checkWithThreshold10	(deUint32 value, deUint32 reference, deUint32 threshold = 1);
+	bool				checkWithThresholdFloat (float value, float reference, float threshold);
+	void				doClearTest				(EGLSurface surface);
+	void				testPixels				(float reference, float increment);
+	void				writeEglConfig			(EGLConfig config);
+
+private:
+	std::vector<EGLint>					m_attribList;
+	EGLConfig							m_eglConfig;
+	EGLint								m_surfaceType;
+	EGLint								m_componentType;
+	EGLint								m_redSize;
+	EGLint								m_colorSpace;
+	const std::vector<struct Iteration> m_iterations;
+	std::stringstream					m_debugLog;
+};
+
+WideColorSurfaceTest::WideColorSurfaceTest (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint* attribList, EGLint colorSpace, const std::vector<struct Iteration>& iterations)
+	: WideColorTest		(eglTestCtx, name, description)
+	, m_colorSpace		(colorSpace)
+	, m_iterations		(iterations)
+{
+	deUint32 idx = 0;
+	while (attribList[idx] != EGL_NONE)
+	{
+		if (attribList[idx] == EGL_COLOR_COMPONENT_TYPE_EXT)
+		{
+			m_componentType = attribList[idx + 1];
+		}
+		else if (attribList[idx] == EGL_SURFACE_TYPE)
+		{
+			m_surfaceType = attribList[idx+1];
+		}
+		else if (attribList[idx] == EGL_RED_SIZE)
+		{
+			m_redSize = attribList[idx + 1];
+		}
+		m_attribList.push_back(attribList[idx++]);
+		m_attribList.push_back(attribList[idx++]);
+	}
+	m_attribList.push_back(EGL_NONE);
+}
+
+void WideColorSurfaceTest::init (void)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+	tcu::TestLog&	log	= m_testCtx.getLog();
+
+	WideColorTest::init();
+
+	// Only check for pixel format required for this specific run
+	// If not available, check will abort test with "NotSupported"
+	switch (m_redSize)
+	{
+		case 10:
+			check1010102Support();
+			break;
+		case 16:
+			checkPixelFloatSupport();
+			checkFP16Support();
+			break;
+	}
+
+	if (m_colorSpace != EGL_NONE && !eglu::hasExtension(egl, m_eglDisplay, "EGL_KHR_gl_colorspace"))
+		TCU_THROW(NotSupportedError, "EGL_KHR_gl_colorspace is not supported");
+
+	switch (m_colorSpace) {
+		case EGL_GL_COLORSPACE_SRGB_KHR:
+			checkColorSpaceSupport();
+			break;
+		case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
+			checkDisplayP3Support();
+			break;
+		case EGL_GL_COLORSPACE_SCRGB_EXT:
+			checkSCRGBSupport();
+			break;
+		case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
+			checkSCRGBLinearSupport();
+			break;
+		default:
+			break;
+	}
+
+	EGLint numConfigs = 0;
+
+	// Query from EGL implementation
+	EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &m_attribList[0], DE_NULL, 0, &numConfigs));
+
+	if (numConfigs <= 0)
+	{
+		log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
+		TCU_FAIL("No configs returned");
+	}
+
+	log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
+
+	EGLBoolean success = egl.chooseConfig(m_eglDisplay, &m_attribList[0], &m_eglConfig, 1, &numConfigs);
+	if (success != EGL_TRUE)
+	{
+		log << tcu::TestLog::Message << "Fail, eglChooseConfig returned an error." << tcu::TestLog::EndMessage;
+		TCU_FAIL("eglChooseConfig failed");
+	}
+	if (numConfigs > 1)
+	{
+		log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
+		TCU_FAIL("Too many configs returned");
+	}
+
+	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+
+	writeEglConfig(m_eglConfig);
+
+}
+
+void WideColorSurfaceTest::readPixels (const glw::Functions& gl, float* dataPtr)
+{
+	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, dataPtr);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with floats");
+}
+
+void WideColorSurfaceTest::readPixels (const glw::Functions& gl, deUint32 *dataPtr)
+{
+	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, dataPtr);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with RGBA_1010102 (32bits)");
+}
+
+void WideColorSurfaceTest::readPixels (const glw::Functions& gl, deUint8 *dataPtr)
+{
+	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dataPtr);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with RGBA_8888 (8 bit components)");
+}
+
+void WideColorSurfaceTest::writeEglConfig (EGLConfig config)
+{
+	const Library&	egl	= m_eglTestCtx.getLibrary();
+	tcu::TestLog&	log		= m_testCtx.getLog();
+	qpEglConfigInfo info;
+	EGLint			val		= 0;
+
+	info.bufferSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BUFFER_SIZE);
+
+	info.redSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_RED_SIZE);
+
+	info.greenSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_GREEN_SIZE);
+
+	info.blueSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BLUE_SIZE);
+
+	info.luminanceSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_LUMINANCE_SIZE);
+
+	info.alphaSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_ALPHA_SIZE);
+
+	info.alphaMaskSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_ALPHA_MASK_SIZE);
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BIND_TO_TEXTURE_RGB);
+	info.bindToTextureRGB = val == EGL_TRUE ? true : false;
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BIND_TO_TEXTURE_RGBA);
+	info.bindToTextureRGBA = val == EGL_TRUE ? true : false;
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_COLOR_BUFFER_TYPE);
+	std::string colorBufferType = de::toString(eglu::getColorBufferTypeStr(val));
+	info.colorBufferType = colorBufferType.c_str();
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFIG_CAVEAT);
+	std::string caveat = de::toString(eglu::getConfigCaveatStr(val));
+	info.configCaveat = caveat.c_str();
+
+	info.configID = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFIG_ID);
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFORMANT);
+	std::string conformant = de::toString(eglu::getAPIBitsStr(val));
+	info.conformant = conformant.c_str();
+
+	info.depthSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_DEPTH_SIZE);
+
+	info.level = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_LEVEL);
+
+	info.maxPBufferWidth = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_WIDTH);
+
+	info.maxPBufferHeight = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_HEIGHT);
+
+	info.maxPBufferPixels = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_PIXELS);
+
+	info.maxSwapInterval = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_SWAP_INTERVAL);
+
+	info.minSwapInterval = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MIN_SWAP_INTERVAL);
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_NATIVE_RENDERABLE);
+	info.nativeRenderable = val == EGL_TRUE ? true : false;
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_RENDERABLE_TYPE);
+	std::string renderableTypes = de::toString(eglu::getAPIBitsStr(val));
+	info.renderableType = renderableTypes.c_str();
+
+	info.sampleBuffers = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SAMPLE_BUFFERS);
+
+	info.samples = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SAMPLES);
+
+	info.stencilSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_STENCIL_SIZE);
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SURFACE_TYPE);
+	std::string surfaceTypes = de::toString(eglu::getSurfaceBitsStr(val));
+	info.surfaceTypes = surfaceTypes.c_str();
+
+	val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_TYPE);
+	std::string transparentType = de::toString(eglu::getTransparentTypeStr(val));
+	info.transparentType = transparentType.c_str();
+
+	info.transparentRedValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_RED_VALUE);
+
+	info.transparentGreenValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_GREEN_VALUE);
+
+	info.transparentBlueValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_BLUE_VALUE);
+
+	log.writeEglConfig(&info);
+}
+
+deUint32 WideColorSurfaceTest::expectedUint10 (float reference)
+{
+	deUint32 expected;
+
+	if (reference < 0.0)
+	{
+		expected = 0;
+	}
+	else if (reference > 1.0)
+	{
+		expected = 1023;
+	}
+	else
+	{
+		expected = static_cast<deUint32>(deRound(reference * 1023.0));
+	}
+
+	return expected;
+}
+
+deUint32 WideColorSurfaceTest::expectedUint2 (float reference)
+{
+	deUint32 expected;
+
+	if (reference < 0.0)
+	{
+		expected = 0;
+	}
+	else if (reference > 1.0)
+	{
+		expected = 3;
+	}
+	else
+	{
+		expected = static_cast<deUint32>(deRound(reference * 3.0));
+	}
+
+	return expected;
+}
+
+deUint8 WideColorSurfaceTest::expectedUint8 (float reference)
+{
+	deUint8 expected;
+	if (reference < 0.0)
+	{
+		expected = 0;
+	}
+	else if (reference >= 1.0)
+	{
+		expected = 255;
+	}
+	else
+	{
+		// Apply sRGB transfer function when colorspace is sRGB and pixel component
+		// size is 8 bits (which is why we are here in expectedUint8).
+		if (m_colorSpace == EGL_GL_COLORSPACE_SRGB_KHR)
+		{
+			float srgbReference;
+
+			if (reference <= 0.0031308)
+			{
+				srgbReference = 12.92f * reference;
+			}
+			else
+			{
+				float powRef = deFloatPow(reference, (1.0f/2.4f));
+				srgbReference = (1.055f * powRef) - 0.055f;
+			}
+			expected = static_cast<deUint8>(deRound(srgbReference * 255.0));
+		}
+		else
+		{
+			expected = static_cast<deUint8>(deRound(reference * 255.0));
+		}
+	}
+	return expected;
+}
+
+deUint8 WideColorSurfaceTest::expectedAlpha8 (float reference)
+{
+	deUint8 expected;
+	if (reference < 0.0)
+	{
+		expected = 0;
+	}
+	else if (reference >= 1.0)
+	{
+		expected = 255;
+	}
+	else
+	{
+		// The sRGB transfer function is not applied to alpha
+		expected = static_cast<deUint8>(deRound(reference * 255.0));
+	}
+	return expected;
+}
+
+// Return true for value out of range (fail)
+bool WideColorSurfaceTest::checkWithThreshold8(deUint8 value, deUint8 reference, deUint8 threshold)
+{
+	const deUint8 low = reference >= threshold ? static_cast<deUint8>(reference - threshold) : 0;
+	const deUint8 high = reference <= (255 - threshold) ? static_cast<deUint8>(reference + threshold) : 255;
+	return !((value >= low) && (value <= high));
+}
+
+bool WideColorSurfaceTest::checkWithThreshold10(deUint32 value, deUint32 reference, deUint32 threshold)
+{
+	const deUint32 low = reference >= threshold ? reference - threshold : 0;
+	const deUint32 high = reference <= (1023 - threshold) ? reference + threshold : 1023;
+	return !((value >= low) && (value <= high));
+}
+
+bool WideColorSurfaceTest::checkWithThresholdFloat(float value, float reference, float threshold)
+{
+	const float low = reference - threshold;
+	const float high = reference + threshold;
+	return !((value >= low) && (value <= high));
+}
+
+void WideColorSurfaceTest::testPixels (float reference, float increment)
+{
+	tcu::TestLog&	log				= m_testCtx.getLog();
+
+	if (m_componentType == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
+	{
+		float pixels[16];
+		const float expected[4] =
+		{
+			reference,
+			reference + increment,
+			reference - increment,
+			reference + 2 * increment
+		};
+		readPixels(m_gl, pixels);
+
+		if (checkWithThresholdFloat(pixels[0], expected[0], increment) ||
+				checkWithThresholdFloat(pixels[1], expected[1], increment) ||
+				checkWithThresholdFloat(pixels[2], expected[2], increment) ||
+				checkWithThresholdFloat(pixels[3], expected[3], increment))
+		{
+			if (m_debugLog.str().size() > 0)
+			{
+				log << tcu::TestLog::Message
+					<< "Prior passing tests\n"
+					<< m_debugLog.str()
+					<< tcu::TestLog::EndMessage;
+				m_debugLog.str("");
+			}
+			log << tcu::TestLog::Message
+				<< "Image comparison failed: "
+				<< "reference = " << reference
+				<< ", expected = " << expected[0]
+					<< ":" << expected[1]
+					<< ":" << expected[2]
+					<< ":" << expected[3]
+				<< ", result = " << pixels[0]
+					<< ":" << pixels[1]
+					<< ":" << pixels[2]
+					<< ":" << pixels[3]
+				<< tcu::TestLog::EndMessage;
+			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
+		}
+		else
+		{
+			// Pixel matches expected value
+			m_debugLog << "Image comparison passed: "
+				<< "reference = " << reference
+				<< ", result = " << pixels[0]
+					<< ":" << pixels[1]
+					<< ":" << pixels[2]
+					<< ":" << pixels[3]
+				<< "\n";
+		}
+	}
+	else if (m_redSize > 8)
+	{
+		deUint32 buffer[16];
+		readPixels(m_gl, buffer);
+		deUint32 pixels[4];
+		deUint32 expected[4];
+
+		pixels[0] = buffer[0] & 0x3ff;
+		pixels[1] = (buffer[0] >> 10) & 0x3ff;
+		pixels[2] = (buffer[0] >> 20) & 0x3ff;
+		pixels[3] = (buffer[0] >> 30) & 0x3;
+
+		expected[0] = expectedUint10(reference);
+		expected[1] = expectedUint10(reference + increment);
+		expected[2] = expectedUint10(reference - increment);
+		expected[3] = expectedUint2(reference + 2 * increment);
+		if (checkWithThreshold10(pixels[0], expected[0]) || checkWithThreshold10(pixels[1], expected[1])
+				|| checkWithThreshold10(pixels[2], expected[2]) || checkWithThreshold10(pixels[3], expected[3]))
+		{
+			if (m_debugLog.str().size() > 0) {
+				log << tcu::TestLog::Message
+					<< "Prior passing tests\n"
+					<< m_debugLog.str()
+					<< tcu::TestLog::EndMessage;
+				m_debugLog.str("");
+			}
+			log << tcu::TestLog::Message
+				<< "Image comparison failed: "
+				<< "reference = " << reference
+				<< ", expected = " << static_cast<deUint32>(expected[0])
+					<< ":" << static_cast<deUint32>(expected[1])
+					<< ":" << static_cast<deUint32>(expected[2])
+					<< ":" << static_cast<deUint32>(expected[3])
+				<< ", result = " << static_cast<deUint32>(pixels[0])
+					<< ":" << static_cast<deUint32>(pixels[1])
+					<< ":" << static_cast<deUint32>(pixels[2])
+					<< ":" << static_cast<deUint32>(pixels[3])
+				<< tcu::TestLog::EndMessage;
+			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
+		}
+		else
+		{
+			// Pixel matches expected value
+			m_debugLog << "Image comparison passed: "
+				<< "reference = " << reference
+				<< ", result = " << static_cast<deUint32>(pixels[0])
+					<< ":" << static_cast<deUint32>(pixels[1])
+					<< ":" << static_cast<deUint32>(pixels[2])
+					<< ":" << static_cast<deUint32>(pixels[3])
+				<< "\n";
+		}
+	}
+	else
+	{
+		deUint8 pixels[16];
+		deUint8 expected[4];
+		readPixels(m_gl, pixels);
+
+		expected[0] = expectedUint8(reference);
+		expected[1] = expectedUint8(reference + increment);
+		expected[2] = expectedUint8(reference - increment);
+		expected[3] = expectedAlpha8(reference + 2 * increment);
+		if (checkWithThreshold8(pixels[0], expected[0]) || checkWithThreshold8(pixels[1], expected[1])
+				|| checkWithThreshold8(pixels[2], expected[2]) || checkWithThreshold8(pixels[3], expected[3]))
+		{
+			if (m_debugLog.str().size() > 0) {
+				log << tcu::TestLog::Message
+					<< "(C)Prior passing tests\n"
+					<< m_debugLog.str()
+					<< tcu::TestLog::EndMessage;
+				m_debugLog.str("");
+			}
+			log << tcu::TestLog::Message
+				<< "Image comparison failed: "
+				<< "reference = " << reference
+				<< ", expected = " << static_cast<deUint32>(expected[0])
+					<< ":" << static_cast<deUint32>(expected[1])
+					<< ":" << static_cast<deUint32>(expected[2])
+					<< ":" << static_cast<deUint32>(expected[3])
+				<< ", result = " << static_cast<deUint32>(pixels[0])
+					<< ":" << static_cast<deUint32>(pixels[1])
+					<< ":" << static_cast<deUint32>(pixels[2])
+					<< ":" << static_cast<deUint32>(pixels[3])
+				<< tcu::TestLog::EndMessage;
+			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
+		}
+		else
+		{
+			// Pixel matches expected value
+			m_debugLog << "Image comparison passed: "
+				<< "reference = " << reference
+				<< ", result = " << static_cast<deUint32>(pixels[0])
+					<< ":" << static_cast<deUint32>(pixels[1])
+					<< ":" << static_cast<deUint32>(pixels[2])
+					<< ":" << static_cast<deUint32>(pixels[3])
+				<< "\n";
+		}
+	}
+}
+
+void WideColorSurfaceTest::doClearTest (EGLSurface surface)
+{
+	tcu::TestLog&	log				= m_testCtx.getLog();
+	const Library&	egl				= m_eglTestCtx.getLibrary();
+	const EGLint	attribList[]	=
+	{
+		EGL_CONTEXT_CLIENT_VERSION, 2,
+		EGL_NONE
+	};
+	EGLContext		eglContext		= egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
+	EGLU_CHECK_MSG(egl, "eglCreateContext");
+
+	egl.makeCurrent(m_eglDisplay, surface, surface, eglContext);
+	EGLU_CHECK_MSG(egl, "eglMakeCurrent");
+
+	{
+		// put gles2Renderer inside it's own scope so that it's cleaned
+		// up before we hit the destroyContext
+		const GLES2Renderer gles2Renderer(m_gl, 128, 128);
+
+		std::vector<Iteration>::const_iterator it;	// declare an Iterator to a vector of strings
+		log << tcu::TestLog::Message << "m_iterations.count = " << m_iterations.size() << tcu::TestLog::EndMessage;
+		for(it = m_iterations.begin() ; it < m_iterations.end(); it++)
+		{
+			float reference = it->start;
+			log << tcu::TestLog::Message << "start = " << it->start
+						<< tcu::TestLog::EndMessage;
+			log << tcu::TestLog::Message
+						<< "increment = " << it->increment
+						<< tcu::TestLog::EndMessage;
+			log << tcu::TestLog::Message
+						<< "count = " << it->iterationCount
+						<< tcu::TestLog::EndMessage;
+			m_debugLog.str("");
+			for (int iterationCount = 0; iterationCount < it->iterationCount; iterationCount++)
+			{
+				const Color	clearColor(reference, reference + it->increment, reference - it->increment, reference + 2 * it->increment);
+
+				clearColorScreen(m_gl, clearColor);
+				GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to test value");
+
+				testPixels(reference, it->increment);
+
+				// reset buffer contents so that we know render below did something
+				const Color	clearColor2(1.0f - reference, 1.0f, 1.0f, 1.0f);
+				clearColorScreen(m_gl, clearColor2);
+				GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to 1.0f - reference value");
+
+				const ColoredRect	coloredRect	(IVec2(0.0f, 0.0f), IVec2(1.0f, 1.0f), clearColor);
+				gles2Renderer.render(coloredRect);
+				testPixels(reference, it->increment);
+
+				reference += it->increment;
+			}
+
+			EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, surface));
+		}
+	}
+
+	// disconnect surface & context so they can be destroyed when
+	// this function exits.
+	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+	egl.destroyContext(m_eglDisplay, eglContext);
+}
+
+void WideColorSurfaceTest::executeTest (void)
+{
+	tcu::TestLog&						log				= m_testCtx.getLog();
+	const Library&						egl				= m_eglTestCtx.getLibrary();
+	const eglu::NativeDisplayFactory&	displayFactory	= m_eglTestCtx.getNativeDisplayFactory();
+	eglu::NativeDisplay&				nativeDisplay	= m_eglTestCtx.getNativeDisplay();
+	egl.bindAPI(EGL_OPENGL_ES_API);
+
+	if (m_surfaceType & EGL_PBUFFER_BIT)
+	{
+		log << tcu::TestLog::Message << "Test Pbuffer" << tcu::TestLog::EndMessage;
+
+		std::vector<EGLint>			attribs;
+		attribs.push_back(EGL_WIDTH);
+		attribs.push_back(128);
+		attribs.push_back(EGL_HEIGHT);
+		attribs.push_back(128);
+		if (m_colorSpace != EGL_NONE)
+		{
+			attribs.push_back(EGL_GL_COLORSPACE_KHR);
+			attribs.push_back(m_colorSpace);
+		}
+		attribs.push_back(EGL_NONE);
+		attribs.push_back(EGL_NONE);
+		const EGLSurface surface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribs.data());
+		if ((surface == EGL_NO_SURFACE) && (egl.getError() == EGL_BAD_MATCH))
+		{
+			TCU_THROW(NotSupportedError, "Colorspace is not supported with this format");
+		}
+		TCU_CHECK(surface != EGL_NO_SURFACE);
+		EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
+
+		doClearTest(surface);
+
+		egl.destroySurface(m_eglDisplay, surface);
+		EGLU_CHECK_MSG(egl, "eglDestroySurface()");
+	}
+	else if (m_surfaceType & EGL_WINDOW_BIT)
+	{
+		log << tcu::TestLog::Message << "Test Window" << tcu::TestLog::EndMessage;
+
+		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(displayFactory, m_testCtx.getCommandLine());
+
+		de::UniquePtr<eglu::NativeWindow>	window			(windowFactory.createWindow(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, eglu::WindowParams(128, 128, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
+		std::vector<EGLAttrib>		attribs;
+		if (m_colorSpace != EGL_NONE)
+		{
+			attribs.push_back(EGL_GL_COLORSPACE_KHR);
+			attribs.push_back(m_colorSpace);
+		}
+		attribs.push_back(EGL_NONE);
+		attribs.push_back(EGL_NONE);
+
+		EGLSurface	surface;
+		try
+		{
+			surface = eglu::createWindowSurface(nativeDisplay, *window, m_eglDisplay, m_eglConfig, attribs.data());
+		}
+		catch (const eglu::Error& error)
+		{
+			if (error.getError() == EGL_BAD_MATCH)
+				TCU_THROW(NotSupportedError, "createWindowSurface is not supported for this config");
+
+			throw;
+		}
+		TCU_CHECK(surface != EGL_NO_SURFACE);
+		EGLU_CHECK_MSG(egl, "eglCreateWindowSurface()");
+
+		doClearTest(surface);
+
+		egl.destroySurface(m_eglDisplay, surface);
+		EGLU_CHECK_MSG(egl, "eglDestroySurface()");
+	}
+	else if (m_surfaceType & EGL_PIXMAP_BIT)
+	{
+		log << tcu::TestLog::Message << "Test Pixmap" << tcu::TestLog::EndMessage;
+
+		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(displayFactory, m_testCtx.getCommandLine());
+
+		de::UniquePtr<eglu::NativePixmap>	pixmap			(pixmapFactory.createPixmap(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, 128, 128));
+		const EGLSurface					surface			= eglu::createPixmapSurface(nativeDisplay, *pixmap, m_eglDisplay, m_eglConfig, DE_NULL);
+		TCU_CHECK(surface != EGL_NO_SURFACE);
+		EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface()");
+
+		doClearTest(surface);
+
+		egl.destroySurface(m_eglDisplay, surface);
+		EGLU_CHECK_MSG(egl, "eglDestroySurface()");
+	}
+	else
+		TCU_FAIL("No valid surface types supported in config");
+}
+
+TestCase::IterateResult WideColorSurfaceTest::iterate (void)
+{
+	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+	executeTest();
+	return STOP;
+}
+
+} // anonymous
+
+WideColorTests::WideColorTests (EglTestContext& eglTestCtx)
+	: TestCaseGroup(eglTestCtx, "wide_color", "Wide Color tests")
+{
+}
+
+void WideColorTests::init (void)
+{
+	addChild(new WideColorFP16Test(m_eglTestCtx, "fp16", "Verify that FP16 pixel format is present"));
+	addChild(new WideColor1010102Test(m_eglTestCtx, "1010102", "Check if 1010102 pixel format is present"));
+
+	// This is an increment FP16 can do between -1.0 to 1.0
+	const float fp16Increment1 = deFloatPow(2.0, -11.0);
+	// This is an increment FP16 can do between 1.0 to 2.0
+	const float fp16Increment2 = deFloatPow(2.0, -10.0);
+
+	const EGLint windowAttribListFP16[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_WINDOW_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					16,
+		EGL_GREEN_SIZE,					16,
+		EGL_BLUE_SIZE,					16,
+		EGL_ALPHA_SIZE,					16,
+		EGL_COLOR_COMPONENT_TYPE_EXT,	EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+		EGL_NONE,						EGL_NONE
+	};
+
+	std::vector<Iteration> fp16Iterations;
+	// -0.333251953125f ~ -1/3 as seen in FP16
+	fp16Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
+	// test crossing 0
+	fp16Iterations.push_back( Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
+	// test crossing 1.0
+	fp16Iterations.push_back( Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_default_colorspace", "FP16 window surface has FP16 pixels in it", windowAttribListFP16, EGL_NONE, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_srgb", "FP16 window surface, explicit sRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_p3", "FP16 window surface, explicit Display-P3 colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb", "FP16 window surface, explicit scRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb_linear", "FP16 window surface, explicit scRGB linear colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, fp16Iterations));
+
+	const EGLint pbufferAttribListFP16[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_PBUFFER_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					16,
+		EGL_GREEN_SIZE,					16,
+		EGL_BLUE_SIZE,					16,
+		EGL_ALPHA_SIZE,					16,
+		EGL_COLOR_COMPONENT_TYPE_EXT,	EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+		EGL_NONE,						EGL_NONE
+	};
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_default_colorspace", "FP16 pbuffer surface has FP16 pixels in it", pbufferAttribListFP16, EGL_NONE, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_srgb", "FP16 pbuffer surface, explicit sRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_p3", "FP16 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb", "FP16 pbuffer surface, explicit scRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, fp16Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb_linear", "FP16 pbuffer surface, explicit scRGB linear colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, fp16Iterations));
+
+	const EGLint windowAttribList1010102[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_WINDOW_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					10,
+		EGL_GREEN_SIZE,					10,
+		EGL_BLUE_SIZE,					10,
+		EGL_ALPHA_SIZE,					2,
+		EGL_NONE,						EGL_NONE
+	};
+
+	std::vector<Iteration> int1010102Iterations;
+	// -0.333251953125f ~ -1/3 as seen in fp16
+	// Negative values will be 0 on read with fixed point pixel formats
+	int1010102Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
+	// test crossing 0
+	int1010102Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
+	// test crossing 1.0
+	// Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
+	int1010102Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_default", "1010102 Window surface, default (sRGB) colorspace", windowAttribList1010102, EGL_NONE, int1010102Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_srgb", "1010102 Window surface, explicit sRGB colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, int1010102Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_p3", "1010102 Window surface, explicit Display-P3 colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int1010102Iterations));
+
+	const EGLint pbufferAttribList1010102[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_PBUFFER_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					10,
+		EGL_GREEN_SIZE,					10,
+		EGL_BLUE_SIZE,					10,
+		EGL_ALPHA_SIZE,					2,
+		EGL_NONE,						EGL_NONE
+	};
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_default", "1010102 pbuffer surface, default (sRGB) colorspace", pbufferAttribList1010102, EGL_NONE, int1010102Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_srgb", "1010102 pbuffer surface, explicit sRGB colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, int1010102Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_p3", "1010102 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int1010102Iterations));
+
+	const EGLint windowAttribList8888[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_WINDOW_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					8,
+		EGL_GREEN_SIZE,					8,
+		EGL_BLUE_SIZE,					8,
+		EGL_ALPHA_SIZE,					8,
+		EGL_NONE,						EGL_NONE
+	};
+
+	std::vector<Iteration> int8888Iterations;
+	// -0.333251953125f ~ -1/3 as seen in fp16
+	// Negative values will be 0 on read with fixed point pixel formats
+	int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
+	// test crossing 0
+	int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
+	// test crossing 1.0
+	// Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
+	int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, int8888Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_srgb", "8888 window surface, explicit sRGB colorspace", windowAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, int8888Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_p3", "8888 window surface, explicit Display-P3 colorspace", windowAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int8888Iterations));
+
+	const EGLint pbufferAttribList8888[] =
+	{
+		EGL_SURFACE_TYPE,				EGL_PBUFFER_BIT,
+		EGL_RENDERABLE_TYPE,			EGL_OPENGL_ES2_BIT,
+		EGL_RED_SIZE,					8,
+		EGL_GREEN_SIZE,					8,
+		EGL_BLUE_SIZE,					8,
+		EGL_ALPHA_SIZE,					8,
+		EGL_NONE,						EGL_NONE
+	};
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_default", "8888 pbuffer surface, default (sRGB) colorspace", pbufferAttribList8888, EGL_NONE, int8888Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_srgb", "8888 pbuffer surface, explicit sRGB colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, int8888Iterations));
+	addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_p3", "8888 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int8888Iterations));
+}
+
+TestCaseGroup* createWideColorTests (EglTestContext& eglTestCtx)
+{
+	return new WideColorTests(eglTestCtx);
+}
+
+} // egl
+} // deqp
diff --git a/modules/egl/teglWideColorTests.hpp b/modules/egl/teglWideColorTests.hpp
new file mode 100644
index 0000000..5f58f58
--- /dev/null
+++ b/modules/egl/teglWideColorTests.hpp
@@ -0,0 +1,39 @@
+#ifndef _TEGLWIDECOLORTESTS_HPP
+#define _TEGLWIDECOLORTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Test KHR_wide_color
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "teglTestCase.hpp"
+
+namespace deqp
+{
+namespace egl
+{
+
+TestCaseGroup* createWideColorTests (EglTestContext& eglTestCtx);
+
+} // egl
+} // deqp
+
+#endif // _TEGLWIDECOLORTESTS_HPP
diff --git a/modules/gles2/functional/es2fFboCompletenessTests.cpp b/modules/gles2/functional/es2fFboCompletenessTests.cpp
index cca35e1..a89967c 100644
--- a/modules/gles2/functional/es2fFboCompletenessTests.cpp
+++ b/modules/gles2/functional/es2fFboCompletenessTests.cpp
@@ -176,7 +176,7 @@
 	},
 	{
 		"DEQP_gles3_core_compatible",
-		(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE),
+		(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID),
 		GLS_ARRAY_RANGE(s_es3NoExtTextureColorRenderableFormats)
 	},
 	{
diff --git a/modules/gles3/functional/es3fFunctionalTests.cpp b/modules/gles3/functional/es3fFunctionalTests.cpp
index 6f6f308..5a57831 100644
--- a/modules/gles3/functional/es3fFunctionalTests.cpp
+++ b/modules/gles3/functional/es3fFunctionalTests.cpp
@@ -191,20 +191,22 @@
 
 	void init (void)
 	{
-		addChild(new ShaderLibraryTest			(m_context, "preprocessor",			"Preprocessor Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "constants",			"Constant Literal Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "linkage",				"Linkage Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "conversions",			"Type Conversion Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "conditionals",			"Conditionals Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "declarations",			"Declarations Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "swizzles",				"Swizzle Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "functions",			"Function Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "arrays",				"Array Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "keywords",				"Keyword Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "qualification_order",	"Order Of Qualification Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "scoping",				"Scoping of Declarations"));
-		addChild(new ShaderLibraryTest			(m_context, "negative",				"Miscellaneous Negative Shader Compilation Tests"));
-		addChild(new ShaderLibraryTest			(m_context, "uniform_block",		"Uniform block tests"));
+		addChild(new ShaderLibraryTest			(m_context, "preprocessor",				"Preprocessor Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "constants",				"Constant Literal Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "linkage",					"Linkage Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "conversions",				"Type Conversion Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "conditionals",				"Conditionals Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "declarations",				"Declarations Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "swizzles",					"Swizzle Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "swizzle_math_operations",	"Swizzle Math Operations Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "functions",				"Function Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "arrays",					"Array Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "large_constant_arrays",	"Large Constant Array Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "keywords",					"Keyword Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "qualification_order",		"Order Of Qualification Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "scoping",					"Scoping of Declarations"));
+		addChild(new ShaderLibraryTest			(m_context, "negative",					"Miscellaneous Negative Shader Compilation Tests"));
+		addChild(new ShaderLibraryTest			(m_context, "uniform_block",			"Uniform block tests"));
 
 		addChild(new ShaderDiscardTests			(m_context));
 		addChild(new ShaderIndexingTests		(m_context));
diff --git a/modules/gles3/scripts/gen-large-constant-arrays.py b/modules/gles3/scripts/gen-large-constant-arrays.py
new file mode 100644
index 0000000..1ae4f7e
--- /dev/null
+++ b/modules/gles3/scripts/gen-large-constant-arrays.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-------------------------------------------------------------------------
+
+import random
+from genutil import *
+
+random.seed(0x1234)
+
+DATA_TYPES	= ["float", "vec4"]
+ARRAY_SIZES	= [16, 32, 64, 128]
+
+s_largeArrayCaseTemplate = """
+case ${{NAME}}
+	version 300 es
+	values
+	{
+		${{VALUES}}
+	}
+
+	both ""
+		#version 300 es
+		precision mediump float;
+
+		${DECLARATIONS}
+
+		void main()
+		{
+			${{ARRAY_DECL}}
+
+			${SETUP}
+			${{OP}}
+			${OUTPUT}
+		}
+	""
+end
+"""[1:]
+
+
+class LargeConstantArrayCase(ShaderCase):
+	def __init__(self, name, array, inputs, outputs):
+		self.name	= name
+		self.array	= array
+		self.inputs	= inputs
+		self.outputs	= outputs
+		self.op		= "out0 = array[in0];"
+
+	def __str__(self):
+		params = {
+			"NAME":		self.name,
+			"VALUES":	genValues(self.inputs, self.outputs),
+			"ARRAY_DECL":	self.array,
+			"OP":		self.op
+		}
+		return fillTemplate(s_largeArrayCaseTemplate, params)
+
+
+def genArray(dataType, size):
+	elements = []
+	for i in xrange(size):
+		if dataType == "float":
+		    elements.append(Scalar(round(random.uniform(-1.0, 1.0), 6)))
+		if dataType == "vec4":
+		    elements.append(Vec4(*[round(random.uniform(-1.0, 1.0), 6) for x in range(4)]))
+
+	return elements
+
+
+def arrayToString(elements):
+	array = ('const {TYPE} array[{LENGTH}] = {TYPE}[](\n'
+		.format(TYPE=elements[0].typeString(), LENGTH=len(elements)))
+
+	array += "\n".join(str(e) + ',' for e in elements[:-1])
+	array += "\n" + str(elements[-1])
+	array += ");"
+
+	return array
+
+allCases = []
+largeConstantArrayCases = []
+
+for dataType in DATA_TYPES:
+	for arraySize in ARRAY_SIZES:
+		indexes = random.sample(range(arraySize-1), 10)
+		array = genArray(dataType, arraySize)
+		outputs = [array[index] for index in indexes]
+		outType = outputs[0].typeString()
+		caseName = "%s_%s" % (dataType, arraySize)
+
+		case = LargeConstantArrayCase(caseName,
+					      arrayToString(array),
+					      [("int in0", indexes)],
+					      [("%s out0" % outType, outputs)])
+
+		largeConstantArrayCases.append(case)
+
+allCases.append(CaseGroup("indexing", "Large constant array indexing", largeConstantArrayCases))
+
+if __name__ == "__main__":
+	print "Generating shader case files."
+	writeAllCases("large_constant_arrays.test", allCases)
diff --git a/modules/gles3/scripts/gen-swizzle-math-operations.py b/modules/gles3/scripts/gen-swizzle-math-operations.py
new file mode 100644
index 0000000..614b26d
--- /dev/null
+++ b/modules/gles3/scripts/gen-swizzle-math-operations.py
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+
+#-------------------------------------------------------------------------
+# drawElements Quality Program utilities
+# --------------------------------------
+#
+# Copyright 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-------------------------------------------------------------------------
+
+import operator as op
+from genutil import *
+from collections import OrderedDict
+
+VECTOR_TYPES	= ["vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4"]
+PRECISION_TYPES = ["mediump"]
+SWIZZLE_NAMES	= ["xyzw"]
+
+s_swizzleCaseTemplate = """
+case ${{NAME}}
+	version 300 es
+	values
+	{
+		${{VALUES}}
+	}
+
+	both ""
+		#version 300 es
+		precision mediump float;
+
+		${DECLARATIONS}
+
+		void main()
+		{
+			${SETUP}
+			${{OP}}
+			${OUTPUT}
+		}
+	""
+end
+"""[1:]
+
+def getDataTypeScalarSize (dt):
+	return {
+		"vec2":		2,
+		"vec3":		3,
+		"vec4":		4,
+		"ivec2":	2,
+		"ivec3":	3,
+		"ivec4":	4,
+	}[dt]
+
+def getSwizzlesForWidth(width):
+	if (width == 2):
+		return [(0, ),
+			(0,0), (0,1), (1,0),
+			(1,0,1), (0,1,0,0), (1,0,1,0)]
+	elif (width == 3):
+		return [(0,), (2,),
+			(0,2), (2,2),
+			(0,1,2), (2,1,0), (0,0,0), (2,2,2), (2,2,1), (1,0,1), (0,2,0),
+			(0,1,1,0), (2,0,1,2)]
+	elif (width == 4):
+		return [(0,), (3,),
+			(3,0), (3,2),
+			(3,3,3), (1,1,3), (3,2,1),
+			(0,1,2,3), (3,2,1,0), (0,1,0,1), (1,2,2,1), (3,0,3,3), (0,1,0,0), (2,2,2,2)]
+	else:
+		assert False
+
+def operatorToSymbol(operator):
+	if operator == "add":		return "+"
+	if operator == "subtract":	return "-"
+	if operator == "multiply":	return "*"
+	if operator == "divide":	return "/"
+
+def rotate(l, n) :
+	return l[n:] + l[:n]
+
+class SwizzleCase(ShaderCase):
+	def __init__(self, name, swizzle1, swizzle2, inputs1, inputs2, operator, outputs):
+		self.name	= name
+		self.swizzle1	= swizzle1
+		self.swizzle2	= swizzle2
+		self.inputs	= inputs1 + inputs2
+		self.outputs	= outputs
+		self.op		= "out0 = in0.%s %s in1.%s;" % (swizzle1, operator, swizzle2)
+
+	def __str__(self):
+		params = {
+			"NAME":		self.name,
+			"VALUES":	genValues(self.inputs, self.outputs),
+			"OP":		self.op
+		}
+		return fillTemplate(s_swizzleCaseTemplate, params)
+
+
+# CASE DECLARATIONS
+inFloat = [Scalar(x) for x in [0.0, 1.0, 2.0, 3.5, -0.5, -20.125, 36.8125]]
+inInt	= [Scalar(x) for x in [0, 1, 2, 5, 8, 11, -12, -66, -192, 255]]
+
+inVec4	= [
+	Vec4(0.1, 0.5, 0.75, 0.825),
+	Vec4(1.0, 1.25, 1.125, 1.75),
+	Vec4(-0.5, -2.25, -4.875, 9.0),
+	Vec4(-32.0, 64.0, -51.0, 24.0),
+	Vec4(-0.75, -1.0/31.0, 1.0/19.0, 1.0/4.0),
+]
+
+inVec3	= toVec3(inVec4)
+inVec2	= toVec2(inVec4)
+
+inIVec4 = toIVec4(
+	[
+	    Vec4(-1, 1, -1, 1),
+	    Vec4(1, 2, 3, 4),
+	    Vec4(-1, -2, -4, -9),
+	]
+)
+
+inIVec3 = toIVec3(inIVec4)
+inIVec2 = toIVec2(inIVec4)
+
+INPUTS = OrderedDict([
+	("float",	inFloat),
+	("vec2",	inVec2),
+	("vec3",	inVec3),
+	("vec4",	inVec4),
+	("int",		inInt),
+	("ivec2",	inIVec2),
+	("ivec3",	inIVec3),
+	("ivec4",	inIVec4),
+])
+
+OPERATORS = OrderedDict([
+	("add",		op.add),
+	("subtract",	op.sub),
+	("multiply",	op.mul),
+	("divide",	op.div),
+])
+
+vectorSwizzleGroupCases = {
+	"add":		[],
+	"subtract" :	[],
+	"multiply" :	[],
+	"divide" :	[],
+}
+
+allCases = []
+
+for operator in OPERATORS:
+	for dataType in VECTOR_TYPES:
+		scalarSize = getDataTypeScalarSize(dataType)
+		for precision in PRECISION_TYPES:
+			for swizzleComponents in SWIZZLE_NAMES:
+				for swizzleIndices in getSwizzlesForWidth(scalarSize):
+					swizzle1 = "".join(map(lambda x: swizzleComponents[x], swizzleIndices))
+
+					swizzle2 = rotate(swizzle1, 1)
+					rotatedSwizzleIndices = rotate(swizzleIndices, 1)
+
+					operands1 = INPUTS[dataType]
+					operands2 = INPUTS[dataType]  # these input values will be swizzled
+
+					outputs = map(lambda x, y: OPERATORS[operator](x.swizzle(swizzleIndices), y.swizzle(rotatedSwizzleIndices)), operands1, operands2)
+					outType = outputs[0].typeString()
+					caseName = "%s_%s_%s_%s" % (precision, dataType, swizzle1, swizzle2)
+
+					case = SwizzleCase(	caseName,
+								swizzle1,
+								swizzle2,
+								[("%s in0" % dataType, operands1)],
+								[("%s in1" % dataType, operands2)],
+								operatorToSymbol(operator),
+								[("%s out0" % outType, outputs)])
+
+					vectorSwizzleGroupCases[operator].append(case)
+
+	allCases.append(CaseGroup("vector_" + operator, "Vector swizzle math operations", vectorSwizzleGroupCases[operator]))
+
+if __name__ == "__main__":
+	print "Generating shader case files."
+	writeAllCases("swizzle_math_operations.test", allCases)
diff --git a/modules/gles31/functional/CMakeLists.txt b/modules/gles31/functional/CMakeLists.txt
index 2f2429e..a4ac348 100644
--- a/modules/gles31/functional/CMakeLists.txt
+++ b/modules/gles31/functional/CMakeLists.txt
@@ -71,6 +71,8 @@
 	es31fFboTestCase.hpp
 	es31fFboTestUtil.cpp
 	es31fFboTestUtil.hpp
+	es31fFboSRGBWriteControlTests.cpp
+	es31fFboSRGBWriteControlTests.hpp
 	es31fTextureFilteringTests.cpp
 	es31fTextureFilteringTests.hpp
 	es31fTextureFormatTests.hpp
@@ -155,6 +157,8 @@
 	es31fNegativeShaderFunctionTests.hpp
 	es31fNegativeShaderDirectiveTests.cpp
 	es31fNegativeShaderDirectiveTests.hpp
+	es31fNegativeSampleVariablesTests.hpp
+	es31fNegativeSampleVariablesTests.cpp
 	es31fNegativePreciseTests.cpp
 	es31fNegativePreciseTests.hpp
 	es31fNegativeAdvancedBlendEquationTests.cpp
@@ -181,6 +185,14 @@
 	es31fNegativeShaderStorageTests.hpp
 	es31fNegativeSSBOBlockTests.cpp
 	es31fNegativeSSBOBlockTests.hpp
+	es31fDrawElementsBaseVertexTests.cpp
+	es31fDrawElementsBaseVertexTests.hpp
+	es31fNegativeComputeTests.cpp
+	es31fNegativeComputeTests.hpp
+	es31fShaderFramebufferFetchTests.cpp
+	es31fShaderFramebufferFetchTests.hpp
+	es31fNegativeShaderFramebufferFetchTests.cpp
+	es31fNegativeShaderFramebufferFetchTests.hpp
 	)
 
 add_library(deqp-gles31-functional STATIC ${DEQP_GLES31_FUNCTIONAL_SRCS})
diff --git a/modules/gles31/functional/es31fDebugTests.cpp b/modules/gles31/functional/es31fDebugTests.cpp
index d41addb..1613179 100644
--- a/modules/gles31/functional/es31fDebugTests.cpp
+++ b/modules/gles31/functional/es31fDebugTests.cpp
@@ -39,6 +39,9 @@
 #include "es31fNegativeAdvancedBlendEquationTests.hpp"
 #include "es31fNegativeShaderStorageTests.hpp"
 #include "es31fNegativeTessellationTests.hpp"
+#include "es31fNegativeComputeTests.hpp"
+#include "es31fNegativeSampleVariablesTests.hpp"
+#include "es31fNegativeShaderFramebufferFetchTests.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -2960,6 +2963,9 @@
 	const vector<FunctionContainer> preciseFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions());
 	const vector<FunctionContainer> advancedBlendFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions());
 	const vector<FunctionContainer> shaderStorageFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderStorageTestFunctions());
+	const vector<FunctionContainer> sampleVariablesFuncs	 = wrapCoreFunctions(NegativeTestShared::getNegativeSampleVariablesTestFunctions());
+	const vector<FunctionContainer> computeFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativeComputeTestFunctions());
+	const vector<FunctionContainer> framebufferFetchFuncs    = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFramebufferFetchTestFunctions());
 	const vector<FunctionContainer> externalFuncs			 = getUserMessageFuncs();
 
 	{
@@ -3068,6 +3074,9 @@
 			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "advanced_blend",				"Negative Advanced Blend Equation Cases",			advancedBlendFuncs));
 			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_storage",				"Negative Shader Storage Cases",					shaderStorageFuncs));
 			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "tessellation",				"Negative Tessellation Cases",						tessellationFuncs));
+			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "oes_sample_variables",		"Negative Sample Variables Cases",					sampleVariablesFuncs));
+			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "compute",					"Negative Compute Cases",							computeFuncs));
+			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "framebuffer_fetch",			"Negative Framebuffer Fetch Cases",					framebufferFetchFuncs));
 		}
 
 		{
@@ -3093,6 +3102,9 @@
 			host->addChild(createChildCases(CASETYPE_LOG, m_context, "advanced_blend",			"Negative Advanced Blend Equation Cases",			advancedBlendFuncs));
 			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_storage",			"Negative Shader Storage Cases",					shaderStorageFuncs));
 			host->addChild(createChildCases(CASETYPE_LOG, m_context, "tessellation",			"Negative Tessellation Cases",						tessellationFuncs));
+			host->addChild(createChildCases(CASETYPE_LOG, m_context, "oes_sample_variables",	"Negative Sample Variables Cases",					sampleVariablesFuncs));
+			host->addChild(createChildCases(CASETYPE_LOG, m_context, "compute",					"Negative Compute Cases",							computeFuncs));
+			host->addChild(createChildCases(CASETYPE_LOG, m_context, "framebuffer_fetch",		"Negative Framebuffer Fetch Cases",					framebufferFetchFuncs));
 		}
 
 		{
@@ -3118,6 +3130,9 @@
 			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "advanced_blend",				"Negative Advanced Blend Equation Cases",			advancedBlendFuncs));
 			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_storage",				"Negative Shader Storage Cases",					shaderStorageFuncs));
 			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "tessellation",				"Negative Tessellation Cases",						tessellationFuncs));
+			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "oes_sample_variables",		"Negative Sample Variables Cases",					sampleVariablesFuncs));
+			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "compute",					"Negative Compute Cases",							computeFuncs));
+			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "framebuffer_fetch",			"Negative Framebuffer Fetch Cases",					framebufferFetchFuncs));
 		}
 	}
 
diff --git a/modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp b/modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp
new file mode 100644
index 0000000..7b68587
--- /dev/null
+++ b/modules/gles31/functional/es31fDrawElementsBaseVertexTests.cpp
@@ -0,0 +1,924 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief GL_EXT_draw_elements_base_vertex tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fDrawElementsBaseVertexTests.hpp"
+#include "deRandom.hpp"
+#include "deStringUtil.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuVectorUtil.hpp"
+#include "sglrGLContext.hpp"
+#include "glsDrawTest.hpp"
+#include "gluStrUtil.hpp"
+#include "gluPixelTransfer.hpp"
+#include "gluContextInfo.hpp"
+
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+
+#include <string>
+#include <set>
+
+using std::vector;
+using std::string;
+using tcu::TestLog;
+
+using namespace glw;
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace
+{
+
+enum TestIterationType
+{
+	TYPE_DRAW_COUNT,		// !< test with 1, 5, and 25 primitives
+	TYPE_INSTANCE_COUNT,	// !< test with 1, 4, and 11 instances
+
+	TYPE_LAST
+};
+
+static size_t getElementCount (gls::DrawTestSpec::Primitive primitive, size_t primitiveCount)
+{
+	switch (primitive)
+	{
+		case gls::DrawTestSpec::PRIMITIVE_POINTS:						return primitiveCount;
+		case gls::DrawTestSpec::PRIMITIVE_TRIANGLES:					return primitiveCount * 3;
+		case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:					return primitiveCount + 2;
+		case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:				return primitiveCount + 2;
+		case gls::DrawTestSpec::PRIMITIVE_LINES:						return primitiveCount * 2;
+		case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP:					return primitiveCount + 1;
+		case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP:					return (primitiveCount==1) ? (2) : (primitiveCount);
+		case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:				return primitiveCount * 4;
+		case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:			return primitiveCount + 3;
+		case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:			return primitiveCount * 6;
+		case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:		return primitiveCount * 2 + 4;
+		default:
+			DE_ASSERT(false);
+			return 0;
+	}
+}
+
+static void addRangeElementsToSpec (gls::DrawTestSpec& spec)
+{
+	if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
+	{
+		spec.indexMin = 0;
+		spec.indexMax = (int)getElementCount(spec.primitive, spec.primitiveCount);
+	}
+}
+
+static void addTestIterations (gls::DrawTest* test, gls::DrawTestSpec& spec, TestIterationType type)
+{
+	if (type == TYPE_DRAW_COUNT)
+	{
+		spec.primitiveCount = 1;
+		addRangeElementsToSpec(spec);
+		test->addIteration(spec, "draw count = 1");
+
+		spec.primitiveCount = 5;
+		addRangeElementsToSpec(spec);
+		test->addIteration(spec, "draw count = 5");
+
+		spec.primitiveCount = 25;
+		addRangeElementsToSpec(spec);
+		test->addIteration(spec, "draw count = 25");
+	}
+	else if (type == TYPE_INSTANCE_COUNT)
+	{
+		spec.instanceCount = 1;
+		addRangeElementsToSpec(spec);
+		test->addIteration(spec, "instance count = 1");
+
+		spec.instanceCount = 4;
+		addRangeElementsToSpec(spec);
+		test->addIteration(spec, "instance count = 4");
+
+		spec.instanceCount = 11;
+		addRangeElementsToSpec(spec);
+		test->addIteration(spec, "instance count = 11");
+	}
+	else
+		DE_ASSERT(false);
+}
+
+static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
+{
+	spec.apiType							= glu::ApiType::es(3,1);
+	spec.primitive							= gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
+	spec.primitiveCount						= 5;
+	spec.drawMethod							= method;
+	spec.indexType							= gls::DrawTestSpec::INDEXTYPE_LAST;
+	spec.indexPointerOffset					= 0;
+	spec.indexStorage						= gls::DrawTestSpec::STORAGE_LAST;
+	spec.first								= 0;
+	spec.indexMin							= 0;
+	spec.indexMax							= 0;
+	spec.instanceCount						= 1;
+	spec.indirectOffset						= 0;
+
+	spec.attribs.resize(2);
+
+	spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+	spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+	spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
+	spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+	spec.attribs[0].componentCount			= 4;
+	spec.attribs[0].offset					= 0;
+	spec.attribs[0].stride					= 0;
+	spec.attribs[0].normalize				= false;
+	spec.attribs[0].instanceDivisor			= 0;
+	spec.attribs[0].useDefaultAttribute		= false;
+
+	spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+	spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+	spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
+	spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+	spec.attribs[1].componentCount			= 2;
+	spec.attribs[1].offset					= 0;
+	spec.attribs[1].stride					= 0;
+	spec.attribs[1].normalize				= false;
+	spec.attribs[1].instanceDivisor			= 0;
+	spec.attribs[1].useDefaultAttribute		= false;
+
+	addRangeElementsToSpec(spec);
+}
+
+class VertexIDCase : public TestCase
+{
+public:
+									VertexIDCase			(Context& context, gls::DrawTestSpec::DrawMethod drawMethod);
+									~VertexIDCase			(void);
+
+	void							init					(void);
+	void							deinit					(void);
+	IterateResult					iterate					(void);
+
+	void							draw					(GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex);
+	void							verifyImage				(const tcu::Surface& image);
+
+private:
+	const glw::Functions&			m_gl;
+	glu::ShaderProgram*				m_program;
+	GLuint							m_coordinatesBuffer;
+	GLuint							m_elementsBuffer;
+	int								m_iterNdx;
+	gls::DrawTestSpec::DrawMethod	m_method;
+
+	enum
+	{
+		VIEWPORT_WIDTH = 64,
+		VIEWPORT_HEIGHT = 64
+	};
+
+	enum
+	{
+		MAX_VERTICES = 2*3	//!< 2 triangles, totals 6 vertices
+	};
+};
+
+VertexIDCase::VertexIDCase (Context& context,  gls::DrawTestSpec::DrawMethod drawMethod)
+	: TestCase				(context, "vertex_id", "gl_VertexID Test")
+	, m_gl					(m_context.getRenderContext().getFunctions())
+	, m_program				(DE_NULL)
+	, m_coordinatesBuffer	(0)
+	, m_elementsBuffer		(0)
+	, m_iterNdx				(0)
+	, m_method				(drawMethod)
+{
+}
+
+VertexIDCase::~VertexIDCase (void)
+{
+	VertexIDCase::deinit();
+}
+
+void VertexIDCase::init (void)
+{
+	if (m_method == deqp::gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX ||
+		m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX ||
+		m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
+	{
+		const bool supportsES32 = contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+		TCU_CHECK_AND_THROW(NotSupportedError, supportsES32 || m_context.getContextInfo().isExtensionSupported("GL_EXT_draw_elements_base_vertex"), "GL_EXT_draw_elements_base_vertex is not supported.");
+	}
+
+	m_testCtx.getLog()	<< TestLog::Message
+						<< "gl_VertexID should be the index of the vertex that is being passed to the shader. i.e. indices[i] + basevertex"
+						<< TestLog::EndMessage;
+
+	DE_ASSERT(!m_program);
+	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(
+		"#version 310 es\n"
+		"in highp vec4 a_position;\n"
+		"out mediump vec4 v_color;\n"
+		"uniform highp vec4 u_colors[8];\n"
+		"void main (void)\n"
+		"{\n"
+		"	gl_Position = a_position;\n"
+		"	v_color = u_colors[gl_VertexID];\n"
+		"}\n",
+
+		"#version 310 es\n"
+		"in mediump vec4 v_color;\n"
+		"layout(location = 0) out mediump vec4 o_color;\n"
+		"void main (void)\n"
+		"{\n"
+		"	o_color = v_color;\n"
+		"}\n"));
+
+	m_testCtx.getLog() << *m_program;
+
+	if (!m_program->isOk())
+	{
+		delete m_program;
+		m_program = DE_NULL;
+		TCU_FAIL("Failed to compile shader program");
+	}
+
+	GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
+
+	GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
+	GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_elementsBuffer));
+}
+
+void VertexIDCase::deinit (void)
+{
+	delete m_program;
+	m_program = DE_NULL;
+
+	if (m_elementsBuffer)
+	{
+		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_elementsBuffer));
+		m_elementsBuffer = 0;
+	}
+
+	if (m_coordinatesBuffer)
+	{
+		GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
+		m_coordinatesBuffer = 0;
+	}
+}
+
+void VertexIDCase::draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex)
+{
+	switch (m_method)
+	{
+		case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX:
+			GLU_CHECK_GLW_CALL(m_gl, drawElementsBaseVertex(mode, count, type, indices, baseVertex));
+			break;
+
+		case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX:
+		{
+			GLint maxElementsVertices = 0;
+			GLU_CHECK_GLW_CALL(m_gl, getIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementsVertices));
+			GLU_CHECK_GLW_CALL(m_gl, drawRangeElementsBaseVertex(mode, 0, maxElementsVertices, count, type, indices, baseVertex));
+			break;
+		}
+
+		case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX:
+				GLU_CHECK_GLW_CALL(m_gl, drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex));
+				break;
+
+		default:
+			DE_FATAL("Draw method not supported");
+	}
+}
+
+void VertexIDCase::verifyImage (const tcu::Surface& image)
+{
+	tcu::TestLog&	log				= m_testCtx.getLog();
+	bool			isOk			= true;
+
+	const int		colorThreshold	= 0; // expect perfect match
+	tcu::Surface	error			(image.getWidth(), image.getHeight());
+
+	for (int y = 0; y < image.getHeight(); y++)
+	for (int x = 0; x < image.getWidth(); x++)
+	{
+		const tcu::RGBA pixel = image.getPixel(x, y);
+		bool pixelOk = true;
+
+		// Ignore pixels not drawn with basevertex
+		if ((x < image.getWidth()* 1/4) || (x > image.getWidth()  * 3/4)
+			|| (y < image.getHeight() * 1/4) || (y > image.getHeight() * 3/4))
+			continue;
+
+		// Any pixel with !(B ~= 255) is faulty
+		if (de::abs(pixel.getBlue() - 255) > colorThreshold)
+			pixelOk = false;
+
+		error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
+		isOk = isOk && pixelOk;
+	}
+
+	if (!isOk)
+	{
+		log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
+		log << TestLog::ImageSet("Verification result", "Result of rendering")
+			<< TestLog::Image("Result",		"Result",		image)
+			<< TestLog::Image("Error Mask",	"Error mask",	error)
+			<< TestLog::EndImageSet;
+	}
+	else
+	{
+		log << TestLog::ImageSet("Verification result", "Result of rendering")
+			<< TestLog::Image("Result", "Result", image)
+			<< TestLog::EndImageSet;
+	}
+
+	if (isOk)
+		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+	else
+		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
+}
+
+VertexIDCase::IterateResult VertexIDCase::iterate (void)
+{
+	const GLuint			drawCount			= 6;
+	const GLuint			baseVertex			= 4;
+	const GLuint			coordLocation		= m_gl.getAttribLocation(m_program->getProgram(), "a_position");
+	const GLuint			colorLocation		= m_gl.getUniformLocation(m_program->getProgram(), "u_colors[0]");
+
+	tcu::Surface			surface(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	const GLfloat coords[] =
+	{
+		// full viewport quad
+		-1.0f, -1.0f,
+		+1.0f, -1.0f,
+		+1.0f, +1.0f,
+		-1.0f, +1.0f,
+
+		// half viewport quad centred
+		-0.5f, -0.5f,
+		+0.5f, -0.5f,
+		+0.5f, +0.5f,
+		-0.5f, +0.5f,
+	};
+
+	const GLushort indices[] =
+	{
+		0, 1, 2, 2, 3, 0,
+	};
+
+	const GLfloat colors[] =
+	{
+		0.0f, 0.0f, 0.0f, 1.0f,
+		0.5f, 1.0f, 0.5f, 1.0f,
+		0.0f, 0.5f, 1.0f, 1.0f,
+		0.0f, 1.0f, 0.0f, 1.0f,
+
+		0.0f, 0.0f, 1.0f, 1.0f, // blue
+		0.0f, 0.0f, 1.0f, 1.0f, // blue
+		0.0f, 0.0f, 1.0f, 1.0f, // blue
+		0.0f, 0.0f, 1.0f, 1.0f, // blue
+	};
+
+	GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT));
+	GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 1.0f, 1.0f, 1.0f)); // white
+	GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
+
+	GLU_CHECK_GLW_CALL(m_gl, uniform4fv(colorLocation, DE_LENGTH_OF_ARRAY(colors), &colors[0]));
+
+	GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
+	GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
+	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
+	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
+
+	if (m_iterNdx == 0)
+	{
+		tcu::ScopedLogSection	logSection	(m_testCtx.getLog(), "Iter0", "Indices in client-side array");
+		draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, (GLvoid*)indices, baseVertex);
+	}
+
+	if (m_iterNdx == 1)
+	{
+		tcu::ScopedLogSection	logSection	(m_testCtx.getLog(), "Iter1", "Indices in element array buffer");
+		GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsBuffer));
+		GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW));
+		draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, DE_NULL, baseVertex);
+	}
+
+	glu::readPixels(m_context.getRenderContext(), 0, 0, surface.getAccess());
+	verifyImage(surface);
+
+	m_iterNdx += 1;
+
+	return (m_iterNdx < 2) ? CONTINUE : STOP;
+}
+
+class BuiltInVariableGroup : public TestCaseGroup
+{
+public:
+									BuiltInVariableGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+									~BuiltInVariableGroup		(void);
+
+	void							init						(void);
+
+private:
+	gls::DrawTestSpec::DrawMethod	m_method;
+};
+
+BuiltInVariableGroup::BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+	: TestCaseGroup		(context, name, descr)
+	, m_method			(drawMethod)
+{
+}
+
+BuiltInVariableGroup::~BuiltInVariableGroup (void)
+{
+}
+
+void BuiltInVariableGroup::init (void)
+{
+	addChild(new VertexIDCase(m_context, m_method));
+}
+
+class IndexGroup : public TestCaseGroup
+{
+public:
+									IndexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+									~IndexGroup		(void);
+
+	void							init			(void);
+
+private:
+	gls::DrawTestSpec::DrawMethod	m_method;
+};
+
+IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+	: TestCaseGroup		(context, name, descr)
+	, m_method			(drawMethod)
+{
+}
+
+IndexGroup::~IndexGroup (void)
+{
+}
+
+void IndexGroup::init (void)
+{
+	struct IndexTest
+	{
+		gls::DrawTestSpec::IndexType	type;
+		int								offsets[3];
+	};
+
+	const IndexTest tests[] =
+	{
+		{ gls::DrawTestSpec::INDEXTYPE_BYTE,	{ 0, 1, -1 } },
+		{ gls::DrawTestSpec::INDEXTYPE_SHORT,	{ 0, 2, -1 } },
+		{ gls::DrawTestSpec::INDEXTYPE_INT,		{ 0, 4, -1 } },
+	};
+
+	gls::DrawTestSpec spec;
+	genBasicSpec(spec, m_method);
+
+	spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
+
+	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
+	{
+		const IndexTest&	indexTest	= tests[testNdx];
+
+		const std::string	name		= std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+		const std::string	desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+		gls::DrawTest*		test		= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
+
+		spec.indexType			= indexTest.type;
+
+		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
+		{
+			const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
+			spec.indexPointerOffset	= indexTest.offsets[iterationNdx];
+			test->addIteration(spec, iterationDesc.c_str());
+		}
+
+		addChild(test);
+	}
+}
+
+class BaseVertexGroup : public TestCaseGroup
+{
+public:
+									BaseVertexGroup		(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+									~BaseVertexGroup	(void);
+
+	void							init				(void);
+
+private:
+	gls::DrawTestSpec::DrawMethod	m_method;
+};
+
+BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+	: TestCaseGroup		(context, name, descr)
+	, m_method			(drawMethod)
+{
+}
+
+BaseVertexGroup::~BaseVertexGroup (void)
+{
+}
+
+void BaseVertexGroup::init (void)
+{
+	struct IndexTest
+	{
+		bool							positiveBase;
+		gls::DrawTestSpec::IndexType	type;
+		int								baseVertex[2];
+	};
+
+	const IndexTest tests[] =
+	{
+		{ true,  gls::DrawTestSpec::INDEXTYPE_BYTE,		{  1,  2 } },
+		{ true,  gls::DrawTestSpec::INDEXTYPE_SHORT,	{  1,  2 } },
+		{ true,  gls::DrawTestSpec::INDEXTYPE_INT,		{  1,  2 } },
+		{ false, gls::DrawTestSpec::INDEXTYPE_BYTE,		{ -1, -2 } },
+		{ false, gls::DrawTestSpec::INDEXTYPE_SHORT,	{ -1, -2 } },
+		{ false, gls::DrawTestSpec::INDEXTYPE_INT,		{ -1, -2 } },
+	};
+
+	gls::DrawTestSpec spec;
+	genBasicSpec(spec, m_method);
+
+	spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
+
+	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
+	{
+		const IndexTest&	indexTest	= tests[testNdx];
+
+		const std::string	name		= std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+		const std::string	desc		= std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
+		gls::DrawTest*		test		= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
+
+		spec.indexType			= indexTest.type;
+
+		for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
+		{
+			const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
+			spec.baseVertex	= indexTest.baseVertex[iterationNdx];
+			// spec.indexMin + spec.baseVertex can not be a negative value
+			if (spec.indexMin + spec.baseVertex < 0)
+			{
+				spec.indexMax -= (spec.indexMin + spec.baseVertex);
+				spec.indexMin -= (spec.indexMin + spec.baseVertex);
+			}
+			test->addIteration(spec, iterationDesc.c_str());
+		}
+
+		addChild(test);
+	}
+}
+
+class AttributeGroup : public TestCaseGroup
+{
+public:
+									AttributeGroup	(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
+									~AttributeGroup	(void);
+
+	void							init			(void);
+
+private:
+	gls::DrawTestSpec::DrawMethod	m_method;
+	gls::DrawTestSpec::Primitive	m_primitive;
+	gls::DrawTestSpec::IndexType	m_indexType;
+	gls::DrawTestSpec::Storage		m_indexStorage;
+};
+
+AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
+	: TestCaseGroup		(context, name, descr)
+	, m_method			(drawMethod)
+	, m_primitive		(primitive)
+	, m_indexType		(indexType)
+	, m_indexStorage	(indexStorage)
+{
+}
+
+AttributeGroup::~AttributeGroup (void)
+{
+}
+
+void AttributeGroup::init (void)
+{
+	// Single attribute
+	{
+		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
+		gls::DrawTestSpec	spec;
+
+		spec.apiType							= glu::ApiType::es(3,1);
+		spec.primitive							= m_primitive;
+		spec.primitiveCount						= 5;
+		spec.drawMethod							= m_method;
+		spec.indexType							= m_indexType;
+		spec.indexPointerOffset					= 0;
+		spec.indexStorage						= m_indexStorage;
+		spec.first								= 0;
+		spec.indexMin							= 0;
+		spec.indexMax							= 0;
+		spec.instanceCount						= 1;
+		spec.indirectOffset						= 0;
+
+		spec.attribs.resize(1);
+
+		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[0].componentCount			= 2;
+		spec.attribs[0].offset					= 0;
+		spec.attribs[0].stride					= 0;
+		spec.attribs[0].normalize				= false;
+		spec.attribs[0].instanceDivisor			= 0;
+		spec.attribs[0].useDefaultAttribute		= false;
+
+		addTestIterations(test, spec, TYPE_DRAW_COUNT);
+
+		this->addChild(test);
+	}
+
+	// Multiple attribute
+	{
+		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
+		gls::DrawTestSpec	spec;
+
+		spec.apiType							= glu::ApiType::es(3,1);
+		spec.primitive							= m_primitive;
+		spec.primitiveCount						= 5;
+		spec.drawMethod							= m_method;
+		spec.indexType							= m_indexType;
+		spec.indexPointerOffset					= 0;
+		spec.indexStorage						= m_indexStorage;
+		spec.first								= 0;
+		spec.indexMin							= 0;
+		spec.indexMax							= 0;
+		spec.instanceCount						= 1;
+		spec.indirectOffset						= 0;
+
+		spec.attribs.resize(2);
+
+		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[0].componentCount			= 4;
+		spec.attribs[0].offset					= 0;
+		spec.attribs[0].stride					= 0;
+		spec.attribs[0].normalize				= false;
+		spec.attribs[0].instanceDivisor			= 0;
+		spec.attribs[0].useDefaultAttribute		= false;
+
+		spec.attribs[1].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[1].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[1].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[1].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[1].componentCount			= 2;
+		spec.attribs[1].offset					= 0;
+		spec.attribs[1].stride					= 0;
+		spec.attribs[1].normalize				= false;
+		spec.attribs[1].instanceDivisor			= 0;
+		spec.attribs[1].useDefaultAttribute		= false;
+
+		addTestIterations(test, spec, TYPE_DRAW_COUNT);
+
+		this->addChild(test);
+	}
+
+	// Multiple attribute, second one divided
+	{
+		gls::DrawTest*		test					= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
+		gls::DrawTestSpec	spec;
+
+		spec.apiType								= glu::ApiType::es(3,1);
+		spec.primitive								= m_primitive;
+		spec.primitiveCount							= 5;
+		spec.drawMethod								= m_method;
+		spec.indexType								= m_indexType;
+		spec.indexPointerOffset						= 0;
+		spec.indexStorage							= m_indexStorage;
+		spec.first									= 0;
+		spec.indexMin								= 0;
+		spec.indexMax								= 0;
+		spec.instanceCount							= 1;
+		spec.indirectOffset							= 0;
+
+		spec.attribs.resize(3);
+
+		spec.attribs[0].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[0].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[0].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[0].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[0].componentCount				= 4;
+		spec.attribs[0].offset						= 0;
+		spec.attribs[0].stride						= 0;
+		spec.attribs[0].normalize					= false;
+		spec.attribs[0].instanceDivisor				= 0;
+		spec.attribs[0].useDefaultAttribute			= false;
+
+		// Add another position component so the instances wont be drawn on each other
+		spec.attribs[1].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[1].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[1].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[1].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[1].componentCount				= 2;
+		spec.attribs[1].offset						= 0;
+		spec.attribs[1].stride						= 0;
+		spec.attribs[1].normalize					= false;
+		spec.attribs[1].instanceDivisor				= 1;
+		spec.attribs[1].useDefaultAttribute			= false;
+		spec.attribs[1].additionalPositionAttribute	= true;
+
+		// Instanced color
+		spec.attribs[2].inputType					= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[2].outputType					= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[2].storage						= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[2].usage						= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[2].componentCount				= 3;
+		spec.attribs[2].offset						= 0;
+		spec.attribs[2].stride						= 0;
+		spec.attribs[2].normalize					= false;
+		spec.attribs[2].instanceDivisor				= 1;
+		spec.attribs[2].useDefaultAttribute			= false;
+
+		addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
+
+		this->addChild(test);
+	}
+
+	// Multiple attribute, second one default
+	{
+		gls::DrawTest*		test				= new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
+		gls::DrawTestSpec	spec;
+
+		spec.apiType							= glu::ApiType::es(3,1);
+		spec.primitive							= m_primitive;
+		spec.primitiveCount						= 5;
+		spec.drawMethod							= m_method;
+		spec.indexType							= m_indexType;
+		spec.indexPointerOffset					= 0;
+		spec.indexStorage						= m_indexStorage;
+		spec.first								= 0;
+		spec.indexMin							= 0;
+		spec.indexMax							= 0;
+		spec.instanceCount						= 1;
+		spec.indirectOffset						= 0;
+
+		spec.attribs.resize(2);
+
+		spec.attribs[0].inputType				= gls::DrawTestSpec::INPUTTYPE_FLOAT;
+		spec.attribs[0].outputType				= gls::DrawTestSpec::OUTPUTTYPE_VEC2;
+		spec.attribs[0].storage					= gls::DrawTestSpec::STORAGE_BUFFER;
+		spec.attribs[0].usage					= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+		spec.attribs[0].componentCount			= 2;
+		spec.attribs[0].offset					= 0;
+		spec.attribs[0].stride					= 0;
+		spec.attribs[0].normalize				= false;
+		spec.attribs[0].instanceDivisor			= 0;
+		spec.attribs[0].useDefaultAttribute		= false;
+
+		struct IOPair
+		{
+			gls::DrawTestSpec::InputType  input;
+			gls::DrawTestSpec::OutputType output;
+			int							  componentCount;
+		} iopairs[] =
+		{
+			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,		 gls::DrawTestSpec::OUTPUTTYPE_VEC2,  4 },
+			{ gls::DrawTestSpec::INPUTTYPE_FLOAT,		 gls::DrawTestSpec::OUTPUTTYPE_VEC4,  2 },
+			{ gls::DrawTestSpec::INPUTTYPE_INT,			 gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
+			{ gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
+		};
+
+		for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
+		{
+			const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
+
+			spec.attribs[1].inputType			= iopairs[ioNdx].input;
+			spec.attribs[1].outputType			= iopairs[ioNdx].output;
+			spec.attribs[1].storage				= gls::DrawTestSpec::STORAGE_BUFFER;
+			spec.attribs[1].usage				= gls::DrawTestSpec::USAGE_STATIC_DRAW;
+			spec.attribs[1].componentCount		= iopairs[ioNdx].componentCount;
+			spec.attribs[1].offset				= 0;
+			spec.attribs[1].stride				= 0;
+			spec.attribs[1].normalize			= false;
+			spec.attribs[1].instanceDivisor		= 0;
+			spec.attribs[1].useDefaultAttribute	= true;
+
+			test->addIteration(spec, desc.c_str());
+		}
+
+		this->addChild(test);
+	}
+}
+
+class MethodGroup : public TestCaseGroup
+{
+public:
+									MethodGroup			(Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
+									~MethodGroup		(void);
+
+	void							init				(void);
+
+private:
+	gls::DrawTestSpec::DrawMethod	m_method;
+};
+
+MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
+	: TestCaseGroup		(context, name, descr)
+	, m_method			(drawMethod)
+{
+}
+
+MethodGroup::~MethodGroup (void)
+{
+}
+
+void MethodGroup::init (void)
+{
+	const bool indexed		=	(m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
+							||	(m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
+							||	(m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX);
+
+	const gls::DrawTestSpec::Primitive primitive[] =
+	{
+		gls::DrawTestSpec::PRIMITIVE_POINTS,
+		gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
+		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
+		gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
+		gls::DrawTestSpec::PRIMITIVE_LINES,
+		gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
+		gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
+	};
+
+	if (indexed)
+	{
+		// Index-tests
+		this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
+		this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
+		this->addChild(new BuiltInVariableGroup(m_context, "builtin_variable", "Built in shader variable tests", m_method));
+	}
+
+	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
+	{
+		const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
+		const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
+
+		this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
+	}
+}
+
+} // anonymous
+
+DrawElementsBaseVertexTests::DrawElementsBaseVertexTests (Context& context)
+	: TestCaseGroup(context, "draw_base_vertex", "Base vertex extension drawing tests")
+{
+}
+
+DrawElementsBaseVertexTests::~DrawElementsBaseVertexTests (void)
+{
+}
+
+void DrawElementsBaseVertexTests::init (void)
+{
+	const gls::DrawTestSpec::DrawMethod basicMethods[] =
+	{
+		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
+		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
+		gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
+	};
+
+	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
+	{
+		const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
+		const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
+
+		this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
+	}
+}
+
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fDrawElementsBaseVertexTests.hpp b/modules/gles31/functional/es31fDrawElementsBaseVertexTests.hpp
new file mode 100644
index 0000000..f3d349b
--- /dev/null
+++ b/modules/gles31/functional/es31fDrawElementsBaseVertexTests.hpp
@@ -0,0 +1,53 @@
+#ifndef _ES31FDRAWELEMENTSBASEVERTEXTESTS_HPP
+#define _ES31FDRAWELEMENTSBASEVERTEXTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief GL_EXT_draw_elements_base_vertex tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes31TestCase.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+
+class DrawElementsBaseVertexTests : public TestCaseGroup
+{
+public:
+									DrawElementsBaseVertexTests		(Context& context);
+									~DrawElementsBaseVertexTests	(void);
+
+	void							init							(void);
+
+private:
+									DrawElementsBaseVertexTests		(const DrawElementsBaseVertexTests& other);
+	DrawElementsBaseVertexTests&	operator=						(const DrawElementsBaseVertexTests& other);
+};
+
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FDRAWELEMENTSBASEVERTEXTESTS_HPP
diff --git a/modules/gles31/functional/es31fDrawTests.cpp b/modules/gles31/functional/es31fDrawTests.cpp
index 2b8b11c..daa5307 100644
--- a/modules/gles31/functional/es31fDrawTests.cpp
+++ b/modules/gles31/functional/es31fDrawTests.cpp
@@ -1276,17 +1276,18 @@
 			buf	<< "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && gl_GlobalInvocationID.z == 0u) {\n"
 				<< "        uint        y           = gl_GlobalInvocationID.x;\n"
 				<< "        uint        x           = gl_GlobalInvocationID.y;\n"
-				<< "        float       posX        = (float(x) / float(gridSize)) * 2.0 - 1.0;\n"
-				<< "        float       posY        = (float(y) / float(gridSize)) * 2.0 - 1.0;\n"
-				<< "        const float cellSize    = 2.0 / float(gridSize);\n"
+				<< "        float       posX        = (float(x)    / float(gridSize)) * 2.0 - 1.0;\n"
+				<< "        float       posXp1      = (float(x+1u) / float(gridSize)) * 2.0 - 1.0;\n"
+				<< "        float       posY        = (float(y)    / float(gridSize)) * 2.0 - 1.0;\n"
+				<< "        float       posYp1      = (float(y+1u) / float(gridSize)) * 2.0 - 1.0;\n"
 				<< "        vec4        color       = ((x + y)%2u != 0u) ? (yellow) : (green);\n"
 				<< "\n"
-				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 0u] = vec4(posX,            posY,            0.0, 1.0);\n"
-				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 0u] = vec4(posX + cellSize, posY,            0.0, 1.0);\n"
-				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 0u] = vec4(posX + cellSize, posY + cellSize, 0.0, 1.0);\n"
-				<< "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 0u] = vec4(posX,            posY,            0.0, 1.0);\n"
-				<< "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 0u] = vec4(posX + cellSize, posY + cellSize, 0.0, 1.0);\n"
-				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 0u] = vec4(posX,            posY + cellSize, 0.0, 1.0);\n"
+				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 0u] = vec4(posX,   posY,   0.0, 1.0);\n"
+				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 0u] = vec4(posXp1, posY,   0.0, 1.0);\n"
+				<< "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 0u] = vec4(posXp1, posYp1, 0.0, 1.0);\n"
+				<< "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 0u] = vec4(posX,   posY,   0.0, 1.0);\n"
+				<< "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 0u] = vec4(posXp1, posYp1, 0.0, 1.0);\n"
+				<< "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 0u] = vec4(posX,   posYp1, 0.0, 1.0);\n"
 				<< "\n"
 				<< "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 1u] = color;\n"
 				<< "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 1u] = color;\n"
diff --git a/modules/gles31/functional/es31fFboSRGBWriteControlTests.cpp b/modules/gles31/functional/es31fFboSRGBWriteControlTests.cpp
new file mode 100644
index 0000000..b4ebcac
--- /dev/null
+++ b/modules/gles31/functional/es31fFboSRGBWriteControlTests.cpp
@@ -0,0 +1,1898 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief FBO sRGB tests.
+*//*--------------------------------------------------------------------*/
+
+#include "es31fFboSRGBWriteControlTests.hpp"
+#include "es31fFboTestUtil.hpp"
+#include "gluTextureUtil.hpp"
+#include "gluContextInfo.hpp"
+#include "tcuTestLog.hpp"
+#include "glwEnums.hpp"
+#include "sglrContextUtil.hpp"
+#include "glwFunctions.hpp"
+#include "deUniquePtr.hpp"
+#include "deSharedPtr.hpp"
+#include "gluObjectWrapper.hpp"
+#include "gluPixelTransfer.hpp"
+#include "glsTextureTestUtil.hpp"
+#include "tcuVectorUtil.hpp"
+#include "gluStrUtil.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace
+{
+
+tcu::Vec4 getTestColorLinear (void)
+{
+	return tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f);
+}
+
+tcu::Vec4 getTestColorSRGB (void)
+{
+	return linearToSRGB(tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f));
+}
+
+tcu::Vec4 getTestColorBlank (void)
+{
+	return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
+}
+
+tcu::Vec4 getEpsilonError (void)
+{
+	return tcu::Vec4(0.005f);
+}
+
+enum QueryType
+{
+	QUERYTYPE_ISENABLED = 0,
+	QUERYTYPE_BOOLEAN,
+	QUERYTYPE_FLOAT,
+	QUERYTYPE_INT,
+	QUERYTYPE_INT64,
+	QUERYTYPE_LAST
+};
+
+enum DataType
+{
+	DATATYPE_BOOLEAN = 0,
+	DATATYPE_FLOAT,
+	DATATYPE_INT,
+	DATATYPE_INT64,
+};
+
+enum FramebufferSRGB
+{
+	FRAMEBUFFERSRGB_ENABLED = 0,
+	FRAMEBUFFERSRGB_DISABLED
+};
+
+enum FramebufferBlend
+{
+	FRAMEBUFFERBLEND_ENABLED = 0,
+	FRAMEBUFFERBLEND_DISABLED
+};
+
+enum TextureSourcesType
+{
+	TEXTURESOURCESTYPE_RGBA		= 0,
+	TEXTURESOURCESTYPE_SRGBA,
+	TEXTURESOURCESTYPE_BOTH,
+	TEXTURESOURCESTYPE_NONE
+};
+
+enum FboType
+{
+	FBOTYPE_SOURCE			= 0,
+	FBOTYPE_DESTINATION
+};
+
+enum RendererTask
+{
+	RENDERERTASK_DRAW = 0,
+	RENDERERTASK_COPY
+};
+
+enum SamplingType
+{
+	SAMPLINGTYPE_TEXTURE			= 0,
+	SAMPLINGTYPE_TEXTURE_LOD,
+	SAMPLINGTYPE_TEXTURE_GRAD,
+	SAMPLINGTYPE_TEXTURE_OFFSET,
+	SAMPLINGTYPE_TEXTURE_PROJ,
+};
+
+namespace TestTextureSizes
+{
+	const int WIDTH = 128;
+	const int HEIGHT = 128;
+} // global test texture sizes
+
+namespace SampligTypeCount
+{
+	const int MAX = 5;
+} // global max number of sampling types
+
+std::string buildSamplingPassType (const int samplerTotal)
+{
+	std::ostringstream	shaderFragment;
+
+	const SamplingType	samplingTypeList [] =
+	{
+		SAMPLINGTYPE_TEXTURE, SAMPLINGTYPE_TEXTURE_LOD, SAMPLINGTYPE_TEXTURE_GRAD, SAMPLINGTYPE_TEXTURE_OFFSET, SAMPLINGTYPE_TEXTURE_PROJ
+	} ;
+
+	for (int samplerTypeIdx = 0; samplerTypeIdx < DE_LENGTH_OF_ARRAY(samplingTypeList); samplerTypeIdx++)
+	{
+		shaderFragment
+			<< "	if (uFunctionType == " << samplerTypeIdx << ") \n"
+			<< "	{ \n";
+
+		for (int samplerIdx = 0; samplerIdx < samplerTotal; samplerIdx++)
+		{
+			switch (static_cast<SamplingType>(samplerTypeIdx))
+			{
+				case SAMPLINGTYPE_TEXTURE:
+				{
+					shaderFragment
+						<< "		texelColor" << samplerIdx << " = texture(uTexture" << samplerIdx << ", vs_aTexCoord); \n";
+					break;
+				}
+				case SAMPLINGTYPE_TEXTURE_LOD:
+				{
+					shaderFragment
+						<< "		texelColor" << samplerIdx << " = textureLod(uTexture" << samplerIdx << ", vs_aTexCoord, 0.0f); \n";
+					break;
+				}
+				case SAMPLINGTYPE_TEXTURE_GRAD:
+				{
+					shaderFragment
+						<< "		texelColor" << samplerIdx << " = textureGrad(uTexture" << samplerIdx << ", vs_aTexCoord, vec2(0.0f, 0.0f), vec2(0.0f, 0.0f)); \n";
+					break;
+				}
+				case SAMPLINGTYPE_TEXTURE_OFFSET:
+				{
+					shaderFragment
+						<< "		texelColor" << samplerIdx << " = textureOffset(uTexture" << samplerIdx << ", vs_aTexCoord, ivec2(0.0f, 0.0f)); \n";
+					break;
+				}
+				case SAMPLINGTYPE_TEXTURE_PROJ:
+				{
+					shaderFragment
+						<< "		texelColor" << samplerIdx << " = textureProj(uTexture" << samplerIdx << ", vec3(vs_aTexCoord, 1.0f)); \n";
+					break;
+				}
+				default:
+					DE_FATAL("Error: sampling type unrecognised");
+			}
+		}
+
+		shaderFragment
+			<< "	} \n";
+	}
+
+	return shaderFragment.str();
+}
+
+void logColor (Context& context, const std::string& colorLogMessage, const tcu::Vec4 resultColor)
+{
+	tcu::TestLog&			log		= context.getTestContext().getLog();
+	std::ostringstream		message;
+
+	message << colorLogMessage << " = (" << resultColor.x() << ", " << resultColor.y() << ", " << resultColor.z() << ", " << resultColor.w() << ")";
+		log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+}
+
+struct TestFunction
+{
+	explicit TestFunction	(const bool hasFunctionValue)
+		: hasFunction		(hasFunctionValue) {}
+	TestFunction			(const char* const functionNameValue, const char* const functionDefinition)
+		: hasFunction		(true)
+		, functionName		(functionNameValue)
+		, functionDefintion	(functionDefinition) {}
+	~TestFunction			(void) {}
+
+	bool			hasFunction;
+	const char*		functionName;
+	const char*		functionDefintion;
+};
+
+TestFunction getFunctionBlendLinearToSRGBCheck (void)
+{
+	const char* const functionName = "blendPlusLinearToSRGB";
+
+	const char* const functionDefinition =
+		"mediump vec4 blendPlusLinearToSRGB(in mediump vec4 colorSrc, in mediump vec4 colorDst) \n"
+		"{ \n"
+		"	const int MAX_VECTOR_SIZE = 4; \n"
+		"	mediump vec4 colorConverted; \n"
+		"	mediump vec4 colorBlended; \n"
+		"	for (int idx = 0; idx < MAX_VECTOR_SIZE; idx++) \n"
+		"	{ \n"
+		"		if (uBlendFunctionType == 0) \n"
+		"		{ \n"
+		"			colorBlended[idx] = (colorSrc[idx] * uFactorSrc) + colorDst[idx] * uFactorDst; \n"
+		"		} \n"
+		"		if (uBlendFunctionType == 1) \n"
+		"		{ \n"
+		"			colorBlended[idx] = (colorSrc[idx] * uFactorSrc) - (colorDst[idx] * uFactorDst); \n"
+		"		} \n"
+				"if (uBlendFunctionType == 2) \n"
+		"		{ \n"
+		"			colorBlended[idx] = (colorDst[idx] * uFactorDst) - (colorSrc[idx] * uFactorSrc); \n"
+		"		} \n"
+		"		if (colorBlended[idx] < 0.0031308f) \n"
+		"		{ \n"
+		"			colorConverted[idx] = 12.92f * colorBlended[idx]; \n"
+		"		} \n"
+		"		else \n"
+		"		{ \n"
+		"			colorConverted[idx] = 1.055f * pow(colorBlended[idx], 0.41666f) - 0.055f; \n"
+		"		} \n"
+		"	} \n"
+		"	return colorConverted; \n"
+		"} \n";
+
+	TestFunction testFunction(functionName, functionDefinition);
+
+	return testFunction;
+}
+
+struct FBOConfig
+{
+	FBOConfig					(const deUint32 textureInternalFormatValue,
+								 const tcu::Vec4 textureColorValue,
+								 const deUint32 fboTargetTypeValue,
+								 const deUint32 fboColorAttachmentValue,
+								 const FboType fboTypeValue)
+		: textureInternalFormat	(textureInternalFormatValue)
+		, textureColor			(textureColorValue)
+		, fboTargetType			(fboTargetTypeValue)
+		, fboColorAttachment	(fboColorAttachmentValue)
+		, fboType				(fboTypeValue) {}
+	~FBOConfig					(void) {}
+
+	deUint32	textureInternalFormat;
+	tcu::Vec4	textureColor;
+	deUint32	fboTargetType;
+	deUint32	fboColorAttachment;
+	FboType		fboType;
+};
+
+struct BlendConfig
+{
+	deUint32	equation;
+	deUint32	funcSrc;
+	deUint32	funcDst;
+};
+
+std::vector<BlendConfig> getBlendingConfigList (void)
+{
+	BlendConfig blendConfigs[12];
+
+	// add function permutations
+	blendConfigs[0].equation = GL_FUNC_ADD;
+	blendConfigs[1].equation = GL_FUNC_ADD;
+	blendConfigs[2].equation = GL_FUNC_ADD;
+	blendConfigs[3].equation = GL_FUNC_ADD;
+
+	blendConfigs[0].funcSrc = GL_ONE;
+	blendConfigs[0].funcDst = GL_ONE;
+	blendConfigs[1].funcSrc = GL_ONE;
+	blendConfigs[1].funcDst = GL_ZERO;
+	blendConfigs[2].funcSrc = GL_ZERO;
+	blendConfigs[2].funcDst = GL_ONE;
+	blendConfigs[3].funcSrc = GL_ZERO;
+	blendConfigs[3].funcDst = GL_ZERO;
+
+	// subtract function permutations
+	blendConfigs[4].equation = GL_FUNC_SUBTRACT;
+	blendConfigs[5].equation = GL_FUNC_SUBTRACT;
+	blendConfigs[6].equation = GL_FUNC_SUBTRACT;
+	blendConfigs[7].equation = GL_FUNC_SUBTRACT;
+
+	blendConfigs[4].funcSrc = GL_ONE;
+	blendConfigs[4].funcDst = GL_ONE;
+	blendConfigs[5].funcSrc = GL_ONE;
+	blendConfigs[5].funcDst = GL_ZERO;
+	blendConfigs[6].funcSrc = GL_ZERO;
+	blendConfigs[6].funcDst = GL_ONE;
+	blendConfigs[7].funcSrc = GL_ZERO;
+	blendConfigs[7].funcDst = GL_ZERO;
+
+	// reverse subtract function permutations
+	blendConfigs[8].equation = GL_FUNC_REVERSE_SUBTRACT;
+	blendConfigs[9].equation = GL_FUNC_REVERSE_SUBTRACT;
+	blendConfigs[10].equation = GL_FUNC_REVERSE_SUBTRACT;
+	blendConfigs[11].equation = GL_FUNC_REVERSE_SUBTRACT;
+
+	blendConfigs[8].funcSrc = GL_ONE;
+	blendConfigs[8].funcDst = GL_ONE;
+	blendConfigs[9].funcSrc = GL_ONE;
+	blendConfigs[9].funcDst = GL_ZERO;
+	blendConfigs[10].funcSrc = GL_ZERO;
+	blendConfigs[10].funcDst = GL_ONE;
+	blendConfigs[11].funcSrc = GL_ZERO;
+	blendConfigs[11].funcDst = GL_ZERO;
+
+	std::vector<BlendConfig> configList(blendConfigs, blendConfigs + DE_LENGTH_OF_ARRAY(blendConfigs));
+
+	return configList;
+}
+
+struct TestRenderPassConfig
+{
+	TestRenderPassConfig		(void)
+		: testFunction			(false) {}
+
+	TestRenderPassConfig		(const TextureSourcesType textureSourcesTypeValue,
+								FBOConfig fboConfigListValue,
+								const FramebufferSRGB framebufferSRGBValue,
+								const FramebufferBlend framebufferBendValue,
+								const RendererTask rendererTaskValue)
+		: textureSourcesType	(textureSourcesTypeValue)
+		, framebufferSRGB		(framebufferSRGBValue)
+		, frameBufferBlend		(framebufferBendValue)
+		, testFunction			(false)
+		, rendererTask			(rendererTaskValue) {fboConfigList.push_back(fboConfigListValue);}
+
+	TestRenderPassConfig		(const TextureSourcesType textureSourcesTypeValue,
+								FBOConfig fboConfigListValue,
+								const FramebufferSRGB framebufferSRGBValue,
+								const FramebufferBlend framebufferBendValue,
+								TestFunction testFunctionValue,
+								const RendererTask rendererTaskValue)
+		: textureSourcesType	(textureSourcesTypeValue)
+		, framebufferSRGB		(framebufferSRGBValue)
+		, frameBufferBlend		(framebufferBendValue)
+		, testFunction			(testFunctionValue)
+		, rendererTask			(rendererTaskValue) {fboConfigList.push_back(fboConfigListValue);}
+
+	TestRenderPassConfig		(const TextureSourcesType textureSourcesTypeValue,
+								std::vector<FBOConfig> fboConfigListValue,
+								const FramebufferSRGB framebufferSRGBValue,
+								const FramebufferBlend framebufferBendValue,
+								TestFunction testFunctionValue,
+								const RendererTask rendererTaskValue)
+		: textureSourcesType	(textureSourcesTypeValue)
+		, fboConfigList			(fboConfigListValue)
+		, framebufferSRGB		(framebufferSRGBValue)
+		, frameBufferBlend		(framebufferBendValue)
+		, testFunction			(testFunctionValue)
+		, rendererTask			(rendererTaskValue) {}
+
+	~TestRenderPassConfig		(void) {}
+
+	TextureSourcesType		textureSourcesType;
+	std::vector<FBOConfig>	fboConfigList;
+	FramebufferSRGB			framebufferSRGB;
+	FramebufferBlend		frameBufferBlend;
+	TestFunction			testFunction;
+	RendererTask			rendererTask;
+};
+
+class TestVertexData
+{
+public:
+							TestVertexData		(Context& context);
+							~TestVertexData		(void);
+
+	void					init				(void);
+
+	void					bind				(void) const;
+	void					unbind				(void) const;
+
+private:
+	const glw::Functions*	m_gl;
+	std::vector<float>		m_data;
+	glw::GLuint				m_vboHandle;
+	glw::GLuint				m_vaoHandle;
+};
+
+TestVertexData::TestVertexData	(Context& context)
+	: m_gl						(&context.getRenderContext().getFunctions())
+{
+	const glw::GLfloat		vertexData[]	=
+	{
+		// position				// texcoord
+		-1.0f, -1.0f, 0.0f,		0.0f, 0.0f, // bottom left corner
+		 1.0f, -1.0f, 0.0f,		1.0f, 0.0f, // bottom right corner
+		 1.0f,  1.0f, 0.0f,		1.0f, 1.0f, // Top right corner
+
+		-1.0f,  1.0f, 0.0f,		0.0f, 1.0f, // top left corner
+		 1.0f,  1.0f, 0.0f,		1.0f, 1.0f, // Top right corner
+		-1.0f, -1.0f, 0.0f,		0.0f, 0.0f  // bottom left corner
+	};
+
+	m_data.resize(DE_LENGTH_OF_ARRAY(vertexData));
+	for (int idx = 0; idx < (int)m_data.size(); idx++)
+		m_data[idx] = vertexData[idx];
+
+	m_gl->genVertexArrays(1, &m_vaoHandle);
+	m_gl->bindVertexArray(m_vaoHandle);
+
+	m_gl->genBuffers(1, &m_vboHandle);
+	m_gl->bindBuffer(GL_ARRAY_BUFFER, m_vboHandle);
+
+	m_gl->bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)(m_data.size() * sizeof(glw::GLfloat)), &m_data[0], GL_STATIC_DRAW);
+
+	m_gl->enableVertexAttribArray(0);
+	m_gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)0);
+	m_gl->enableVertexAttribArray(1);
+	m_gl->vertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)(3 * sizeof(GL_FLOAT)));
+
+	m_gl->bindVertexArray(0);
+	m_gl->bindBuffer(GL_ARRAY_BUFFER, 0);
+	GLU_EXPECT_NO_ERROR(m_gl->getError(), "gl error during vertex data setup");
+}
+
+TestVertexData::~TestVertexData (void)
+{
+	m_gl->deleteBuffers(1, &m_vboHandle);
+	m_gl->deleteVertexArrays(1, &m_vaoHandle);
+}
+
+void TestVertexData::bind (void) const
+{
+	m_gl->bindVertexArray(m_vaoHandle);
+}
+
+void TestVertexData::unbind (void) const
+{
+	m_gl->bindVertexArray(0);
+}
+
+class TestTexture2D
+{
+public:
+								TestTexture2D		(Context& context, const deUint32 internalFormatValue, const deUint32 transferFormatValue, const deUint32 transferTypeValue, const tcu::Vec4 imageColorValue, const int idx);
+								~TestTexture2D		(void);
+
+	int							getTextureUnit		(void) const;
+	deUint32					getHandle			(void) const;
+	int							getIdx				(void) const;
+
+	void						bind				(const int textureUnit);
+	void						unbind				(void) const;
+
+private:
+	const glw::Functions*		m_gl;
+	glw::GLuint					m_handle;
+	const deUint32				m_internalFormat;
+	tcu::TextureFormat			m_transferFormat;
+	int							m_width;
+	int							m_height;
+	tcu::TextureLevel			m_imageData;
+	int							m_textureUnit;
+	const int					m_idx;
+};
+
+TestTexture2D::TestTexture2D	(Context& context, const deUint32 internalFormat, const deUint32 transferFormat, const deUint32 transferType, const tcu::Vec4 imageColor, const int idx)
+	: m_gl						(&context.getRenderContext().getFunctions())
+	, m_internalFormat			(internalFormat)
+	, m_transferFormat			(tcu::TextureFormat(glu::mapGLTransferFormat(transferFormat, transferType)))
+	, m_width					(TestTextureSizes::WIDTH)
+	, m_height					(TestTextureSizes::HEIGHT)
+	, m_imageData				(tcu::TextureLevel(glu::mapGLInternalFormat(internalFormat), m_width, m_height, 1))
+	, m_idx						(idx)
+{
+	// fill image data with a solid test color
+	tcu::clear(m_imageData.getAccess(), tcu::Vec4(0.0f));
+	for (int py = 0; py < m_imageData.getHeight(); py++)
+	{
+		for (int px = 0; px < m_imageData.getWidth(); px++)
+			m_imageData.getAccess().setPixel(imageColor, px, py);
+	}
+
+	m_gl->genTextures(1, &m_handle);
+
+	m_gl->bindTexture(GL_TEXTURE_2D, m_handle);
+	m_gl->texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_MIRRORED_REPEAT);
+	m_gl->texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_MIRRORED_REPEAT);
+	m_gl->texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
+	m_gl->texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
+
+	m_gl->texImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFormat, transferType, m_imageData.getAccess().getDataPtr());
+
+	m_gl->bindTexture(GL_TEXTURE_2D, 0);
+}
+
+TestTexture2D::~TestTexture2D (void)
+{
+	m_gl->deleteTextures(1, &m_handle);
+}
+
+int TestTexture2D::getTextureUnit (void) const
+{
+	return m_textureUnit;
+}
+
+deUint32 TestTexture2D::getHandle (void) const
+{
+	return m_handle;
+}
+
+int TestTexture2D::getIdx (void) const
+{
+	return m_idx;
+}
+
+void TestTexture2D::bind (const int textureUnit)
+{
+	m_textureUnit = textureUnit;
+	m_gl->activeTexture(GL_TEXTURE0 + m_textureUnit);
+	m_gl->bindTexture(GL_TEXTURE_2D, m_handle);
+}
+
+void TestTexture2D::unbind (void) const
+{
+	m_gl->bindTexture(GL_TEXTURE_2D, 0);
+}
+
+class TestFramebuffer
+{
+public:
+												TestFramebuffer			(void);
+												TestFramebuffer			(Context& context, const deUint32 targetType, const deUint32 colorAttachment, glw::GLuint textureAttachmentHandle, const bool isSRGB, const FboType fboType, const int idx);
+												~TestFramebuffer		(void);
+
+	void										setTargetType			(const deUint32 targetType);
+
+	FboType										getType					(void) const;
+	deUint32									getHandle				(void) const;
+	deUint32									getColorAttachment		(void) const;
+	int											getIdx					(void) const;
+	deUint32									getTargetType			(void) const;
+
+	void										bind					(void);
+	void										unbind					(void);
+
+	typedef de::UniquePtr<glu::Framebuffer>		fboUniquePtr;
+
+private:
+	const glw::Functions*						m_gl;
+	fboUniquePtr								m_referenceSource;
+	deUint32									m_targetType;
+	bool										m_bound;
+	bool										m_isSRGB;
+	FboType										m_type;
+	const int									m_idx;
+	deUint32									m_colorAttachment;
+};
+
+TestFramebuffer::TestFramebuffer	(Context& context, const deUint32 targetType, const deUint32 colorAttachment, glw::GLuint textureAttachmentHandle, const bool isSRGB, const FboType fboType, const int idx)
+	: m_gl							(&context.getRenderContext().getFunctions())
+	, m_referenceSource				(new glu::Framebuffer(context.getRenderContext()))
+	, m_targetType					(targetType)
+	, m_bound						(false)
+	, m_isSRGB						(isSRGB)
+	, m_type						(fboType)
+	, m_idx							(idx)
+	, m_colorAttachment				(colorAttachment)
+{
+	m_gl->bindFramebuffer(m_targetType, **m_referenceSource);
+
+	m_gl->framebufferTexture2D(m_targetType, m_colorAttachment, GL_TEXTURE_2D, textureAttachmentHandle, 0);
+
+	TCU_CHECK(m_gl->checkFramebufferStatus(m_targetType) == GL_FRAMEBUFFER_COMPLETE);
+
+	if (targetType == GL_DRAW_BUFFER)
+	{
+		glw::GLuint textureAttachments[] = {m_colorAttachment};
+		m_gl->drawBuffers(DE_LENGTH_OF_ARRAY(textureAttachments), textureAttachments);
+		GLU_EXPECT_NO_ERROR(m_gl->getError(), "glDrawBuffer()");
+	}
+
+	if (targetType == GL_READ_BUFFER)
+	{
+		m_gl->readBuffer(m_colorAttachment);
+		GLU_EXPECT_NO_ERROR(m_gl->getError(), "glReadBuffer()");
+	}
+
+	m_gl->bindFramebuffer(m_targetType, 0);
+}
+
+TestFramebuffer::~TestFramebuffer (void)
+{
+}
+
+void TestFramebuffer::setTargetType (const deUint32 targetType)
+{
+	m_targetType = targetType;
+}
+
+FboType TestFramebuffer::getType (void) const
+{
+	return m_type;
+}
+
+deUint32 TestFramebuffer::getHandle (void) const
+{
+	return **m_referenceSource;
+}
+
+deUint32 TestFramebuffer::getColorAttachment (void) const
+{
+	return m_colorAttachment;
+}
+
+int TestFramebuffer::getIdx (void) const
+{
+	return m_idx;
+}
+
+deUint32 TestFramebuffer::getTargetType (void) const
+{
+	return m_targetType;
+}
+
+void TestFramebuffer::bind (void)
+{
+	if (!m_bound)
+	{
+		m_gl->bindFramebuffer(m_targetType, **m_referenceSource);
+		m_bound = true;
+	}
+}
+
+void TestFramebuffer::unbind (void)
+{
+	if (m_bound)
+	{
+		m_gl->bindFramebuffer(m_targetType, 0);
+		m_bound = false;
+	}
+}
+
+class TestShaderProgram
+{
+public:
+										TestShaderProgram		(Context& context, const int samplerTotal, TestFunction testFunction);
+										~TestShaderProgram		(void);
+
+	glw::GLuint							getHandle				(void) const;
+	int									getSamplerTotal			(void) const;
+
+	void								use						(void) const;
+	void								unuse					(void) const;
+
+	glu::ShaderProgramInfo				getLogInfo				(void);
+
+private:
+	const glw::Functions*				m_gl;
+	de::MovePtr<glu::ShaderProgram>		m_referenceSource;
+	const int							m_samplerTotal;
+	const int							m_shaderStagesTotal;
+};
+
+TestShaderProgram::TestShaderProgram	(Context& context, const int samplerTotal, TestFunction testFunction)
+	: m_gl								(&context.getRenderContext().getFunctions())
+	, m_samplerTotal					(samplerTotal)
+	, m_shaderStagesTotal				(2)
+{
+	std::ostringstream		shaderFragment;
+
+	const char* const shaderVertex =
+		"#version 310 es \n"
+		"layout (location = 0) in mediump vec3 aPosition; \n"
+		"layout (location = 1) in mediump vec2 aTexCoord; \n"
+		"out mediump vec2 vs_aTexCoord; \n"
+		"void main () \n"
+		"{ \n"
+		"	gl_Position = vec4(aPosition, 1.0f); \n"
+		"	vs_aTexCoord = aTexCoord; \n"
+		"} \n";
+
+	shaderFragment
+		<< "#version 310 es \n"
+		<< "in mediump vec2 vs_aTexCoord; \n"
+		<< "layout (location = 0) out mediump vec4 fs_aColor0; \n";
+
+	for (int samplerIdx = 0; samplerIdx < m_samplerTotal; samplerIdx++)
+		shaderFragment
+			<< "uniform sampler2D uTexture" << samplerIdx << "; \n";
+
+	shaderFragment
+		<< "uniform int uFunctionType; \n";
+
+	if (testFunction.hasFunction)
+		shaderFragment
+		<< "uniform int uBlendFunctionType; \n"
+		<< "uniform mediump float uFactorSrc; \n"
+		<< "uniform mediump float uFactorDst; \n"
+			<< testFunction.functionDefintion;
+
+	shaderFragment
+		<< "void main () \n"
+		<< "{ \n";
+
+	for (int samplerIdx = 0; samplerIdx < m_samplerTotal; samplerIdx++)
+		shaderFragment
+			<<"	mediump vec4 texelColor" << samplerIdx << " = vec4(0.0f, 0.0f, 0.0f, 1.0f); \n";
+
+	shaderFragment
+		<< buildSamplingPassType(m_samplerTotal);
+
+	if (testFunction.hasFunction)
+		shaderFragment
+			<< "	fs_aColor0 = " << testFunction.functionName << "(texelColor0, texelColor1); \n";
+	else
+		shaderFragment
+			<< "	fs_aColor0 = texelColor0; \n";
+
+	shaderFragment
+		<< "} \n";
+
+	m_referenceSource = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(context.getRenderContext(), glu::makeVtxFragSources(shaderVertex, shaderFragment.str())));
+	if (!m_referenceSource->isOk())
+	{
+		tcu::TestLog& log = context.getTestContext().getLog();
+		log << this->getLogInfo();
+		TCU_FAIL("Failed to compile shaders and link program");
+	}
+}
+
+TestShaderProgram::~TestShaderProgram (void)
+{
+	m_referenceSource = de::MovePtr<glu::ShaderProgram>(DE_NULL);
+	m_referenceSource.clear();
+}
+
+deUint32 TestShaderProgram::getHandle (void) const
+{
+	return m_referenceSource->getProgram();
+}
+
+int TestShaderProgram::getSamplerTotal (void) const
+{
+	return m_samplerTotal;
+}
+
+void TestShaderProgram::use (void) const
+{
+	m_gl->useProgram(this->getHandle());
+}
+
+void TestShaderProgram::unuse (void) const
+{
+	m_gl->useProgram(0);
+}
+
+glu::ShaderProgramInfo TestShaderProgram::getLogInfo (void)
+{
+	glu::ShaderProgramInfo	buildInfo;
+
+	// log shader program info. Only vertex and fragment shaders included
+	buildInfo.program = m_referenceSource->getProgramInfo();
+	for (int shaderIdx = 0; shaderIdx < m_shaderStagesTotal; shaderIdx++)
+	{
+		glu::ShaderInfo shaderInfo = m_referenceSource->getShaderInfo(static_cast<glu::ShaderType>(static_cast<int>(glu::SHADERTYPE_VERTEX) + static_cast<int>(shaderIdx)), 0);
+		buildInfo.shaders.push_back(shaderInfo);
+	}
+	return buildInfo;
+}
+
+class Renderer
+{
+public:
+											Renderer						(Context& context);
+											~Renderer						(void);
+
+	void									init							(const TestRenderPassConfig& renderPassConfig, const int renderpass);
+	void									deinit							(void);
+
+	void									setSamplingType					(const SamplingType samplerIdx);
+	void									setBlendIteration				(const int blendIteration);
+	void									setFramebufferBlend				(const bool blend);
+	void									setFramebufferSRGB				(const bool sRGB);
+
+	std::vector<tcu::Vec4>					getResultsPreDraw				(void) const;
+	std::vector<tcu::Vec4>					getResultsPostDraw				(void) const;
+	int										getBlendConfigCount				(void) const;
+	glu::ShaderProgramInfo					getShaderProgramInfo			(void);
+
+	void									copyFrameBufferTexture			(const int srcPx, const int srcPy, const int dstPx, const int dstPy);
+	void									draw							(void);
+	void									storeShaderProgramInfo			(void);
+	void									logShaderProgramInfo			(void);
+
+	typedef de::SharedPtr<TestTexture2D>	TextureSp;
+	typedef de::SharedPtr<TestFramebuffer>	FboSp;
+
+private:
+	void									createFBOwithColorAttachment	(const std::vector<FBOConfig> fboConfigList);
+	void									setShaderProgramSamplingType	(const int samplerIdx);
+	void									setShaderBlendFunctionType		(void);
+	void									setShaderBlendSrcDstValues		(void);
+	void									bindActiveTexturesSamplers		(void);
+	void									bindAllRequiredSourceTextures	(const TextureSourcesType texturesRequired);
+	void									unbindAllSourceTextures			(void);
+	void									bindFramebuffer					(const int framebufferIdx);
+	void									unbindFramebuffer				(const int framebufferIdx);
+	void									enableFramebufferSRGB			(void);
+	void									enableFramebufferBlend			(void);
+	bool									isFramebufferAttachmentSRGB		(const deUint32 targetType, const deUint32 attachment) const;
+	void									readTexels						(const int px, const int py, const deUint32 attachment, tcu::Vec4& texelData);
+	void									logState						(const deUint32 targetType, const deUint32 attachment, const SamplingType samplingType) const;
+
+	// renderer specific constants initialized during constructor
+	Context&								m_context;
+	const TestVertexData					m_vertexData;
+	const int								m_textureSourceTotal;
+
+	// additional resources monitored by the renderer
+	std::vector<BlendConfig>				m_blendConfigList;
+	std::vector<TextureSp>					m_textureSourceList;
+	TestRenderPassConfig					m_renderPassConfig;
+	std::vector<TextureSp>					m_fboTextureList;
+	TestShaderProgram*						m_shaderProgram;
+	std::vector<FboSp>						m_framebufferList;
+	std::vector<tcu::Vec4>					m_resultsListPreDraw;
+	std::vector<tcu::Vec4>					m_resultsListPostDraw;
+
+	// mutable state variables (internal access only)
+	bool									m_hasShaderProgramInfo;
+	int										m_renderPass;
+	int										m_samplersRequired;
+	bool									m_hasFunction;
+	bool									m_blittingEnabled;
+	glu::ShaderProgramInfo					m_shaderProgramInfo;
+
+	// mutable state variables (external access via setters)
+	SamplingType							m_samplingType;
+	int										m_blendIteration;
+	bool									m_framebufferBlendEnabled;
+	bool									m_framebufferSRGBEnabled;
+};
+
+Renderer::Renderer				(Context& context)
+	: m_context					(context)
+	, m_vertexData				(context)
+	, m_textureSourceTotal		(2)
+	, m_blendConfigList			(getBlendingConfigList())
+	, m_hasShaderProgramInfo	(false)
+{
+	TextureSp textureLinear(new TestTexture2D(m_context, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, getTestColorLinear(), 0));
+	m_textureSourceList.push_back(textureLinear);
+
+	TextureSp textureSRGB(new TestTexture2D(m_context, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, getTestColorLinear(), 1));
+	m_textureSourceList.push_back(textureSRGB);
+}
+
+Renderer::~Renderer (void)
+{
+	m_textureSourceList.clear();
+	this->deinit();
+}
+
+void Renderer::init (const TestRenderPassConfig& renderPassConfig, const int renderpass)
+{
+	m_renderPassConfig = renderPassConfig;
+	m_renderPass = renderpass;
+
+	this->createFBOwithColorAttachment(m_renderPassConfig.fboConfigList);
+
+	if (m_renderPassConfig.textureSourcesType != TEXTURESOURCESTYPE_NONE)
+	{
+		if (m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_RGBA || m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_SRGBA)
+			m_samplersRequired = 1;
+		else if (m_renderPassConfig.textureSourcesType ==TEXTURESOURCESTYPE_BOTH )
+			m_samplersRequired = 2;
+		else
+			DE_FATAL("Error: Texture source required not recognised");
+
+		m_shaderProgram = new TestShaderProgram(m_context, m_samplersRequired, m_renderPassConfig.testFunction);
+		m_hasFunction = m_renderPassConfig.testFunction.hasFunction;
+	}
+	else
+		m_shaderProgram = DE_NULL;
+}
+
+void Renderer::deinit (void)
+{
+	if (m_shaderProgram != DE_NULL)
+	{
+		delete m_shaderProgram;
+		m_shaderProgram = DE_NULL;
+	}
+
+	m_fboTextureList.clear();
+	m_framebufferList.clear();
+}
+
+void Renderer::setSamplingType (const SamplingType samplingType)
+{
+	m_samplingType = samplingType;
+}
+
+void Renderer::setBlendIteration (const int blendIteration)
+{
+	m_blendIteration = blendIteration;
+}
+
+void Renderer::setFramebufferBlend (const bool blend)
+{
+	m_framebufferBlendEnabled = blend;
+}
+
+void Renderer::setFramebufferSRGB (const bool sRGB)
+{
+	m_framebufferSRGBEnabled = sRGB;
+}
+
+std::vector<tcu::Vec4> Renderer::getResultsPreDraw (void) const
+{
+	return m_resultsListPreDraw;
+}
+
+std::vector<tcu::Vec4> Renderer::getResultsPostDraw (void) const
+{
+	return m_resultsListPostDraw;
+}
+
+int Renderer::getBlendConfigCount (void) const
+{
+	return (int)m_blendConfigList.size();
+}
+
+void Renderer::copyFrameBufferTexture (const int srcPx, const int srcPy, const int dstPx, const int dstPy)
+{
+	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
+	int						fboSrcIdx				= -1;
+	int						fboDstIdx				= -1;
+	deUint32				fboSrcColAttachment		= GL_NONE;
+	deUint32				fboDstColAttachment		= GL_NONE;
+
+	for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
+		this->bindFramebuffer(idx);
+
+	// cache fbo attachments and idx locations
+	for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
+	{
+		if (m_framebufferList[idx]->getType() == FBOTYPE_SOURCE)
+		{
+			fboSrcIdx = m_framebufferList[idx]->getIdx();
+			fboSrcColAttachment = m_framebufferList[fboSrcIdx]->getColorAttachment();
+		}
+		if (m_framebufferList[idx]->getType() == FBOTYPE_DESTINATION)
+		{
+			fboDstIdx = m_framebufferList[idx]->getIdx();
+			fboDstColAttachment = m_framebufferList[fboDstIdx]->getColorAttachment();
+		}
+	}
+
+	for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
+		m_framebufferList[idx]->unbind();
+
+	// store texel data from both src and dst before performing the copy
+	m_resultsListPreDraw.resize(2);
+	m_framebufferList[fboSrcIdx]->bind();
+	this->readTexels(0, 0, fboSrcColAttachment, m_resultsListPreDraw[0]);
+	m_framebufferList[fboSrcIdx]->unbind();
+	m_framebufferList[fboDstIdx]->setTargetType(GL_READ_FRAMEBUFFER);
+	m_framebufferList[fboDstIdx]->bind();
+	this->readTexels(0, 0, fboDstColAttachment, m_resultsListPreDraw[1]);
+	m_framebufferList[fboDstIdx]->unbind();
+	m_framebufferList[fboDstIdx]->setTargetType(GL_DRAW_FRAMEBUFFER);
+
+	m_framebufferList[fboSrcIdx]->bind();
+	m_framebufferList[fboDstIdx]->bind();
+
+	this->enableFramebufferSRGB();
+	this->enableFramebufferBlend();
+
+	gl.blitFramebuffer(	srcPx, srcPy, TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT,
+						dstPx, dstPy, TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT,
+						GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+	m_resultsListPostDraw.resize(2);
+	this->readTexels(0, 0, fboSrcColAttachment, m_resultsListPostDraw[0]);
+	m_framebufferList[fboSrcIdx]->unbind();
+	m_framebufferList[fboDstIdx]->unbind();
+
+	m_framebufferList[fboDstIdx]->setTargetType(GL_READ_FRAMEBUFFER);
+	m_framebufferList[fboDstIdx]->bind();
+	this->readTexels(0, 0, fboDstColAttachment, m_resultsListPostDraw[1]);
+	m_framebufferList[fboDstIdx]->unbind();
+}
+
+void Renderer::draw (void)
+{
+	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
+
+	if (m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_NONE)
+		DE_FATAL("Error: Attempted to draw with no texture sources");
+
+	// resize results storage with each render pass
+	m_resultsListPreDraw.resize(m_renderPass + 1);
+	m_resultsListPostDraw.resize(m_renderPass + 1);
+
+	m_shaderProgram->use();
+	m_vertexData.bind();
+
+	for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
+		this->bindFramebuffer(idx);
+
+	this->bindAllRequiredSourceTextures(m_renderPassConfig.textureSourcesType);
+	this->bindActiveTexturesSamplers();
+
+	this->enableFramebufferSRGB();
+	this->enableFramebufferBlend();
+
+	this->readTexels(0, 0, GL_COLOR_ATTACHMENT0, m_resultsListPreDraw[m_renderPass]);
+	this->setShaderProgramSamplingType(m_samplingType);
+	if (m_hasFunction)
+	{
+		this->setShaderBlendFunctionType();
+		this->setShaderBlendSrcDstValues();
+	}
+
+	gl.drawArrays(GL_TRIANGLES, 0, 6);
+
+	this->readTexels(0, 0, GL_COLOR_ATTACHMENT0, m_resultsListPostDraw[m_renderPass]);
+	this->logState(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_samplingType);
+
+	this->unbindAllSourceTextures();
+	for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
+		this->unbindFramebuffer(idx);
+	m_vertexData.unbind();
+	m_shaderProgram->unuse();
+}
+
+void Renderer::storeShaderProgramInfo (void)
+{
+	m_shaderProgramInfo = m_shaderProgram->getLogInfo();
+	m_hasShaderProgramInfo = true;
+}
+
+void Renderer::logShaderProgramInfo (void)
+{
+	tcu::TestLog& log = m_context.getTestContext().getLog();
+
+	if (m_hasShaderProgramInfo)
+		log << m_shaderProgramInfo;
+}
+
+void Renderer::createFBOwithColorAttachment (const std::vector<FBOConfig> fboConfigList)
+{
+	const int size = (int)fboConfigList.size();
+	for (int idx = 0; idx < size; idx++)
+	{
+		TextureSp texture(new TestTexture2D(m_context, fboConfigList[idx].textureInternalFormat, GL_RGBA, GL_UNSIGNED_BYTE, fboConfigList[idx].textureColor, idx));
+		m_fboTextureList.push_back(texture);
+
+		bool isSRGB;
+		if (fboConfigList[idx].textureInternalFormat == GL_SRGB8_ALPHA8)
+			isSRGB = true;
+		else
+			isSRGB = false;
+
+		FboSp framebuffer(new TestFramebuffer(m_context, fboConfigList[idx].fboTargetType, fboConfigList[idx].fboColorAttachment, texture->getHandle(), isSRGB, fboConfigList[idx].fboType, idx));
+		m_framebufferList.push_back(framebuffer);
+	}
+}
+
+void Renderer::setShaderProgramSamplingType (const int samplerIdx)
+{
+	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+	glw::GLuint location = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFunctionType");
+	DE_ASSERT(location != (glw::GLuint)-1);
+	gl.uniform1i(location, samplerIdx);
+}
+
+void Renderer::setShaderBlendFunctionType (void)
+{
+	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+	int function = -1;
+	if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_ADD)
+		function = 0;
+	else if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_SUBTRACT)
+		function = 1;
+	else if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_REVERSE_SUBTRACT)
+		function = 2;
+	else
+		DE_FATAL("Error: Blend function not recognised");
+
+	glw::GLuint location = gl.getUniformLocation(m_shaderProgram->getHandle(), "uBlendFunctionType");
+	DE_ASSERT(location != (glw::GLuint)-1);
+	gl.uniform1i(location, function);
+}
+
+void Renderer::setShaderBlendSrcDstValues (void)
+{
+	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+	float funcSrc;
+	if (m_blendConfigList[m_blendIteration].funcSrc == GL_ONE)
+		funcSrc = 1.0f;
+	else
+		funcSrc = 0.0f;
+
+	float funcDst;
+		if (m_blendConfigList[m_blendIteration].funcDst == GL_ONE)
+		funcDst = 1.0f;
+	else
+		funcDst = 0.0f;
+
+	glw::GLuint locationSrc = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFactorSrc");
+	gl.uniform1f(locationSrc, funcSrc);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f()");
+
+	glw::GLuint locationDst = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFactorDst");
+	gl.uniform1f(locationDst, funcDst);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f()");
+}
+
+void Renderer::bindActiveTexturesSamplers (void)
+{
+	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+	for (int idx = 0; idx < m_samplersRequired; idx++)
+	{
+		std::ostringstream stream;
+		stream << "uTexture" << idx;
+		std::string uniformName(stream.str());
+		glw::GLint location = gl.getUniformLocation(m_shaderProgram->getHandle(), uniformName.c_str());
+		DE_ASSERT(location != -1);
+		gl.uniform1i(location, m_textureSourceList[idx]->getTextureUnit());
+		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
+	}
+}
+
+void Renderer::bindAllRequiredSourceTextures (const TextureSourcesType texturesRequired)
+{
+	if (texturesRequired == TEXTURESOURCESTYPE_RGBA)
+		m_textureSourceList[0]->bind(0);
+	else if (texturesRequired == TEXTURESOURCESTYPE_SRGBA)
+		m_textureSourceList[1]->bind(0);
+	else if (texturesRequired == TEXTURESOURCESTYPE_BOTH)
+	{
+		m_textureSourceList[0]->bind(0);
+		m_textureSourceList[1]->bind(1);
+	}
+	else
+		DE_FATAL("Error: Invalid sources requested in bind all");
+}
+
+void Renderer::unbindAllSourceTextures (void)
+{
+	for (int idx = 0; idx < (int)m_textureSourceList.size(); idx++)
+		m_textureSourceList[idx]->unbind();
+}
+
+void Renderer::bindFramebuffer (const int framebufferIdx)
+{
+	m_framebufferList[framebufferIdx]->bind();
+}
+
+void Renderer::unbindFramebuffer (const int framebufferIdx)
+{
+	m_framebufferList[framebufferIdx]->unbind();
+}
+
+void Renderer::enableFramebufferSRGB (void)
+{
+	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+	if (m_framebufferSRGBEnabled)
+		gl.enable(GL_FRAMEBUFFER_SRGB);
+	else
+		gl.disable(GL_FRAMEBUFFER_SRGB);
+}
+
+void Renderer::enableFramebufferBlend (void)
+{
+	const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();
+	tcu::TestLog&			log	= m_context.getTestContext().getLog();
+	std::ostringstream		message;
+
+	message << "Blend settings = ";
+
+	if (m_framebufferBlendEnabled)
+	{
+		gl.enable(GL_BLEND);
+		gl.blendEquation(m_blendConfigList[m_blendIteration].equation);
+		gl.blendFunc(m_blendConfigList[m_blendIteration].funcSrc, m_blendConfigList[m_blendIteration].funcDst);
+
+		std::string equation, src, dst;
+		if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_ADD)
+			equation = "GL_FUNC_ADD";
+		if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_SUBTRACT)
+			equation = "GL_FUNC_SUBTRACT";
+		if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_REVERSE_SUBTRACT)
+			equation = "GL_FUNC_REVERSE_SUBTRACT";
+		if (m_blendConfigList[m_blendIteration].funcSrc == GL_ONE)
+			src = "GL_ONE";
+		else
+			src = "GL_ZERO";
+		if (m_blendConfigList[m_blendIteration].funcDst == GL_ONE)
+			dst = "GL_ONE";
+		else
+			dst = "GL_ZERO";
+
+		message << "Enabled: equation = " << equation << ", func src = " << src << ", func dst = " << dst;
+	}
+	else
+	{
+		gl.disable(GL_BLEND);
+		message << "Disabled";
+	}
+
+	log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+}
+
+bool Renderer::isFramebufferAttachmentSRGB (const deUint32 targetType, const deUint32 attachment) const
+{
+	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
+	glw::GLint				encodingType;
+
+	gl.getFramebufferAttachmentParameteriv(targetType, attachment, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encodingType);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedFramebufferAttachmentParameteriv()");
+
+	switch (static_cast<glw::GLenum>(encodingType))
+	{
+		case GL_SRGB:
+		{
+			return true;
+			break;
+		}
+		case GL_LINEAR:
+		{
+			return false;
+			break;
+		}
+		default:
+		{
+			DE_FATAL("Error: Color attachment format not recognised");
+			return false;
+		}
+	}
+}
+
+void Renderer::readTexels (const int px, const int py, const deUint32 mode, tcu::Vec4& texelData)
+{
+	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
+	tcu::TextureLevel		textureRead;
+
+	// ensure result sampling coordinates are within range of the result color attachment
+	DE_ASSERT((px >= 0) && (px < m_context.getRenderTarget().getWidth()));
+	DE_ASSERT((py >= 0) && (py < m_context.getRenderTarget().getHeight()));
+
+	gl.readBuffer(mode);
+	textureRead.setStorage(glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE), TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT);
+	glu::readPixels(m_context.getRenderContext(), px, py, textureRead.getAccess());
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
+	texelData = textureRead.getAccess().getPixel(px, py);
+}
+
+void Renderer::logState (const deUint32 targetType, const deUint32 attachment, const SamplingType samplingType) const
+{
+	tcu::TestLog&			log					= m_context.getTestContext().getLog();
+	std::ostringstream		message;
+
+	bool fboAttachmentSRGB = this->isFramebufferAttachmentSRGB(targetType, attachment);
+	message.str("");
+	message << "getFramebufferAttachmentParameteriv() check = ";
+	if (fboAttachmentSRGB)
+		message << "GL_SRGB";
+	else
+		message << "GL_LINEAR";
+	log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+
+	message.str("");
+	message << "Framebuffer color attachment value BEFORE draw call";
+	logColor(m_context, message.str(), m_resultsListPreDraw[m_renderPass]);
+
+	message.str("");
+	message << "Framebuffer color attachment value AFTER draw call";
+	logColor(m_context, message.str(), m_resultsListPostDraw[m_renderPass]);
+
+	message.str("");
+	message << "Sampling type = ";
+	std::string type;
+	if (samplingType == 0)
+		type = "texture()";
+	else if (samplingType == 1)
+		type = "textureLOD()";
+	else if (samplingType == 2)
+		type = "textureGrad()";
+	else if (samplingType == 3)
+		type = "textureOffset()";
+	else if (samplingType == 4)
+		type = "textureProj()";
+	else
+		DE_FATAL("Error: Sampling type unregonised");
+	message << type;
+	log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+
+	message.str("");
+	if (m_framebufferSRGBEnabled)
+		message << "Framebuffer SRGB = enabled";
+	else
+		message << "Framebuffer SRGB = disabled";
+	log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+}
+
+class FboSRGBTestCase : public TestCase
+{
+public:
+											FboSRGBTestCase				(Context& context, const char* const name, const char* const desc);
+											~FboSRGBTestCase			(void);
+
+	void									init						(void);
+	void									deinit						(void);
+	IterateResult							iterate						(void);
+
+	void									setTestConfig				(std::vector<TestRenderPassConfig> renderPassConfigList);
+
+	virtual void							setupTest					(void) = 0;
+	virtual bool							verifyResult				(void) = 0;
+
+protected:
+	bool									m_hasTestConfig;
+	std::vector<TestRenderPassConfig>		m_renderPassConfigList;
+	bool									m_testcaseRequiresBlend;
+	std::vector<tcu::Vec4>					m_resultsPreDraw;
+	std::vector<tcu::Vec4>					m_resultsPostDraw;
+
+private:
+											FboSRGBTestCase				(const FboSRGBTestCase&);
+	FboSRGBTestCase&						operator=					(const FboSRGBTestCase&);
+};
+
+FboSRGBTestCase::FboSRGBTestCase	(Context& context, const char* const name, const char* const desc)
+	: TestCase						(context, name, desc)
+	, m_hasTestConfig				(false)
+{
+}
+
+FboSRGBTestCase::~FboSRGBTestCase (void)
+{
+	FboSRGBTestCase::deinit();
+}
+
+void FboSRGBTestCase::init (void)
+{
+	// extensions requirements for test
+	if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+		TCU_THROW(NotSupportedError, "Test requires a context version equal or higher than 3.2");
+
+	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
+		TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control");
+
+	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "Test requires GL_EXT_texture_sRGB_decode extension");
+}
+
+void FboSRGBTestCase::deinit (void)
+{
+}
+
+FboSRGBTestCase::IterateResult FboSRGBTestCase::iterate (void)
+{
+	this->setupTest();
+
+	DE_ASSERT(m_hasTestConfig && "Error: Renderer was not supplied a test config");
+
+	Renderer renderer(m_context);
+
+	// loop through each sampling type
+	for (int samplingIdx = 0; samplingIdx < SampligTypeCount::MAX; samplingIdx++)
+	{
+		renderer.setSamplingType(static_cast<SamplingType>(samplingIdx));
+
+		// loop through each blend configuration
+		const int blendCount = renderer.getBlendConfigCount();
+		for (int blendIdx = 0; blendIdx < blendCount; blendIdx++)
+		{
+			// loop through each render pass
+			const int renderPassCount = (int)m_renderPassConfigList.size();
+			for (int renderPassIdx = 0; renderPassIdx < renderPassCount; renderPassIdx++)
+			{
+				TestRenderPassConfig renderPassConfig = m_renderPassConfigList[renderPassIdx];
+
+				renderer.init(renderPassConfig, renderPassIdx);
+
+				if (blendIdx == 0 && renderPassConfig.rendererTask == RENDERERTASK_DRAW)
+					renderer.storeShaderProgramInfo();
+
+				if (renderPassConfig.frameBufferBlend == FRAMEBUFFERBLEND_ENABLED)
+				{
+					renderer.setBlendIteration(blendIdx);
+					renderer.setFramebufferBlend(true);
+				}
+				else
+					renderer.setFramebufferBlend(false);
+
+				if (renderPassConfig.framebufferSRGB == FRAMEBUFFERSRGB_ENABLED)
+					renderer.setFramebufferSRGB(true);
+				else
+					renderer.setFramebufferSRGB(false);
+
+				if (renderPassConfig.rendererTask == RENDERERTASK_DRAW)
+					renderer.draw();
+				else if (renderPassConfig.rendererTask == RENDERERTASK_COPY)
+					renderer.copyFrameBufferTexture(0, 0, 0, 0);
+				else
+					DE_FATAL("Error: render task not recognised");
+
+				renderer.deinit();
+
+			} // render passes
+
+			m_resultsPreDraw = renderer.getResultsPreDraw();
+			m_resultsPostDraw = renderer.getResultsPostDraw();
+
+			bool testPassed = this->verifyResult();
+			if (testPassed)
+				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+			else
+			{
+				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
+				renderer.logShaderProgramInfo();
+				return STOP;
+			}
+
+			if (!m_testcaseRequiresBlend)
+				break;
+		} // blend configs
+
+		renderer.logShaderProgramInfo();
+	} // sampling types
+
+	return STOP;
+}
+
+void FboSRGBTestCase::setTestConfig (std::vector<TestRenderPassConfig> renderPassConfigList)
+{
+	m_renderPassConfigList = renderPassConfigList;
+	m_hasTestConfig = true;
+
+	for (int idx = 0; idx < (int)renderPassConfigList.size(); idx++)
+	{
+		if (renderPassConfigList[idx].frameBufferBlend == FRAMEBUFFERBLEND_ENABLED)
+		{
+			m_testcaseRequiresBlend = true;
+			return;
+		}
+	}
+	m_testcaseRequiresBlend = false;
+}
+
+class FboSRGBQueryCase : public TestCase
+{
+public:
+					FboSRGBQueryCase	(Context& context, const char* const name, const char* const description);
+					~FboSRGBQueryCase	(void);
+
+	void			init				(void);
+	void			deinit				(void);
+	IterateResult	iterate				(void);
+};
+
+FboSRGBQueryCase::FboSRGBQueryCase	(Context& context, const char* const name, const char* const description)
+	: TestCase						(context, name, description)
+{
+}
+
+FboSRGBQueryCase::~FboSRGBQueryCase (void)
+{
+	FboSRGBQueryCase::deinit();
+}
+
+void FboSRGBQueryCase::init (void)
+{
+	// extension requirements for test
+	if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
+		TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control or a context version equal or higher than 3.2");
+}
+
+void FboSRGBQueryCase::deinit (void)
+{
+}
+
+FboSRGBQueryCase::IterateResult FboSRGBQueryCase::iterate (void)
+{
+	// TEST INFO:
+	// API tests which check when querying FRAMEBUFFER_SRGB_EXT capability returns the correct information when using glEnabled() or glDisabled()
+
+	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
+	tcu::TestLog&			log		= m_context.getTestContext().getLog();
+	const char*	const		msgPart	= ", after disabling = ";
+
+	for (int idx = 0; idx < static_cast<int>(QUERYTYPE_LAST); idx++)
+	{
+		std::ostringstream	message;
+		bool				pass		= false;
+
+		message << std::string("Results: After Enabling = ");
+
+		gl.enable(GL_FRAMEBUFFER_SRGB);
+
+		switch (static_cast<QueryType>(idx))
+		{
+			case QUERYTYPE_ISENABLED:
+			{
+				glw::GLboolean enabled[2];
+				enabled[0] = gl.isEnabled(GL_FRAMEBUFFER_SRGB);
+				gl.disable(GL_FRAMEBUFFER_SRGB);
+				enabled[1] = gl.isEnabled(GL_FRAMEBUFFER_SRGB);
+
+				message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
+				pass = (enabled[0] && !(enabled[1])) ? true : false;
+				break;
+			}
+			case QUERYTYPE_BOOLEAN:
+			{
+				glw::GLboolean enabled[2];
+				gl.getBooleanv(GL_FRAMEBUFFER_SRGB,&enabled[0]);
+				gl.disable(GL_FRAMEBUFFER_SRGB);
+				gl.getBooleanv(GL_FRAMEBUFFER_SRGB,&enabled[1]);
+
+				message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
+				pass = (enabled[0] && !(enabled[1])) ? true : false;
+				break;
+			}
+			case QUERYTYPE_FLOAT:
+			{
+				glw::GLfloat enabled[2];
+				gl.getFloatv(GL_FRAMEBUFFER_SRGB, &enabled[0]);
+				gl.disable(GL_FRAMEBUFFER_SRGB);
+				gl.getFloatv(GL_FRAMEBUFFER_SRGB, &enabled[1]);
+
+				message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
+				pass = ((int)enabled[0] && !((int)enabled[1])) ? true : false;
+				break;
+			}
+			case QUERYTYPE_INT:
+			{
+				glw::GLint enabled[2];
+				gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &enabled[0]);
+				gl.disable(GL_FRAMEBUFFER_SRGB);
+				gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &enabled[1]);
+
+				message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
+				pass = (enabled[0] && !(enabled[1])) ? true : false;
+				break;
+			}
+			case QUERYTYPE_INT64:
+			{
+				glw::GLint64 enabled[2];
+				gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &enabled[0]);
+				gl.disable(GL_FRAMEBUFFER_SRGB);
+				gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &enabled[1]);
+
+				message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
+				pass = (enabled[0] && !(enabled[1])) ? true : false;
+				break;
+			}
+			default:
+				DE_FATAL("Error: Datatype not recognised");
+		}
+
+		log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+
+		if (pass)
+			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+		else
+		{
+			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
+			return STOP;
+		}
+	}
+	return STOP;
+}
+
+class FboSRGBColAttachCase : public FboSRGBTestCase
+{
+public:
+			FboSRGBColAttachCase	(Context& context, const char* const name, const char* const description)
+				: FboSRGBTestCase	(context, name, description) {}
+			~FboSRGBColAttachCase	(void) {}
+
+	void	setupTest				(void);
+	bool	verifyResult			(void);
+};
+
+void FboSRGBColAttachCase::setupTest (void)
+{
+	// TEST INFO:
+	// Check if FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING  set to SRGB and FRAMEBUFFER_SRGB_EXT enabled, destination colors are converted from SRGB to linear
+	// before and after blending, finally the result is converted back to SRGB for storage
+
+	// NOTE:
+	// if fbo pre-draw color set to linaer, color values get linearlized "twice"
+	// (0.2f, 0.3f, 0.4f, 1.0f) when sampled i.e. converted in shader = (0.0331048f, 0.073239f, 0.132868f)
+	// resulting in the follolwing blending equation (0.2f, 0.3f, 0.4f 1.0f) + (0.0331048, 0.073239, 0.132868) = (0.521569f, 0.647059f, 0.756863f, 1.0f)
+
+	FBOConfig fboConfig0 = FBOConfig(GL_SRGB8_ALPHA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE);
+	FBOConfig fboConfig1 = FBOConfig(GL_RGBA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE);
+
+	const TestRenderPassConfig renderPassConfigs[] =
+	{
+		TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_ENABLED, RENDERERTASK_DRAW),
+		TestRenderPassConfig(TEXTURESOURCESTYPE_BOTH, fboConfig1, FRAMEBUFFERSRGB_DISABLED, FRAMEBUFFERBLEND_DISABLED, getFunctionBlendLinearToSRGBCheck(), RENDERERTASK_DRAW)
+	};
+	std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
+
+	this->setTestConfig(renderPassConfigList);
+}
+
+bool FboSRGBColAttachCase::verifyResult (void)
+{
+	if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[0] - m_resultsPostDraw[1]), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[0], m_resultsPostDraw[1])))
+		return true;
+	else
+		return false;
+}
+
+class FboSRGBToggleBlendCase : public FboSRGBTestCase
+{
+public:
+			FboSRGBToggleBlendCase		(Context& context, const char* const name, const char* const description)
+				: FboSRGBTestCase		(context, name, description) {}
+			~FboSRGBToggleBlendCase		(void) {}
+
+	void	setupTest					(void);
+	bool	verifyResult				(void);
+};
+
+void FboSRGBToggleBlendCase::setupTest (void)
+{
+	//	TEST INFO:
+	//	Test to check if changing FRAMEBUFFER_SRGB_EXT from enabled to disabled. Enabled should produce SRGB color whilst disabled
+	//	should produce linear color. Test conducted with blending disabled.
+
+	FBOConfig fboConfig0 = FBOConfig(GL_SRGB8_ALPHA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION);
+
+	const TestRenderPassConfig renderPassConfigs[] =
+	{
+		TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED,  FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW),
+		TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_DISABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW)
+	};
+	std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
+
+	this->setTestConfig(renderPassConfigList);
+}
+
+bool FboSRGBToggleBlendCase::verifyResult (void)
+{
+	if (tcu::boolAny(tcu::greaterThan(tcu::abs(m_resultsPostDraw[0] - m_resultsPostDraw[1]), getEpsilonError())))
+		return true;
+	else
+		return false;
+}
+
+class FboSRGBRenderTargetIgnoreCase : public FboSRGBTestCase
+{
+public:
+			FboSRGBRenderTargetIgnoreCase		(Context& context, const char* const name, const char* const description)
+				: FboSRGBTestCase				(context, name, description) {}
+			~FboSRGBRenderTargetIgnoreCase		(void) {}
+
+	void	setupTest							(void);
+	bool	verifyResult						(void);
+};
+
+void FboSRGBRenderTargetIgnoreCase::setupTest (void)
+{
+	// TEST INFO:
+	// Check if render targets that are non-RGB ignore the state of GL_FRAMEBUFFER_SRGB_EXT. Rendering to an fbo with non-sRGB color
+	// attachment should ignore color space conversion, producing linear color.
+
+	FBOConfig fboConfig0 = FBOConfig(GL_RGBA8, getTestColorBlank(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION);
+
+	const TestRenderPassConfig renderPassConfigs[] =
+	{
+		TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED,  FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW)
+
+	};
+	std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
+
+	this->setTestConfig(renderPassConfigList);
+}
+
+bool FboSRGBRenderTargetIgnoreCase::verifyResult (void)
+{
+	if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[0] - getTestColorLinear()), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[0], getTestColorLinear())))
+		return true;
+	else
+		return false;
+}
+
+class FboSRGBCopyToLinearCase : public FboSRGBTestCase
+{
+public:
+			FboSRGBCopyToLinearCase		(Context& context, const char* const name, const char* const description)
+				: FboSRGBTestCase		(context, name, description) {}
+			~FboSRGBCopyToLinearCase	(void) {}
+
+	void	setupTest					(void);
+	bool	verifyResult				(void);
+};
+
+void FboSRGBCopyToLinearCase::setupTest (void)
+{
+	// TEST INFO:
+	// Check if copying from an fbo with an sRGB color attachment to an fbo with a linear color attachment with FRAMEBUFFER_EXT enabled results in
+	// an sRGB to linear conversion
+
+	FBOConfig fboConfigs[] =
+	{
+		FBOConfig(GL_SRGB8_ALPHA8, getTestColorSRGB(), GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE),
+		FBOConfig(GL_RGBA8, getTestColorBlank(), GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION)
+	};
+	std::vector<FBOConfig> fboConfigList(fboConfigs, fboConfigs + DE_LENGTH_OF_ARRAY(fboConfigs));
+
+	const TestRenderPassConfig renderPassConfigs[] =
+	{
+		TestRenderPassConfig(TEXTURESOURCESTYPE_NONE, fboConfigList, FRAMEBUFFERSRGB_ENABLED,  FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_COPY)
+	};
+	std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
+
+	this->setTestConfig(renderPassConfigList);
+}
+
+bool FboSRGBCopyToLinearCase::verifyResult (void)
+{
+	logColor(m_context, "pre-copy source fbo color values", m_resultsPreDraw[0]);
+	logColor(m_context, "pre-copy destination fbo color values", m_resultsPreDraw[1]);
+	logColor(m_context, "post-copy source fbo color values", m_resultsPostDraw[0]);
+	logColor(m_context, "post-copy destination fbo color values", m_resultsPostDraw[1]);
+
+	if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[1] - getTestColorLinear()), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[1], getTestColorLinear())))
+		return true;
+	else
+		return false;
+}
+
+class FboSRGBUnsupportedEnumCase : public TestCase
+{
+public:
+					FboSRGBUnsupportedEnumCase	(Context& context, const char* const name, const char* const description);
+					~FboSRGBUnsupportedEnumCase	(void);
+
+	void			init						(void);
+	void			deinit						(void);
+	bool			isInvalidEnum				(std::string functionName);
+	IterateResult	iterate						(void);
+};
+
+FboSRGBUnsupportedEnumCase::FboSRGBUnsupportedEnumCase	(Context& context, const char* const name, const char* const description)
+	: TestCase						(context, name, description)
+{
+}
+
+FboSRGBUnsupportedEnumCase::~FboSRGBUnsupportedEnumCase (void)
+{
+	FboSRGBUnsupportedEnumCase::deinit();
+}
+
+void FboSRGBUnsupportedEnumCase::init (void)
+{
+	// extension requirements for test
+	if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
+		TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control to be unsupported and a context version less than 3.2");
+}
+
+void FboSRGBUnsupportedEnumCase::deinit (void)
+{
+}
+
+bool FboSRGBUnsupportedEnumCase::isInvalidEnum (std::string functionName)
+{
+	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
+	tcu::TestLog&			log			= m_context.getTestContext().getLog();
+	bool					isOk		= true;
+	glw::GLenum				error		= GL_NO_ERROR;
+
+	log << tcu::TestLog::Message << "Checking call to " << functionName << tcu::TestLog::EndMessage;
+
+	error = gl.getError();
+
+	if (error != GL_INVALID_ENUM)
+	{
+		log << tcu::TestLog::Message << " returned wrong value [" << glu::getErrorStr(error) << ", expected " << glu::getErrorStr(GL_INVALID_ENUM) << "]" << tcu::TestLog::EndMessage;
+		isOk = false;
+	}
+
+	return isOk;
+}
+
+FboSRGBUnsupportedEnumCase::IterateResult FboSRGBUnsupportedEnumCase::iterate (void)
+{
+	// TEST INFO:
+	// API tests that check calls using enum GL_FRAMEBUFFER_SRGB return GL_INVALID_ENUM  when GL_EXT_sRGB_write_control is not supported
+
+	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
+	bool					allPass		= true;
+	glw::GLboolean			bEnabled	= GL_FALSE;
+	glw::GLfloat			fEnabled	= 0;
+	glw::GLint				iEnabled	= 0;
+	glw::GLint64			lEnabled	= 0;
+
+	m_context.getTestContext().getLog() << tcu::TestLog::Message
+										<< "Check calls using enum GL_FRAMEBUFFER_SRGB return GL_INVALID_ENUM  when GL_EXT_sRGB_write_control is not supported\n\n"
+										<< tcu::TestLog::EndMessage;
+
+	gl.enable(GL_FRAMEBUFFER_SRGB);
+	allPass &= isInvalidEnum("glEnable()");
+
+	gl.disable(GL_FRAMEBUFFER_SRGB);
+	allPass &= isInvalidEnum("glDisable()");
+
+	gl.isEnabled(GL_FRAMEBUFFER_SRGB);
+	allPass &= isInvalidEnum("glIsEnabled()");
+
+	gl.getBooleanv(GL_FRAMEBUFFER_SRGB, &bEnabled);
+	allPass &= isInvalidEnum("glGetBooleanv()");
+
+	gl.getFloatv(GL_FRAMEBUFFER_SRGB, &fEnabled);
+	allPass &= isInvalidEnum("glGetFloatv()");
+
+	gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &iEnabled);
+	allPass &= isInvalidEnum("glGetIntegerv()");
+
+	gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &lEnabled);
+	allPass &= isInvalidEnum("glGetInteger64v()");
+
+	if (allPass)
+		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+	else
+		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+	return STOP;
+}
+
+} // anonymous
+
+FboSRGBWriteControlTests::FboSRGBWriteControlTests	(Context& context)
+	: TestCaseGroup			(context, "srgb_write_control", "Colorbuffer tests")
+{
+}
+
+FboSRGBWriteControlTests::~FboSRGBWriteControlTests (void)
+{
+}
+
+void FboSRGBWriteControlTests::init (void)
+{
+	this->addChild(new FboSRGBQueryCase					(m_context, "framebuffer_srgb_enabled",							"srgb enable framebuffer"));
+	this->addChild(new FboSRGBColAttachCase				(m_context, "framebuffer_srgb_enabled_col_attach",				"srgb enable color attachment and framebuffer"));
+	this->addChild(new FboSRGBToggleBlendCase			(m_context, "framebuffer_srgb_enabled_blend",					"toggle framebuffer srgb settings with blend disabled"));
+	this->addChild(new FboSRGBRenderTargetIgnoreCase	(m_context, "framebuffer_srgb_enabled_render_target_ignore",	"enable framebuffer srgb, non-srgb render target should ignore"));
+	this->addChild(new FboSRGBCopyToLinearCase			(m_context, "framebuffer_srgb_enabled_copy_to_linear",			"no conversion when blittering between framebuffer srgb and linear"));
+
+	// negative
+	this->addChild(new FboSRGBUnsupportedEnumCase		(m_context, "framebuffer_srgb_unsupported_enum",				"check error codes for query functions when extension is not supported"));
+}
+
+}
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fFboSRGBWriteControlTests.hpp b/modules/gles31/functional/es31fFboSRGBWriteControlTests.hpp
new file mode 100644
index 0000000..a4e0f17
--- /dev/null
+++ b/modules/gles31/functional/es31fFboSRGBWriteControlTests.hpp
@@ -0,0 +1,53 @@
+#ifndef _ES31FFBOSRGBWRITECONTROLTESTS_HPP
+#define _ES31FFBOSRGBWRITECONTROLTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief FBO sRGB tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes31TestCase.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+
+class FboSRGBWriteControlTests  : public TestCaseGroup
+{
+public:
+								FboSRGBWriteControlTests	(Context& context);
+								~FboSRGBWriteControlTests	(void);
+
+	void						init						(void);
+
+private:
+								FboSRGBWriteControlTests	(const FboSRGBWriteControlTests & other);
+	FboSRGBWriteControlTests&	operator=					(const FboSRGBWriteControlTests & other);
+};
+
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FFBOSRGBWRITECONTROLTESTS_HPP
\ No newline at end of file
diff --git a/modules/gles31/functional/es31fFunctionalTests.cpp b/modules/gles31/functional/es31fFunctionalTests.cpp
index b2bdac6..3fb407e 100644
--- a/modules/gles31/functional/es31fFunctionalTests.cpp
+++ b/modules/gles31/functional/es31fFunctionalTests.cpp
@@ -76,6 +76,7 @@
 #include "es31fDebugTests.hpp"
 #include "es31fFboColorbufferTests.hpp"
 #include "es31fFboNoAttachmentTests.hpp"
+#include "es31fFboSRGBWriteControlTests.hpp"
 #include "es31fProgramInterfaceQueryTests.hpp"
 #include "es31fTextureGatherTests.hpp"
 #include "es31fTextureFormatTests.hpp"
@@ -89,6 +90,8 @@
 #include "es31fDrawBuffersIndexedTests.hpp"
 #include "es31fDefaultVertexArrayObjectTests.hpp"
 #include "es31fSRGBDecodeTests.hpp"
+#include "es31fDrawElementsBaseVertexTests.hpp"
+#include "es31fShaderFramebufferFetchTests.hpp"
 
 namespace deqp
 {
@@ -200,6 +203,7 @@
 		addChild(new ShaderHelperInvocationTests		(m_context));
 		addChild(new ShaderLibraryTest					(m_context, "implicit_conversions", "GL_EXT_shader_implicit_conversions Tests"));
 		addChild(new ShaderLibraryTest					(m_context, "uniform_block", "Uniform block tests"));
+		addChild(new ShaderFramebufferFetchTests		(m_context));
 	}
 };
 
@@ -294,6 +298,7 @@
 		addChild(new FboColorTests						(m_context));
 		addChild(createFboNoAttachmentTests				(m_context));
 		addChild(createFboNoAttachmentCompletenessTests	(m_context));
+		addChild(new FboSRGBWriteControlTests			(m_context));
 	}
 };
 
@@ -353,6 +358,7 @@
 	addChild(createDrawBuffersIndexedTests				(m_context));
 	addChild(new DefaultVertexArrayObjectTests			(m_context));
 	addChild(new SRGBTextureDecodeTests					(m_context));
+	addChild(new DrawElementsBaseVertexTests			(m_context));
 }
 
 } // Functional
diff --git a/modules/gles31/functional/es31fNegativeComputeTests.cpp b/modules/gles31/functional/es31fNegativeComputeTests.cpp
new file mode 100644
index 0000000..eb2e0ec
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeComputeTests.cpp
@@ -0,0 +1,876 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Compute tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeComputeTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluShaderProgram.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+#include "tcuStringTemplate.hpp"
+
+namespace deqp
+{
+
+using std::string;
+using std::map;
+
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+using tcu::TestLog;
+using namespace glw;
+
+static const char* const vertexShaderSource			=	"${GLSL_VERSION_STRING}\n"
+														"\n"
+														"void main (void)\n"
+														"{\n"
+														"	gl_Position = vec4(0.0);\n"
+														"}\n";
+
+static const char* const fragmentShaderSource		=	"${GLSL_VERSION_STRING}\n"
+														"precision mediump float;\n"
+														"layout(location = 0) out mediump vec4 fragColor;\n"
+														"\n"
+														"void main (void)\n"
+														"{\n"
+														"	fragColor = vec4(1.0);\n"
+														"}\n";
+
+static const char* const computeShaderSource		=	"${GLSL_VERSION_STRING}\n"
+														"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+														"void main (void)\n"
+														"{\n"
+														"}\n";
+
+static const char* const invalidComputeShaderSource	=	"${GLSL_VERSION_STRING}\n"
+														"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+														"void main (void)\n"
+														"{\n"
+														"	highp uint var = -1;\n" // error
+														"}\n";
+
+int getResourceLimit (NegativeTestContext& ctx, GLenum resource)
+{
+	int limit = 0;
+	ctx.glGetIntegerv(resource, &limit);
+
+	return limit;
+}
+
+void verifyLinkError (NegativeTestContext& ctx, const glu::ShaderProgram& program)
+{
+	bool testFailed = false;
+
+	tcu::TestLog& log = ctx.getLog();
+	log << program;
+
+	testFailed = program.getProgramInfo().linkOk;
+
+	if (testFailed)
+	{
+		const char* const message("Program was not expected to link.");
+		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+		ctx.fail(message);
+	}
+}
+
+void verifyCompileError (NegativeTestContext& ctx, const glu::ShaderProgram& program, glu::ShaderType shaderType)
+{
+	bool testFailed = false;
+
+	tcu::TestLog& log = ctx.getLog();
+	log << program;
+
+	testFailed = program.getShaderInfo(shaderType).compileOk;
+
+	if (testFailed)
+	{
+		const char* const message("Program was not expected to compile.");
+		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+		ctx.fail(message);
+	}
+}
+
+string generateComputeShader (NegativeTestContext& ctx, const string& shaderDeclarations, const string& shaderBody)
+{
+	const bool			isES32			= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	const char* const	shaderVersion	= isES32
+										? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES)
+										: getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	std::ostringstream compShaderSource;
+
+	compShaderSource	<<	shaderVersion << "\n"
+						<<	"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+						<<	shaderDeclarations << "\n"
+						<<	"void main (void)\n"
+						<<	"{\n"
+						<<	shaderBody
+						<<	"}\n";
+
+	return compShaderSource.str();
+}
+
+string genBuiltInSource (glu::ShaderType shaderType)
+{
+	std::ostringstream		source;
+	source << "${GLSL_VERSION_STRING}\n";
+
+	switch (shaderType)
+	{
+		case glu::SHADERTYPE_VERTEX:
+		case glu::SHADERTYPE_FRAGMENT:
+			break;
+
+		case glu::SHADERTYPE_COMPUTE:
+			source << "layout (local_size_x = 1) in;\n";
+			break;
+
+		case glu::SHADERTYPE_GEOMETRY:
+			source << "layout(points) in;\n"
+				   << "layout(line_strip, max_vertices = 3) out;\n";
+			break;
+
+		case glu::SHADERTYPE_TESSELLATION_CONTROL:
+			source << "${GLSL_TESS_EXTENSION_STRING}\n"
+				   << "layout(vertices = 10) out;\n";
+			break;
+
+		case glu::SHADERTYPE_TESSELLATION_EVALUATION:
+			source << "${GLSL_TESS_EXTENSION_STRING}\n"
+				   << "layout(triangles) in;\n";
+			break;
+
+		default:
+			DE_FATAL("Unknown shader type");
+			break;
+	}
+
+	source	<< "\n"
+			<< "void main(void)\n"
+			<< "{\n"
+			<< "${COMPUTE_BUILT_IN_CONSTANTS_STRING}"
+			<< "}\n";
+
+	return source.str();
+}
+
+void exceed_uniform_block_limit (NegativeTestContext& ctx)
+{
+	std::ostringstream shaderDecl;
+	std::ostringstream shaderBody;
+
+	shaderDecl	<< "layout(std140, binding = 0) uniform Block\n"
+				<< "{\n"
+				<< "    highp vec4 val;\n"
+				<< "} block[" << getResourceLimit(ctx, GL_MAX_COMPUTE_UNIFORM_BLOCKS) + 1 << "];\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if a compute shader exceeds GL_MAX_COMPUTE_UNIFORM_BLOCKS.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void exceed_shader_storage_block_limit (NegativeTestContext& ctx)
+{
+	std::ostringstream shaderDecl;
+	std::ostringstream shaderBody;
+
+	shaderDecl	<< "layout(std140, binding = 0) buffer Block\n"
+				<< "{\n"
+				<< "    highp vec4 val;\n"
+				<< "} block[" << getResourceLimit(ctx, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS) + 1 << "];\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if compute shader exceeds GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void exceed_texture_image_units_limit (NegativeTestContext& ctx)
+{
+	const int			limit			= getResourceLimit(ctx, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS) + 1;
+	std::ostringstream	shaderDecl;
+	std::ostringstream	shaderBody;
+
+	shaderDecl	<< "layout(binding = 0) "
+				<< "uniform highp sampler2D u_sampler[" << limit + 1 << "];\n"
+				<< "\n"
+				<< "layout(binding = 0) buffer Output {\n"
+				<< "    vec4 values[ " << limit + 1 << " ];\n"
+				<< "} sb_out;\n";
+
+	for (int i = 0; i < limit + 1; ++i)
+		shaderBody	<< "   sb_out.values[" << i << "] = texture(u_sampler[" << i << "], vec2(1.0f));\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	tcu::TestLog& log = ctx.getLog();
+	log << tcu::TestLog::Message << "Possible link error is generated if compute shader exceeds GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS." << tcu::TestLog::EndMessage;
+	log << program;
+
+	if (program.getProgramInfo().linkOk)
+	{
+		log << tcu::TestLog::Message << "Quality Warning: program was not expected to link." << tcu::TestLog::EndMessage;
+		ctx.glUseProgram(program.getProgram());
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.beginSection("GL_INVALID_OPERATION error is generated if the sum of the number of active samplers for each active program exceeds the maximum number of texture image units allowed");
+		ctx.glDispatchCompute(1, 1, 1);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+	}
+}
+
+void exceed_image_uniforms_limit (NegativeTestContext& ctx)
+{
+	const int			limit = getResourceLimit(ctx, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
+	std::ostringstream	shaderDecl;
+	std::ostringstream	shaderBody;
+
+	shaderDecl	<< "layout(rgba8, binding = 0) "
+				<< "uniform readonly highp image2D u_image[" << limit + 1 << "];\n"
+				<< "\n"
+				<< "layout(binding = 0) buffer Output {\n"
+				<< "    float values[" << limit + 1 << "];\n"
+				<< "} sb_out;\n";
+
+	for (int i = 0; i < limit + 1; ++i)
+		shaderBody	<< "    sb_out.values[" << i << "]" << "  = imageLoad(u_image[" << i << "], ivec2(gl_GlobalInvocationID.xy)).x;\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if compute shader exceeds GL_MAX_COMPUTE_IMAGE_UNIFORMS.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void exceed_shared_memory_size_limit (NegativeTestContext& ctx)
+{
+	const int			limit				= getResourceLimit(ctx, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
+	const long			numberOfElements	= limit / sizeof(GLuint);
+	std::ostringstream	shaderDecl;
+	std::ostringstream	shaderBody;
+
+	shaderDecl	<< "shared uint values[" << numberOfElements + 1 << "];\n"
+				<< "\n"
+				<< "layout(binding = 0) buffer Output {\n"
+				<< "    uint values;\n"
+				<< "} sb_out;\n";
+
+	shaderBody	<< "    sb_out.values = values[" << numberOfElements << "];\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if compute shader exceeds GL_MAX_COMPUTE_SHARED_MEMORY_SIZE.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void exceed_uniform_components_limit (NegativeTestContext& ctx)
+{
+	const int			limit = getResourceLimit(ctx, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
+	std::ostringstream	shaderDecl;
+	std::ostringstream	shaderBody;
+
+	shaderDecl	<< "uniform highp uint u_value[" << limit + 1 << "];\n"
+				<< "\n"
+				<< "layout(binding = 0) buffer Output {\n"
+				<< "    uint values[2];\n"
+				<< "} sb_out;\n";
+
+	shaderBody << "    sb_out.values[0] = u_value[" << limit << "];\n";
+	shaderBody << "    sb_out.values[1] = u_value[0];\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if compute shader exceeds GL_MAX_COMPUTE_UNIFORM_COMPONENTS.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void exceed_atomic_counter_buffer_limit (NegativeTestContext& ctx)
+{
+	const int			limit = getResourceLimit(ctx, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
+	std::ostringstream	shaderDecl;
+	std::ostringstream	shaderBody;
+
+	for (int i = 0; i < limit + 1; ++i)
+	{
+		shaderDecl	<< "layout(binding = " << i << ") "
+					<< "uniform atomic_uint u_atomic" << i << ";\n";
+
+		if (i == 0)
+			shaderBody	<< "    uint oldVal = atomicCounterIncrement(u_atomic" << i << ");\n";
+		else
+			shaderBody	<< "    oldVal = atomicCounterIncrement(u_atomic" << i << ");\n";
+	}
+
+	shaderBody	<< "    sb_out.value = oldVal;\n";
+
+	shaderDecl	<< "\n"
+				<< "layout(binding = 0) buffer Output {\n"
+				<< "    uint value;\n"
+				<< "} sb_out;\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if compute shader exceeds GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void exceed_atomic_counters_limit (NegativeTestContext& ctx)
+{
+	std::ostringstream	shaderDecl;
+	std::ostringstream	shaderBody;
+
+	shaderDecl	<< "layout(binding = 0, offset = 0) uniform atomic_uint u_atomic0;\n"
+				<< "layout(binding = " << sizeof(GLuint) * getResourceLimit(ctx, GL_MAX_COMPUTE_ATOMIC_COUNTERS) << ", offset = 0) uniform atomic_uint u_atomic1;\n"
+				<< "\n"
+				<< "layout(binding = 0) buffer Output {\n"
+				<< "    uint value;\n"
+				<< "} sb_out;\n";
+
+	shaderBody	<< "    uint oldVal = 0u;\n"
+				<< "    oldVal = atomicCounterIncrement(u_atomic0);\n"
+				<< "    oldVal = atomicCounterIncrement(u_atomic1);\n"
+				<< "    sb_out.value = oldVal;\n";
+
+	glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::ComputeSource(generateComputeShader(ctx, shaderDecl.str(), shaderBody.str())));
+
+	ctx.beginSection("Link error is generated if compute shader exceeds GL_MAX_COMPUTE_ATOMIC_COUNTERS.");
+	verifyLinkError(ctx, program);
+	ctx.endSection();
+}
+
+void program_not_active (NegativeTestContext& ctx)
+{
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	const glu::VertexSource		vertSource(tcu::StringTemplate(vertexShaderSource).specialize(args));
+	const glu::FragmentSource	fragSource(tcu::StringTemplate(fragmentShaderSource).specialize(args));
+
+	glu::ProgramPipeline		pipeline(ctx.getRenderContext());
+
+	glu::ShaderProgram			vertProgram	(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << vertSource);
+	glu::ShaderProgram			fragProgram	(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << fragSource);
+
+	tcu::TestLog& log			= ctx.getLog();
+	log << vertProgram << fragProgram;
+
+	if (!vertProgram.isOk() || !fragProgram.isOk())
+		TCU_THROW(InternalError, "failed to build program");
+
+	ctx.glBindProgramPipeline(pipeline.getPipeline());
+	ctx.expectError(GL_NO_ERROR);
+
+	ctx.beginSection("Program not set at all");
+	{
+		ctx.beginSection("GL_INVALID_OPERATION is generated by glDispatchCompute if there is no active program for the compute shader stage.");
+		ctx.glDispatchCompute(1, 1, 1);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated by glDispatchComputeIndirect if there is no active program for the compute shader stage.");
+		GLintptr indirect = 0;
+		ctx.glDispatchComputeIndirect(indirect);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+	}
+	ctx.endSection();
+
+	ctx.beginSection("Program contains graphic pipeline stages");
+	{
+		ctx.glUseProgramStages(pipeline.getPipeline(), GL_VERTEX_SHADER_BIT, vertProgram.getProgram());
+		ctx.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, fragProgram.getProgram());
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated by glDispatchCompute if there is no active program for the compute shader stage.");
+		ctx.glDispatchCompute(1, 1, 1);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated by glDispatchComputeIndirect if there is no active program for the compute shader stage.");
+		GLintptr indirect = 0;
+		ctx.glDispatchComputeIndirect(indirect);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+	}
+	ctx.endSection();
+
+	ctx.glBindProgramPipeline(0);
+	ctx.expectError(GL_NO_ERROR);
+}
+
+void invalid_program_query (NegativeTestContext& ctx)
+{
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	GLint data[3] = { 0, 0, 0 };
+
+	ctx.beginSection("Compute shader that does not link");
+	{
+		const glu::ComputeSource	compSource(tcu::StringTemplate(invalidComputeShaderSource).specialize(args));
+		glu::ShaderProgram			invalidComputeProgram (ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+		tcu::TestLog& log = ctx.getLog();
+		log << invalidComputeProgram;
+
+		if (invalidComputeProgram.isOk())
+			TCU_THROW(InternalError, "program should not of built");
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated if GL_COMPUTE_WORK_GROUP_SIZE is queried for a program which has not been linked properly.");
+		ctx.glGetProgramiv(invalidComputeProgram.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, &data[0]);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.glUseProgram(0);
+	}
+	ctx.endSection();
+
+	ctx.beginSection("Compute shader not present");
+	{
+		const glu::VertexSource		vertSource(tcu::StringTemplate(vertexShaderSource).specialize(args));
+		const glu::FragmentSource	fragSource(tcu::StringTemplate(fragmentShaderSource).specialize(args));
+		glu::ShaderProgram			graphicsPipelineProgram	(ctx.getRenderContext(), glu::ProgramSources() << vertSource << fragSource);
+
+		tcu::TestLog& log = ctx.getLog();
+		log << graphicsPipelineProgram;
+
+		if (!graphicsPipelineProgram.isOk())
+			TCU_THROW(InternalError, "failed to build program");
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated if GL_COMPUTE_WORK_GROUP_SIZE is queried for a program which has not been linked properly.");
+		ctx.glGetProgramiv(graphicsPipelineProgram.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, &data[0]);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.glUseProgram(0);
+	}
+	ctx.endSection();
+}
+
+void invalid_dispatch_compute_indirect (NegativeTestContext& ctx)
+{
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	const glu::ComputeSource	compSource(tcu::StringTemplate(computeShaderSource).specialize(args));
+	glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+	tcu::TestLog& log = ctx.getLog();
+	log << program;
+
+	if (!program.isOk())
+		TCU_THROW(InternalError, "failed to build program");
+
+	ctx.glUseProgram(program.getProgram());
+	ctx.expectError(GL_NO_ERROR);
+
+	static const struct
+	{
+		GLuint numGroupsX;
+		GLuint numGroupsY;
+		GLuint numGroupsZ;
+	} data = {0, 0, 0};
+
+	{
+		GLuint buffer;
+		ctx.glGenBuffers(1, &buffer);
+		ctx.glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated by glDispatchComputeIndirect if zero is bound to GL_DISPATCH_INDIRECT_BUFFER.");
+		GLintptr indirect = 0;
+		ctx.glDispatchComputeIndirect(indirect);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.glDeleteBuffers(1, &buffer);
+	}
+
+	{
+		GLuint buffer;
+		ctx.glGenBuffers(1, &buffer);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(data), &data, GL_STATIC_DRAW);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.beginSection("GL_INVALID_OPERATION is generated by glDispatchComputeIndirect if data is sourced beyond the end of the buffer object.");
+		GLintptr indirect = 1 << 10;
+		ctx.glDispatchComputeIndirect(indirect);
+		ctx.expectError(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
+		ctx.glDeleteBuffers(1, &buffer);
+	}
+
+	{
+		ctx.beginSection("GL_INVALID_VALUE is generated by glDispatchComputeIndirect if the value of indirect is less than zero.");
+		GLintptr indirect = -1;
+		ctx.glDispatchComputeIndirect(indirect);
+		ctx.expectError(GL_INVALID_VALUE);
+		ctx.endSection();
+	}
+
+	{
+		GLuint buffer;
+		ctx.glGenBuffers(1, &buffer);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(data), &data, GL_STATIC_DRAW);
+		ctx.expectError(GL_NO_ERROR);
+
+		ctx.beginSection("GL_INVALID_VALUE is generated by glDispatchComputeIndirect if indirect is not a multiple of the size, in basic machine units, of uint.");
+		GLintptr indirect = sizeof(data) + 1;
+		ctx.glDispatchComputeIndirect(indirect);
+		ctx.expectError(GL_INVALID_VALUE);
+		ctx.endSection();
+
+		ctx.glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
+		ctx.glDeleteBuffers(1, &buffer);
+	}
+}
+
+void invalid_maximum_work_group_counts (NegativeTestContext& ctx)
+{
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	const glu::ComputeSource	compSource(tcu::StringTemplate(computeShaderSource).specialize(args));
+	glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+	tcu::TestLog& log = ctx.getLog();
+	log << program;
+
+	if (!program.isOk())
+		TCU_THROW(InternalError, "failed to build program");
+
+	ctx.glUseProgram(program.getProgram());
+	ctx.expectError(GL_NO_ERROR);
+
+	GLint workGroupCountX;
+	ctx.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, (GLuint)0, &workGroupCountX);
+	ctx.expectError(GL_NO_ERROR);
+
+	ctx.beginSection("GL_INVALID_VALUE is generated by glDispatchCompute if <numGroupsX> array is larger than the maximum work group count for the x dimension.");
+	ctx.glDispatchCompute(workGroupCountX+1, 1, 1);
+	ctx.expectError(GL_INVALID_VALUE);
+	ctx.endSection();
+
+	GLint workGroupCountY;
+	ctx.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, (GLuint)1, &workGroupCountY);
+	ctx.expectError(GL_NO_ERROR);
+
+	ctx.beginSection("GL_INVALID_VALUE is generated by glDispatchCompute if <numGroupsY> array is larger than the maximum work group count for the y dimension.");
+	ctx.glDispatchCompute(1, workGroupCountY+1, 1);
+	ctx.expectError(GL_INVALID_VALUE);
+	ctx.endSection();
+
+	GLint workGroupCountZ;
+	ctx.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, (GLuint)2, &workGroupCountZ);
+	ctx.expectError(GL_NO_ERROR);
+
+	ctx.beginSection("GL_INVALID_VALUE is generated by glDispatchCompute if <numGroupsZ> array is larger than the maximum work group count for the z dimension.");
+	ctx.glDispatchCompute(1, 1, workGroupCountZ+1);
+	ctx.expectError(GL_INVALID_VALUE);
+	ctx.endSection();
+}
+
+void invalid_maximum_work_group_sizes (NegativeTestContext& ctx)
+{
+	GLint maxWorkGroupSizeX;
+	ctx.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, (GLuint)0, &maxWorkGroupSizeX);
+	ctx.expectError(GL_NO_ERROR);
+
+	GLint maxWorkGroupSizeY;
+	ctx.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, (GLuint)1, &maxWorkGroupSizeY);
+	ctx.expectError(GL_NO_ERROR);
+
+	GLint maxWorkGroupSizeZ;
+	ctx.glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, (GLuint)2, &maxWorkGroupSizeZ);
+	ctx.expectError(GL_NO_ERROR);
+
+	GLint maxWorkGroupInvocations;
+	ctx.glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &maxWorkGroupInvocations);
+	ctx.expectError(GL_NO_ERROR);
+
+	DE_ASSERT((maxWorkGroupSizeX * maxWorkGroupSizeY * maxWorkGroupSizeZ) > maxWorkGroupInvocations );
+
+	const bool				isES32			= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	const char* const		shaderVersion	= isES32
+											? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES)
+											: getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	static const struct
+	{
+		GLint x;
+		GLint y;
+		GLint z;
+	} localWorkGroupSizeCases[] =
+	{
+		{	maxWorkGroupSizeX+1,	1,						1						},
+		{	1,						maxWorkGroupSizeY+1,	1						},
+		{	1,						1,						maxWorkGroupSizeZ+1		},
+		{	maxWorkGroupSizeX,		maxWorkGroupSizeY,		maxWorkGroupSizeZ		},
+	};
+
+	for (int testCase = 0; testCase < DE_LENGTH_OF_ARRAY(localWorkGroupSizeCases); ++testCase)
+	{
+		std::ostringstream compShaderSource;
+
+		compShaderSource	<<	shaderVersion << "\n"
+							<<	"layout(local_size_x = " << localWorkGroupSizeCases[testCase].x << ", local_size_y = " << localWorkGroupSizeCases[testCase].y << ", local_size_z = " << localWorkGroupSizeCases[testCase].z << ") in;\n"
+							<<	"void main (void)\n"
+							<<	"{\n"
+							<<	"}\n";
+
+		const glu::ComputeSource	compSource(compShaderSource.str());
+		glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+		if (testCase == DE_LENGTH_OF_ARRAY(localWorkGroupSizeCases)-1)
+		{
+			bool testFailed = false;
+			ctx.beginSection("A compile time or link error is generated if the maximum number of invocations in a single local work group (product of the three dimensions) is greater than GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS.");
+
+			ctx.getLog() << program;
+			testFailed = (program.getProgramInfo().linkOk) && (program.getShaderInfo(glu::SHADERTYPE_COMPUTE).compileOk);
+
+			if (testFailed)
+			{
+				const char* const message("Program was not expected to compile or link.");
+				ctx.getLog() << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+				ctx.fail(message);
+			}
+		}
+		else
+		{
+			ctx.beginSection("A compile time error is generated if the fixed local group size of the shader in any dimension is greater than the maximum supported.");
+			verifyCompileError(ctx, program, glu::SHADERTYPE_COMPUTE);
+		}
+
+		ctx.endSection();
+	}
+}
+
+void invalid_layout_qualifiers (NegativeTestContext& ctx)
+{
+	const bool				isES32			= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	const char* const		shaderVersion	= isES32
+											? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES)
+											: getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	{
+		std::ostringstream compShaderSource;
+		compShaderSource	<<	shaderVersion << "\n"
+							<<	"void main (void)\n"
+							<<	"{\n"
+							<<	"}\n";
+
+		const glu::ComputeSource	compSource(compShaderSource.str());
+		glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+		ctx.beginSection("A link error is generated if the compute shader program does not contain an input layout qualifier specifying a fixed local group size.");
+		verifyLinkError(ctx, program);
+		ctx.endSection();
+	}
+
+	{
+		std::ostringstream compShaderSource;
+		compShaderSource	<<	shaderVersion << "\n"
+							<<	"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+							<<	"layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n"
+							<<	"void main (void)\n"
+							<<	"{\n"
+							<<	"}\n";
+
+		const glu::ComputeSource	compSource(compShaderSource.str());
+		glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+		ctx.beginSection("A compile-time error is generated if a local work group size qualifier is declared more than once in the same shader.");
+		verifyCompileError(ctx, program, glu::SHADERTYPE_COMPUTE);
+		ctx.endSection();
+	}
+
+	{
+		std::ostringstream compShaderSource;
+		compShaderSource	<<	shaderVersion << "\n"
+							<<	"out mediump vec4 fragColor;\n"
+							<<	"\n"
+							<<	"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+							<<	"void main (void)\n"
+							<<	"{\n"
+							<<	"}\n";
+
+		const glu::ComputeSource	compSource(compShaderSource.str());
+		glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+		ctx.beginSection("A compile-time error is generated if a user defined output variable is declared in a compute shader.");
+		verifyCompileError(ctx, program, glu::SHADERTYPE_COMPUTE);
+		ctx.endSection();
+	}
+
+	{
+		std::ostringstream compShaderSource;
+		compShaderSource	<<	shaderVersion << "\n"
+							<<	"uvec3 gl_NumWorkGroups;\n"
+							<<	"uvec3 gl_WorkGroupSize;\n"
+							<<	"uvec3 gl_WorkGroupID;\n"
+							<<	"uvec3 gl_LocalInvocationID;\n"
+							<<	"uvec3 gl_GlobalInvocationID;\n"
+							<<	"uvec3 gl_LocalInvocationIndex;\n"
+							<<	"\n"
+							<<	"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+							<<	"void main (void)\n"
+							<<	"{\n"
+							<<	"}\n";
+
+		const glu::ComputeSource	compSource(compShaderSource.str());
+		glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << compSource);
+
+		ctx.beginSection("A compile time or link error is generated if compute shader built-in variables are redeclared.");
+		bool testFailed = false;
+
+		tcu::TestLog& log = ctx.getLog();
+		log << program;
+
+		testFailed = (program.getProgramInfo().linkOk) && (program.getShaderInfo(glu::SHADERTYPE_COMPUTE).compileOk);
+
+		if (testFailed)
+		{
+			const char* const message("Program was not expected to compile or link.");
+			log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+			ctx.fail(message);
+		}
+
+		ctx.endSection();
+	}
+}
+
+void invalid_write_built_in_constants (NegativeTestContext& ctx)
+{
+	if ((!ctx.isExtensionSupported("GL_EXT_tessellation_shader") && !ctx.isExtensionSupported("GL_OES_tessellation_shader")) ||
+	    (!ctx.isExtensionSupported("GL_EXT_geometry_shader") && !ctx.isExtensionSupported("GL_OES_geometry_shader")))
+	{
+		TCU_THROW(NotSupportedError, "tessellation and geometry shader extensions not supported");
+	}
+
+	const bool					isES32			= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+
+	args["GLSL_VERSION_STRING"]					=	isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+	args["GLSL_TESS_EXTENSION_STRING"]			=	isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+	args["COMPUTE_BUILT_IN_CONSTANTS_STRING"]	=	"	gl_MaxComputeWorkGroupCount       = ivec3(65535, 65535, 65535);\n"
+													"	gl_MaxComputeWorkGroupCount       = ivec3(1024, 1024, 64);\n"
+													"	gl_MaxComputeWorkGroupSize        = ivec3(512);\n"
+													"	gl_MaxComputeUniformComponents    = 512;\n"
+													"	gl_MaxComputeTextureImageUnits    = 16;\n"
+													"	gl_MaxComputeImageUniforms        = 8;\n"
+													"	gl_MaxComputeAtomicCounters       = 8;\n"
+													"	gl_MaxComputeAtomicCounterBuffers = 1;\n";
+
+	const glu::VertexSource					vertSource		(tcu::StringTemplate(genBuiltInSource(glu::SHADERTYPE_VERTEX)).specialize(args));
+	const glu::FragmentSource				fragSource		(tcu::StringTemplate(genBuiltInSource(glu::SHADERTYPE_FRAGMENT)).specialize(args));
+	const glu::TessellationControlSource	tessCtrlSource	(tcu::StringTemplate(genBuiltInSource(glu::SHADERTYPE_TESSELLATION_CONTROL)).specialize(args));
+	const glu::TessellationEvaluationSource	tessEvalSource	(tcu::StringTemplate(genBuiltInSource(glu::SHADERTYPE_TESSELLATION_EVALUATION)).specialize(args));
+	const glu::GeometrySource				geometrySource	(tcu::StringTemplate(genBuiltInSource(glu::SHADERTYPE_GEOMETRY)).specialize(args));
+	const glu::ComputeSource				computeSource	(tcu::StringTemplate(genBuiltInSource(glu::SHADERTYPE_COMPUTE)).specialize(args));
+
+	glu::ShaderProgram	vertProgram		(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << vertSource);
+	glu::ShaderProgram	fragProgram		(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << fragSource);
+	glu::ShaderProgram	tessCtrlProgram	(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << tessCtrlSource);
+	glu::ShaderProgram	tessEvalProgram	(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << tessEvalSource);
+	glu::ShaderProgram	geometryProgram	(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << geometrySource);
+	glu::ShaderProgram	computeProgram	(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << computeSource);
+
+	ctx.beginSection("A compile time is generated if compute built-in constants provided in all shaders are written to.");
+	verifyCompileError(ctx, vertProgram, glu::SHADERTYPE_VERTEX);
+	verifyCompileError(ctx, fragProgram, glu::SHADERTYPE_FRAGMENT);
+	verifyCompileError(ctx, tessCtrlProgram, glu::SHADERTYPE_TESSELLATION_CONTROL);
+	verifyCompileError(ctx, tessEvalProgram, glu::SHADERTYPE_TESSELLATION_EVALUATION);
+	verifyCompileError(ctx, geometryProgram, glu::SHADERTYPE_GEOMETRY);
+	verifyCompileError(ctx, computeProgram, glu::SHADERTYPE_COMPUTE);
+	ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeComputeTestFunctions (void)
+{
+	const FunctionContainer funcs[] =
+	{
+		{ program_not_active,					"program_not_active",					"Use dispatch commands with no active program"									},
+		{ invalid_program_query,				"invalid_program_query",				"Querying GL_COMPUTE_WORK_GROUP_SIZE with glGetProgramiv() on invalid programs"	},
+		{ invalid_dispatch_compute_indirect,	"invalid_dispatch_compute_indirect",	"Invalid glDispatchComputeIndirect usage"										},
+		{ invalid_maximum_work_group_counts,	"invalid_maximum_work_group_counts",	"Maximum workgroup counts for dispatch commands"								},
+		{ invalid_maximum_work_group_sizes,		"invalid_maximum_work_group_sizes",		"Maximum local workgroup sizes declared in compute shaders"						},
+		{ invalid_layout_qualifiers,			"invalid_layout_qualifiers",			"Invalid layout qualifiers in compute shaders"									},
+		{ invalid_write_built_in_constants,		"invalid_write_built_in_constants",		"Invalid writes to built-in compute shader constants"							},
+		{ exceed_uniform_block_limit,			"exceed_uniform_block_limit",			"Link error when shader exceeds GL_MAX_COMPUTE_UNIFORM_BLOCKS"					},
+		{ exceed_shader_storage_block_limit,	"exceed_shader_storage_block_limit",	"Link error when shader exceeds GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS"			},
+		{ exceed_texture_image_units_limit,		"exceed_texture_image_units_limit",		"Link error when shader exceeds GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS"				},
+		{ exceed_image_uniforms_limit,			"exceed_image_uniforms_limit",			"Link error when shader exceeds GL_MAX_COMPUTE_IMAGE_UNIFORMS"					},
+		{ exceed_shared_memory_size_limit,		"exceed_shared_memory_size_limit",		"Link error when shader exceeds GL_MAX_COMPUTE_SHARED_MEMORY_SIZE"				},
+		{ exceed_uniform_components_limit,		"exceed_uniform_components_limit",		"Link error when shader exceeds GL_MAX_COMPUTE_UNIFORM_COMPONENTS"				},
+		{ exceed_atomic_counter_buffer_limit,	"exceed_atomic_counter_buffer_limit",	"Link error when shader exceeds GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS"			},
+		{ exceed_atomic_counters_limit,			"exceed_atomic_counters_limit",			"Link error when shader exceeds GL_MAX_COMPUTE_ATOMIC_COUNTERS"					},
+	};
+
+	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeComputeTests.hpp b/modules/gles31/functional/es31fNegativeComputeTests.hpp
new file mode 100644
index 0000000..8b582c9
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeComputeTests.hpp
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVECOMPUTETESTS_HPP
+#define _ES31FNEGATIVECOMPUTETESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Compute tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeComputeTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles3
+} // deqp
+
+#endif // _ES31FNEGATIVECOMPUTETESTS_HPP
diff --git a/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp b/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp
index bddd035..358b7a2 100644
--- a/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp
+++ b/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp
@@ -76,16 +76,7 @@
 	void			setSingleValue						(const SsboArgData argData);
 	bool			setAllValues						(const std::vector<SsboArgData> argDataList);
 
-	const std::string&	getContextVersion				(void) const;
-	const std::string&	getStdFormat					(void) const;
-	const std::string&	getBindingPoint					(void) const;
-	const std::string&	getMatrixOrder					(void) const;
-	const std::string&	getMemberType					(void) const;
-	const std::string&	getMemberName					(void) const;
-	const std::string&	getMemberFixedArrayName			(void) const;
-	const std::string&	getMemberVariableArray			(void) const;
 	bool				getMemberReorder				(void) const;
-	int					getNumberMembers				(void) const;
 
 	void				resetValues						(void);
 
@@ -177,56 +168,11 @@
 	return true;
 }
 
-const std::string& SsboArgs::getContextVersion (void) const
-{
-	return m_negativeContextVersion;
-}
-
-const std::string& SsboArgs::getStdFormat (void) const
-{
-	return m_stdFormat;
-}
-
-const std::string& SsboArgs::getBindingPoint (void) const
-{
-	return m_bindingPoint;
-}
-
-const std::string& SsboArgs::getMatrixOrder (void) const
-{
-	return m_matrixOrder;
-}
-
-const std::string& SsboArgs::getMemberType (void) const
-{
-	return m_memberType;
-}
-
-const std::string& SsboArgs::getMemberName (void) const
-{
-	return m_memberName;
-}
-
-const std::string& SsboArgs::getMemberFixedArrayName (void) const
-{
-	return m_memberFixedArrayerName;
-}
-
-const std::string& SsboArgs::getMemberVariableArray (void) const
-{
-	return m_memberVariableArray;
-}
-
 bool SsboArgs::getMemberReorder (void) const
 {
 	return m_memberReorder;
 }
 
-int SsboArgs::getNumberMembers (void) const
-{
-	return m_numberMembers;
-}
-
 void SsboArgs::resetValues (void)
 {
 	setDefaultValues();
diff --git a/modules/gles31/functional/es31fNegativeSampleVariablesTests.cpp b/modules/gles31/functional/es31fNegativeSampleVariablesTests.cpp
new file mode 100644
index 0000000..54b77da
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeSampleVariablesTests.cpp
@@ -0,0 +1,365 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Sample Variables Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeSampleVariablesTests.hpp"
+#include "gluShaderProgram.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+enum ExpectResult
+{
+	EXPECT_RESULT_PASS = 0,
+	EXPECT_RESULT_FAIL,
+	EXPECT_RESULT_LAST
+};
+
+void verifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource, ExpectResult expect)
+{
+	DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST);
+
+	tcu::TestLog&		log			= ctx.getLog();
+	bool				testFailed	= false;
+	const char* const	source		= shaderSource.c_str();
+	const int			length		= (int) shaderSource.size();
+	glu::Shader			shader		(ctx.getRenderContext(), shaderType);
+	std::string			message;
+
+	shader.setSources(1, &source, &length);
+	shader.compile();
+
+	log << shader;
+
+	if (expect == EXPECT_RESULT_PASS)
+	{
+		testFailed = !shader.getCompileStatus();
+		message = "Shader did not compile.";
+	}
+	else
+	{
+		testFailed = shader.getCompileStatus();
+		message = "Shader was not expected to compile.";
+	}
+
+	if (testFailed)
+	{
+		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+		ctx.fail(message);
+	}
+}
+
+std::string getVersionAndExtension (NegativeTestContext& ctx)
+{
+	const bool				isES32	= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	const glu::GLSLVersion	version	= isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+
+	std::string versionAndExtension = glu::getGLSLVersionDeclaration(version);
+	versionAndExtension += " \n";
+
+	if (!isES32)
+		versionAndExtension += "#extension GL_OES_sample_variables : require \n";
+
+	return versionAndExtension;
+}
+
+void checkSupported (NegativeTestContext& ctx)
+{
+	const bool isES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+
+	if (!isES32 && !ctx.isExtensionSupported("GL_OES_sample_variables"))
+		TCU_THROW(NotSupportedError, "GL_OES_sample_variables is not supported.");
+}
+
+void write_to_read_only_types (NegativeTestContext& ctx)
+{
+	checkSupported(ctx);
+
+	std::ostringstream	shader;
+
+	struct testConfig
+	{
+		std::string builtInType;
+		std::string varyingCheck;
+	} testConfigs[] =
+	{
+		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
+		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
+		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"}
+	};
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< getVersionAndExtension(ctx)
+			<< "layout (location = 0) out mediump vec4 fs_color; \n"
+			<< "void main() \n"
+			<< "{ \n"
+			<<		testConfigs[idx].varyingCheck
+			<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
+			<< "} \n";
+
+		ctx.beginSection("OES_sample_variables: trying to write to built-in read-only variable" + testConfigs[idx].builtInType);
+		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+}
+
+void access_built_in_types_inside_other_shaders (NegativeTestContext& ctx)
+{
+	checkSupported(ctx);
+
+	if ((!ctx.isExtensionSupported("GL_EXT_tessellation_shader") && !ctx.isExtensionSupported("GL_OES_tessellation_shader")) ||
+		(!ctx.isExtensionSupported("GL_EXT_geometry_shader") && !ctx.isExtensionSupported("GL_OES_geometry_shader")))
+	{
+		TCU_THROW(NotSupportedError, "tessellation and geometry shader extensions not supported");
+	}
+
+	std::ostringstream	shader;
+
+	struct testConfig
+	{
+		std::string builtInType;
+		std::string varyingCheck;
+	} testConfigs[] =
+	{
+		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
+		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
+		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"},
+		{"gl_SampleMask",		"	highp int readValue = gl_SampleMask[0]; \n"},
+	};
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< getVersionAndExtension(ctx)
+			<< "void main () \n"
+			<< "{ \n"
+			<<		testConfigs[idx].varyingCheck
+			<< "	gl_Position = vec4(1.0f, 0.0f, 0.0f , 1.0f); \n"
+			<< "} \n";
+
+		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside vertex shader");
+		verifyShader(ctx, glu::SHADERTYPE_VERTEX, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< getVersionAndExtension(ctx)
+			<< "layout (vertices = 3) out; \n"
+			<< "void main () \n"
+			<< "{ \n"
+			<<		testConfigs[idx].varyingCheck
+			<< "} \n";
+
+		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation control shader");
+		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< getVersionAndExtension(ctx)
+			<< "layout (triangles, equal_spacing, ccw) in; \n"
+			<< "void main () \n"
+			<< "{ \n"
+			<<		testConfigs[idx].varyingCheck
+			<< "} \n";
+
+		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation evaluation shader");
+		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_EVALUATION, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< getVersionAndExtension(ctx)
+			<< "layout (triangles) in; \n"
+			<< "layout (triangle_strip, max_vertices = 32) out; \n"
+			<< "void main () \n"
+			<< "{ \n"
+			<<		testConfigs[idx].varyingCheck
+			<< "} \n";
+
+		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside geometry shader");
+		verifyShader(ctx, glu::SHADERTYPE_GEOMETRY, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+}
+
+void index_outside_sample_mask_range (NegativeTestContext& ctx)
+{
+	checkSupported(ctx);
+
+	std::ostringstream	shader;
+	const int			MAX_TYPES	= 2;
+	const int			MAX_INDEXES = 2;
+
+	struct testConfig
+	{
+		std::string builtInType[MAX_TYPES];
+		std::string invalidIndex[MAX_INDEXES];
+	} testConfigs =
+	{
+		{
+			"gl_SampleMask",
+			"gl_SampleMaskIn"
+		},
+		{
+			"	const highp int invalidIndex = (gl_MaxSamples + 31) / 32; \n",
+			"	const highp int invalidIndex = -1; \n"
+		}
+	};
+
+	for (int typeIdx = 0; typeIdx < MAX_TYPES; typeIdx++)
+	{
+		for (int invalidIdx = 0; invalidIdx < MAX_INDEXES; invalidIdx++)
+		{
+			shader.str("");
+			shader
+				<< getVersionAndExtension(ctx)
+				<< "layout (location = 0) out mediump vec4 fs_color; \n"
+				<< "void main() \n"
+				<< "{ \n"
+				<<		testConfigs.invalidIndex[invalidIdx]
+				<< "	highp int invalidValue = " << testConfigs.builtInType[typeIdx] << "[invalidIndex]; \n"
+				<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
+				<< "} \n";
+
+			ctx.beginSection("OES_sample_variables: using constant integral expression outside of " + testConfigs.builtInType[typeIdx] + " bounds");
+			verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
+			ctx.endSection();
+		}
+	}
+}
+
+void access_built_in_types_without_extension (NegativeTestContext& ctx)
+{
+	checkSupported(ctx);
+
+	std::ostringstream	shader;
+
+	struct testConfig
+	{
+		std::string builtInType;
+		std::string varyingCheck;
+	} testConfigs[] =
+	{
+		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
+		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
+		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"},
+		{"gl_SampleMask",		"	highp int readValue = gl_SampleMask[0]; \n"},
+	};
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< "#version 310 es \n"
+			<< "layout (location = 0) out mediump vec4 fs_color; \n"
+			<< "void main() \n"
+			<< "{ \n"
+			<<		testConfigs[idx].varyingCheck
+			<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
+			<< "} \n";
+
+		ctx.beginSection("OES_sample_variables: accessing built-in type " + testConfigs[idx].builtInType + " in shader version 310 ES without required extension");
+		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+}
+
+void redeclare_built_in_types (NegativeTestContext& ctx)
+{
+	checkSupported(ctx);
+
+	std::ostringstream	shader;
+	std::ostringstream	testName;
+
+	const char* const testConfigs[] =
+	{
+		"gl_SampleID",
+		"gl_SamplePosition",
+		"gl_SampleMaskIn",
+		"gl_SampleMask",
+	};
+
+	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
+	{
+		shader.str("");
+		shader
+			<< getVersionAndExtension(ctx)
+			<< "layout (location = 0) out mediump vec4 fs_color; \n"
+			<< "uniform lowp int " << testConfigs[idx] << "; \n"
+			<< "void main() \n"
+			<< "{ \n"
+			<< "	if (" << testConfigs[idx] << " == 0) \n"
+			<< "		fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
+			<< "	else \n"
+			<< "		fs_color = vec4(0.0f, 1.0f, 0.0f, 1.0f); \n"
+			<< "} \n";
+
+		testName.str("");
+		testName << "OES_sample_variables: redeclare built-in type " << testConfigs[idx];
+		ctx.beginSection(testName.str());
+		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
+		ctx.endSection();
+	}
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeSampleVariablesTestFunctions (void)
+{
+	const FunctionContainer funcs[] =
+	{
+		{write_to_read_only_types,						"write_to_read_only_types",						"tests trying writing to read-only built-in sample variables"},
+		{access_built_in_types_inside_other_shaders,	"access_built_in_types_inside_other_shaders",	"Tests try to access fragment shader sample variables in other shaders"},
+		{index_outside_sample_mask_range,				"index_outside_sample_mask_range",				"tests try to index into built-in sample array types out of bounds"},
+		{access_built_in_types_without_extension,		"access_built_in_types_without_extension",		"tests try to access built-in sample types without the correct extension using version 310 es"},
+		{redeclare_built_in_types,						"redeclare_built_in_types",						"Tests try to redeclare built-in sample types"},
+	};
+
+	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeSampleVariablesTests.hpp b/modules/gles31/functional/es31fNegativeSampleVariablesTests.hpp
new file mode 100644
index 0000000..e4d516f
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeSampleVariablesTests.hpp
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVESAMPLEVARIABLESTESTS_HPP
+#define _ES31FNEGATIVESAMPLEVARIABLESTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Sample Variables Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeSampleVariablesTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVESAMPLEVARIABLESTESTS_HPP
diff --git a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
index a80d6ca..e82734a 100644
--- a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
@@ -2503,6 +2503,126 @@
 	ctx.endSection();
 }
 
+void srgb_decode_samplerparameteri (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLuint	sampler		= 0x1234;
+	GLint	samplerMode	= -1;
+
+	ctx.glGenSamplers(1, &sampler);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteSamplers(1, &sampler);
+}
+
+void srgb_decode_samplerparameterf (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLuint	sampler	= 0x1234;
+	GLfloat	samplerMode	= -1.0f;
+
+	ctx.glGenSamplers(1, &sampler);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glSamplerParameterf(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteSamplers(1, &sampler);
+}
+
+void srgb_decode_samplerparameteriv (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	int		params[1]	= { GL_LINEAR };
+	GLuint	sampler		= 0x1234;
+
+	ctx.glGenSamplers(1, &sampler);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	params[0] = -1;
+	ctx.glSamplerParameteriv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, &params[0]);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteSamplers(1, &sampler);
+}
+
+void srgb_decode_samplerparameterfv (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	float	params[1]	= { GL_LINEAR };
+	GLuint	sampler		= 0x1234;
+
+	ctx.glGenSamplers(1, &sampler);
+
+	params[0] = -1.0f;
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glSamplerParameterfv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, &params[0]);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteSamplers(1, &sampler);
+}
+
+void srgb_decode_samplerparameterIiv (NegativeTestContext& ctx)
+{
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+		TCU_THROW(NotSupportedError, "glSamplerParameterIiv is not supported.");
+
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLint	samplerMode[]	= {GL_DEPTH_COMPONENT, GL_STENCIL_INDEX};
+	GLuint	sampler			= 0x1234;
+
+	ctx.glGenSamplers(1, &sampler);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	samplerMode[0] = -1;
+	samplerMode[1] = -1;
+	ctx.glSamplerParameterIiv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteSamplers(1, &sampler);
+}
+
+void srgb_decode_samplerparameterIuiv (NegativeTestContext& ctx)
+{
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+		TCU_THROW(NotSupportedError, "glSamplerParameterIuiv is not supported.");
+
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLuint	samplerMode[]	= {GL_DEPTH_COMPONENT, GL_STENCIL_INDEX};
+	GLuint	sampler			= 0x1234;
+
+	ctx.glGenSamplers(1, &sampler);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	samplerMode[0] = GL_DONT_CARE;
+	samplerMode[1] = GL_DONT_CARE;
+	ctx.glSamplerParameterIuiv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteSamplers(1, &sampler);
+}
+
 std::vector<FunctionContainer> getNegativeShaderApiTestFunctions ()
 {
 	FunctionContainer funcs[] =
@@ -2533,7 +2653,7 @@
 		{sampler_parameterf,					"sampler_parameterf",					"Invalid glSamplerParameterf() usage"		   },
 		{sampler_parameterfv,					"sampler_parameterfv",					"Invalid glSamplerParameterfv() usage"		   },
 		{sampler_parameterIiv,					"sampler_parameterIiv",					"Invalid glSamplerParameterIiv() usage"		   },
-		{sampler_parameterIuiv,					"sampler_parameterIuiv",				"Invalid glSamplerParameterIuiv() usage"		   },
+		{sampler_parameterIuiv,					"sampler_parameterIuiv",				"Invalid glSamplerParameterIuiv() usage"	   },
 		{get_attrib_location,					"get_attrib_location",					"Invalid glGetAttribLocation() usage"		   },
 		{get_uniform_location,					"get_uniform_location",					"Invalid glGetUniformLocation() usage"		   },
 		{bind_attrib_location,					"bind_attrib_location",					"Invalid glBindAttribLocation() usage"		   },
@@ -2574,6 +2694,12 @@
 		{transform_feedback_varyings,			"transform_feedback_varyings",			"Invalid glTransformFeedbackVaryings() usage"  },
 		{compile_compute_shader,				"compile_compute_shader",				"Invalid Compute Shader compilation"		   },
 		{link_compute_shader,					"link_compute_shader",					"Invalid Compute Shader linkage"			   },
+		{srgb_decode_samplerparameteri,			"srgb_decode_samplerparameteri",		"Invalid glSamplerParameteri() usage srgb"	   },
+		{srgb_decode_samplerparameterf,			"srgb_decode_samplerparameterf",		"Invalid glSamplerParameterf() usage srgb"	   },
+		{srgb_decode_samplerparameteriv,		"srgb_decode_samplerparameteriv",		"Invalid glSamplerParameteriv() usage srgb"	   },
+		{srgb_decode_samplerparameterfv,		"srgb_decode_samplerparameterfv",		"Invalid glSamplerParameterfv() usage srgb"	   },
+		{srgb_decode_samplerparameterIiv,		"srgb_decode_samplerparameterIiv",		"Invalid glSamplerParameterIiv() usage srgb"   },
+		{srgb_decode_samplerparameterIuiv,		"srgb_decode_samplerparameterIuiv",		"Invalid glSamplerParameterIiuv() usage srgb"  },
 	};
 
 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
diff --git a/modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.cpp b/modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.cpp
new file mode 100644
index 0000000..b74c5a6
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.cpp
@@ -0,0 +1,267 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative ShaderFramebufferFetch tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeShaderFramebufferFetchTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluShaderProgram.hpp"
+#include "tcuStringTemplate.hpp"
+
+namespace deqp
+{
+
+using std::string;
+using std::map;
+
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+static const char* vertexShaderSource		=	"${GLSL_VERSION_STRING}\n"
+												"\n"
+												"void main (void)\n"
+												"{\n"
+												"	gl_Position = vec4(0.0);\n"
+												"}\n";
+
+static const char* fragmentShaderSource		=	"${GLSL_VERSION_STRING}\n"
+												"layout(location = 0) out mediump vec4 fragColor;\n"
+												"\n"
+												"void main (void)\n"
+												"{\n"
+												"	fragColor = vec4(1.0);\n"
+												"}\n";
+
+static void checkExtensionSupport (NegativeTestContext& ctx, const char* extName)
+{
+	if (!ctx.getContextInfo().isExtensionSupported(extName))
+		throw tcu::NotSupportedError(string(extName) + " not supported");
+}
+
+static void checkFramebufferFetchSupport (NegativeTestContext& ctx)
+{
+	checkExtensionSupport(ctx, "GL_EXT_shader_framebuffer_fetch");
+}
+
+enum ProgramError
+{
+	PROGRAM_ERROR_LINK = 0,
+	PROGRAM_ERROR_COMPILE,
+	PROGRAM_ERROR_COMPILE_OR_LINK,
+};
+
+void verifyProgramError (NegativeTestContext& ctx, const glu::ShaderProgram& program,  ProgramError error, glu::ShaderType shaderType)
+{
+	bool	testFailed = false;
+	string	message;
+
+	ctx.getLog() << program;
+
+	switch (error)
+	{
+		case PROGRAM_ERROR_LINK:
+		{
+			message = "Program was not expected to link.";
+			testFailed = (program.getProgramInfo().linkOk);
+			break;
+		}
+		case PROGRAM_ERROR_COMPILE:
+		{
+			message = "Program was not expected to compile.";
+			testFailed = program.getShaderInfo(shaderType).compileOk;
+			break;
+		}
+		case PROGRAM_ERROR_COMPILE_OR_LINK:
+		{
+			message = "Program was not expected to compile or link.";
+			testFailed = (program.getProgramInfo().linkOk) && (program.getShaderInfo(shaderType).compileOk);
+			break;
+		}
+		default:
+		{
+			DE_FATAL("Invalid program error type");
+			break;
+		}
+	}
+
+	if (testFailed)
+	{
+		ctx.getLog() << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+		ctx.fail(message);
+	}
+}
+
+void last_frag_data_not_defined (NegativeTestContext& ctx)
+{
+	checkFramebufferFetchSupport(ctx);
+
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
+											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
+											"layout(location = 0) out mediump vec4 fragColor;\n"
+											"\n"
+											"void main (void)\n"
+											"{\n"
+											"	fragColor = gl_LastFragData[0];\n"
+											"}\n";
+
+	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
+			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
+
+	ctx.beginSection("A link error is generated if the built-in fragment outputs of ES 2.0 are used in #version 300 es shaders");
+	verifyProgramError(ctx, program, PROGRAM_ERROR_LINK, glu::SHADERTYPE_FRAGMENT);
+	ctx.endSection();
+}
+
+void last_frag_data_readonly (NegativeTestContext& ctx)
+{
+	checkFramebufferFetchSupport(ctx);
+
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			=	getGLSLVersionDeclaration(glu::GLSL_VERSION_100_ES);
+
+	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
+											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
+											"\n"
+											"void main (void)\n"
+											"{\n"
+											"	gl_LastFragData[0] = vec4(1.0);\n"
+											"	gl_FragColor = gl_LastFragData[0];\n"
+											"}\n";
+
+	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
+			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
+
+	ctx.beginSection("A compile-time or link error is generated if the built-in fragment outputs of ES 2.0 are written to.");
+	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_FRAGMENT);
+	ctx.endSection();
+}
+
+void invalid_inout_version (NegativeTestContext& ctx)
+{
+	checkFramebufferFetchSupport(ctx);
+
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			=	getGLSLVersionDeclaration(glu::GLSL_VERSION_100_ES);
+
+	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
+											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
+											"inout highp vec4 fragColor;\n"
+											"\n"
+											"void main (void)\n"
+											"{\n"
+											"	highp float product = dot(vec3(0.5), fragColor.rgb);\n"
+											"	gl_FragColor = vec4(product);\n"
+											"}\n";
+
+	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
+			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
+
+	ctx.beginSection("A compile-time or link error is generated if user-defined inout arrays are used in earlier versions of GLSL before ES 3.0");
+	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_FRAGMENT);
+	ctx.endSection();
+}
+
+void invalid_redeclaration_inout (NegativeTestContext& ctx)
+{
+	checkFramebufferFetchSupport(ctx);
+
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
+											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
+											"layout(location = 0) out mediump vec4 fragColor;\n"
+											"inout highp float gl_FragDepth;\n"
+											"\n"
+											"void main (void)\n"
+											"{\n"
+											"	gl_FragDepth += 0.5f;\n"
+											"	fragColor = vec4(1.0f);\n"
+											"}\n";
+
+	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
+			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
+
+	ctx.beginSection("A compile-time or link error is generated if re-declaring an existing fragment output such as gl_FragDepth as inout");
+	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_FRAGMENT);
+	ctx.endSection();
+}
+
+void invalid_vertex_inout (NegativeTestContext& ctx)
+{
+	checkFramebufferFetchSupport(ctx);
+
+	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
+	const char* const vertShaderSource	=	"${GLSL_VERSION_STRING}\n"
+											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
+											"inout mediump vec4 v_color;\n"
+											"\n"
+											"void main (void)\n"
+											"{\n"
+											"}\n";
+
+	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
+			<< glu::VertexSource(tcu::StringTemplate(vertShaderSource).specialize(args))
+			<< glu::FragmentSource(tcu::StringTemplate(fragmentShaderSource).specialize(args)));
+
+	ctx.beginSection("A compile-time error or link error is generated if inout variables are declared in the vertex shader\n");
+	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_VERTEX);
+	ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeShaderFramebufferFetchTestFunctions (void)
+{
+	const FunctionContainer funcs[] =
+	{
+		{ last_frag_data_not_defined,		"last_frag_data_not_defined",		"The built-in gl_LastFragData not defined in #version 300 es shaders"				},
+		{ last_frag_data_readonly,			"last_frag_data_readonly",			"Invalid write to readonly builtin in gl_LastFragData"								},
+		{ invalid_inout_version,			"invalid_inout_version",			"Invalid use of user-defined inout arrays in versions before GLSL #version 300 es."	},
+		{ invalid_redeclaration_inout,		"invalid_redeclaration_inout",		"Existing fragment shader built-ins cannot be redeclared as inout arrays"			},
+		{ invalid_vertex_inout,				"invalid_vertex_inout",				"User defined inout arrays are not allowed in the vertex shader"					},
+	};
+
+	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.hpp b/modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.hpp
new file mode 100644
index 0000000..3fd55d7
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeShaderFramebufferFetchTests.hpp
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVESHADERFRAMEBUFFERFETCHTESTS_HPP
+#define _ES31FNEGATIVESHADERFRAMEBUFFERFETCHTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative ShaderFramebufferFetch tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeShaderFramebufferFetchTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles3
+} // deqp
+
+#endif // _ES31FNEGATIVESHADERFRAMEBUFFERFETCHTESTS_HPP
diff --git a/modules/gles31/functional/es31fNegativeTextureApiTests.cpp b/modules/gles31/functional/es31fNegativeTextureApiTests.cpp
index 52f7146..4acbdbe 100644
--- a/modules/gles31/functional/es31fNegativeTextureApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeTextureApiTests.cpp
@@ -1995,6 +1995,7 @@
 void texparameteriv (NegativeTestContext& ctx)
 {
 	GLint params[1] = {GL_LINEAR};
+
 	GLuint texture = 0x1234;
 	ctx.glGenTextures(1, &texture);
 	ctx.glBindTexture(GL_TEXTURE_2D, texture);
@@ -3909,6 +3910,132 @@
 	ctx.glDeleteTextures(2, textures);
 }
 
+void srgb_decode_texparameteri (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLuint	texture		= 0x1234;
+	GLint	textureMode	= -1;
+
+	ctx.glGenTextures(1, &texture);
+	ctx.glBindTexture(GL_TEXTURE_2D, texture);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, textureMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteTextures(1, &texture);
+}
+
+void srgb_decode_texparameterf (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLuint	texture		= 0x1234;
+	GLfloat	textureMode	= -1.0f;
+
+	ctx.glGenTextures(1, &texture);
+	ctx.glBindTexture(GL_TEXTURE_2D, texture);
+
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, textureMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteTextures(1, &texture);
+}
+
+void srgb_decode_texparameteriv (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLint	params[1]	= {GL_LINEAR};
+	GLuint	texture		= 0x1234;
+
+	ctx.glGenTextures(1, &texture);
+	ctx.glBindTexture(GL_TEXTURE_2D, texture);
+
+	params[0] = -1;
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, &params[0]);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteTextures(1, &texture);
+}
+
+void srgb_decode_texparameterfv (NegativeTestContext& ctx)
+{
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLfloat	params[1]	= {GL_LINEAR};
+	GLuint	texture		= 0x1234;
+
+	ctx.glGenTextures(1, &texture);
+	ctx.glBindTexture(GL_TEXTURE_2D, texture);
+
+	params[0] = -1.0f;
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, &params[0]);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteTextures(1, &texture);
+}
+
+void srgb_decode_texparameterIiv (NegativeTestContext& ctx)
+{
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+		TCU_THROW(NotSupportedError,"glTexParameterIiv is not supported.");
+
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLint	textureMode[]	= {GL_DEPTH_COMPONENT, GL_STENCIL_INDEX};
+	GLuint	texture			= 0x1234;
+
+	ctx.glGenTextures(1, &texture);
+	ctx.glBindTexture(GL_TEXTURE_2D, texture);
+
+	textureMode[0] = -1;
+	textureMode[1] = -1;
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glTexParameterIiv(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, textureMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteTextures(1, &texture);
+}
+
+void srgb_decode_texparameterIuiv (NegativeTestContext& ctx)
+{
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+		TCU_THROW(NotSupportedError,"glTexParameterIuiv is not supported.");
+
+	if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
+		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
+
+	GLuint	textureMode[]	= {GL_DEPTH_COMPONENT, GL_STENCIL_INDEX};
+	GLuint	texture			= 0x1234;
+
+	ctx.glGenTextures(1, &texture);
+	ctx.glBindTexture(GL_TEXTURE_2D, texture);
+
+	textureMode[0] = GL_DONT_CARE;
+	textureMode[1] = GL_DONT_CARE;
+	ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
+	ctx.glTexParameterIuiv(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, textureMode);
+	ctx.expectError(GL_INVALID_ENUM);
+	ctx.endSection();
+
+	ctx.glDeleteTextures(1, &texture);
+}
+
 std::vector<FunctionContainer> getNegativeTextureApiTestFunctions()
 {
 	FunctionContainer funcs[] =
@@ -4021,6 +4148,12 @@
 		{texstorage3d,									"texstorage3d",										"Invalid glTexStorage3D() usage"		   },
 		{texstorage3d_invalid_binding,					"texstorage3d_invalid_binding",						"Invalid glTexStorage3D() usage"		   },
 		{texstorage3d_invalid_levels,					"texstorage3d_invalid_levels",						"Invalid glTexStorage3D() usage"		   },
+		{srgb_decode_texparameteri,						"srgb_decode_texparameteri",						"Invalid texparameteri() usage srgb"	   },
+		{srgb_decode_texparameterf,						"srgb_decode_texparameterf",						"Invalid texparameterf() usage srgb"	   },
+		{srgb_decode_texparameteriv,					"srgb_decode_texparameteriv",						"Invalid texparameteriv() usage srgb"	   },
+		{srgb_decode_texparameterfv,					"srgb_decode_texparameterfv",						"Invalid texparameterfv() usage srgb"	   },
+		{srgb_decode_texparameterIiv,					"srgb_decode_texparameterIiv",						"Invalid texparameterIiv() usage srgb"	   },
+		{srgb_decode_texparameterIuiv,					"srgb_decode_texparameterIuiv",						"Invalid texparameterIuiv() usage srgb"	   },
 	};
 
 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
diff --git a/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp b/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
index 53a1414..1ed5f2d 100644
--- a/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
@@ -59,6 +59,13 @@
 												"	fragColor = vec4(0.0);\n"
 												"}\n\0";
 
+static const char* geometryShaderSource		=	"#version 320 es\n"
+												"layout(points) in;\n"
+												"layout(points, max_vertices = 3) out;\n"
+												"void main (void)\n"
+												"{\n"
+												"}\n";
+
 void vertex_attribf (NegativeTestContext& ctx)
 {
 	ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
@@ -663,8 +670,8 @@
 {
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
-	GLuint	fbo = 0;
-	GLfloat	vertices[1];
+	GLuint				fbo = 0;
+	GLfloat				vertices[1];
 
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not an accepted value.");
 	ctx.glDrawElementsBaseVertex(-1, 1, GL_UNSIGNED_INT, vertices, 1);
@@ -694,6 +701,25 @@
 	ctx.endSection();
 }
 
+void draw_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
+{
+	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
+
+	GLfloat						vertices[1];
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
+
+	glu::ShaderProgram			program(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
+
+	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
+	ctx.glUseProgram(program.getProgram());
+	ctx.glDrawElementsBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.expectError(GL_INVALID_OPERATION);
+	ctx.endSection();
+
+	ctx.glUseProgram(0);
+}
+
 void draw_arrays_instanced (NegativeTestContext& ctx)
 {
 	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
@@ -1003,7 +1029,7 @@
 	GLfloat						vertices[1];
 	map<string, string>			args;
 	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
-	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
+	glu::ShaderProgram			program			(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
 
 	ctx.glUseProgram(program.getProgram());
 	ctx.glVertexAttribDivisor(0, 1);
@@ -1041,6 +1067,24 @@
 	ctx.glUseProgram(0);
 }
 
+void draw_elements_instanced_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
+{
+	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
+
+	GLfloat						vertices[1];
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
+	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
+
+	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
+	ctx.glUseProgram(geometryProgram.getProgram());
+	ctx.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, 1, GL_UNSIGNED_INT, vertices, 1, 1);
+	ctx.expectError(GL_INVALID_OPERATION);
+	ctx.endSection();
+
+	ctx.glUseProgram(0);
+}
+
 void draw_range_elements (NegativeTestContext& ctx)
 {
 	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
@@ -1246,11 +1290,10 @@
 {
 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
 
-	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
 	GLuint						fbo		= 0;
 	GLfloat						vertices[1];
 	map<string, string>			args;
-	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+	args["GLSL_VERSION_STRING"]			= getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
 	glu::ShaderProgram			program	(ctx.getRenderContext(), glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderSource).specialize(args), tcu::StringTemplate(fragmentShaderSource).specialize(args)));
 
 	ctx.glUseProgram(program.getProgram());
@@ -1291,42 +1334,63 @@
 	ctx.glUseProgram(0);
 }
 
+void draw_range_elements_base_vertex_primitive_mode_mismatch (NegativeTestContext& ctx)
+{
+	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
+
+	GLfloat						vertices[1];
+	map<string, string>			args;
+	args["GLSL_VERSION_STRING"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES);
+	glu::ShaderProgram			geometryProgram(ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args)) << glu::GeometrySource(geometryShaderSource));
+
+	ctx.beginSection("GL_INVALID_OPERATION is generated if a geometry shader is active and mode is incompatible with the input primitive type of the geometry shader in the currently installed program object.");
+	ctx.glUseProgram(geometryProgram.getProgram());
+	ctx.glDrawRangeElementsBaseVertex(GL_TRIANGLES, 0, 1, 1, GL_UNSIGNED_INT, vertices, 1);
+	ctx.expectError(GL_INVALID_OPERATION);
+	ctx.endSection();
+
+	ctx.glUseProgram(0);
+}
+
 std::vector<FunctionContainer> getNegativeVertexArrayApiTestFunctions ()
 {
 	FunctionContainer funcs[] =
 	{
-		{vertex_attribf,								"vertex_attribf",								"Invalid glVertexAttrib{1234}f() usage"				},
-		{vertex_attribfv,								"vertex_attribfv",								"Invalid glVertexAttrib{1234}fv() usage"			},
-		{vertex_attribi4,								"vertex_attribi4",								"Invalid glVertexAttribI4{i|ui}f() usage"			},
-		{vertex_attribi4v,								"vertex_attribi4v",								"Invalid glVertexAttribI4{i|ui}fv() usage"			},
-		{vertex_attrib_pointer,							"vertex_attrib_pointer",						"Invalid glVertexAttribPointer() usage"				},
-		{vertex_attrib_i_pointer,						"vertex_attrib_i_pointer",						"Invalid glVertexAttribPointer() usage"				},
-		{vertex_attrib_format,							"vertex_attrib_format",							"Invalid glVertexAttribFormat() usage"				},
-		{vertex_attrib_i_format,						"vertex_attrib_i_format",						"Invalid glVertexAttribIFormat() usage"				},
-		{enable_vertex_attrib_array,					"enable_vertex_attrib_array",					"Invalid glEnableVertexAttribArray() usage"			},
-		{disable_vertex_attrib_array,					"disable_vertex_attrib_array",					"Invalid glDisableVertexAttribArray() usage"		},
-		{gen_vertex_arrays,								"gen_vertex_arrays",							"Invalid glGenVertexArrays() usage"					},
-		{bind_vertex_array,								"bind_vertex_array",							"Invalid glBindVertexArray() usage"					},
-		{delete_vertex_arrays,							"delete_vertex_arrays",							"Invalid glDeleteVertexArrays() usage"				},
-		{vertex_attrib_divisor,							"vertex_attrib_divisor",						"Invalid glVertexAttribDivisor() usage"				},
-		{draw_arrays,									"draw_arrays",									"Invalid glDrawArrays() usage"						},
-		{draw_arrays_invalid_program,					"draw_arrays_invalid_program",					"Invalid glDrawArrays() usage"						},
-		{draw_arrays_incomplete_primitive,				"draw_arrays_incomplete_primitive",				"Invalid glDrawArrays() usage"						},
-		{draw_elements,									"draw_elements",								"Invalid glDrawElements() usage"					},
-		{draw_elements_base_vertex,						"draw_elements_base_vertex",					"Invalid glDrawElementsBaseVertex() usage"			},
-		{draw_elements_invalid_program,					"draw_elements_invalid_program",				"Invalid glDrawElements() usage"					},
-		{draw_elements_incomplete_primitive,			"draw_elements_incomplete_primitive",			"Invalid glDrawElements() usage"					},
-		{draw_arrays_instanced,							"draw_arrays_instanced",						"Invalid glDrawArraysInstanced() usage"				},
-		{draw_arrays_instanced_invalid_program,			"draw_arrays_instanced_invalid_program",		"Invalid glDrawArraysInstanced() usage"				},
-		{draw_arrays_instanced_incomplete_primitive,	"draw_arrays_instanced_incomplete_primitive",	"Invalid glDrawArraysInstanced() usage"				},
-		{draw_elements_instanced,						"draw_elements_instanced",						"Invalid glDrawElementsInstanced() usage"			},
-		{draw_elements_instanced_invalid_program,		"draw_elements_instanced_invalid_program",		"Invalid glDrawElementsInstanced() usage"			},
-		{draw_elements_instanced_incomplete_primitive,	"draw_elements_instanced_incomplete_primitive",	"Invalid glDrawElementsInstanced() usage"			},
-		{draw_elements_instanced_base_vertex,			"draw_elements_instanced_base_vertex",			"Invalid glDrawElementsInstancedBaseVertex() usage"	},
-		{draw_range_elements,							"draw_range_elements",							"Invalid glDrawRangeElements() usage"				},
-		{draw_range_elements_invalid_program,			"draw_range_elements_invalid_program",			"Invalid glDrawRangeElements() usage"				},
-		{draw_range_elements_incomplete_primitive,		"draw_range_elements_incomplete_primitive",		"Invalid glDrawRangeElements() usage"				},
-		{draw_range_elements_base_vertex,				"draw_range_elements_base_vertex",				"Invalid glDrawRangeElementsBaseVertex() usage"		},
+		{vertex_attribf,												"vertex_attribf",												"Invalid glVertexAttrib{1234}f() usage"				},
+		{vertex_attribfv,												"vertex_attribfv",												"Invalid glVertexAttrib{1234}fv() usage"			},
+		{vertex_attribi4,												"vertex_attribi4",												"Invalid glVertexAttribI4{i|ui}f() usage"			},
+		{vertex_attribi4v,												"vertex_attribi4v",												"Invalid glVertexAttribI4{i|ui}fv() usage"			},
+		{vertex_attrib_pointer,											"vertex_attrib_pointer",										"Invalid glVertexAttribPointer() usage"				},
+		{vertex_attrib_i_pointer,										"vertex_attrib_i_pointer",										"Invalid glVertexAttribPointer() usage"				},
+		{vertex_attrib_format,											"vertex_attrib_format",											"Invalid glVertexAttribFormat() usage"				},
+		{vertex_attrib_i_format,										"vertex_attrib_i_format",										"Invalid glVertexAttribIFormat() usage"				},
+		{enable_vertex_attrib_array,									"enable_vertex_attrib_array",									"Invalid glEnableVertexAttribArray() usage"			},
+		{disable_vertex_attrib_array,									"disable_vertex_attrib_array",									"Invalid glDisableVertexAttribArray() usage"		},
+		{gen_vertex_arrays,												"gen_vertex_arrays",											"Invalid glGenVertexArrays() usage"					},
+		{bind_vertex_array,												"bind_vertex_array",											"Invalid glBindVertexArray() usage"					},
+		{delete_vertex_arrays,											"delete_vertex_arrays",											"Invalid glDeleteVertexArrays() usage"				},
+		{vertex_attrib_divisor,											"vertex_attrib_divisor",										"Invalid glVertexAttribDivisor() usage"				},
+		{draw_arrays,													"draw_arrays",													"Invalid glDrawArrays() usage"						},
+		{draw_arrays_invalid_program,									"draw_arrays_invalid_program",									"Invalid glDrawArrays() usage"						},
+		{draw_arrays_incomplete_primitive,								"draw_arrays_incomplete_primitive",								"Invalid glDrawArrays() usage"						},
+		{draw_elements,													"draw_elements",												"Invalid glDrawElements() usage"					},
+		{draw_elements_base_vertex,										"draw_elements_base_vertex",									"Invalid glDrawElementsBaseVertex() usage"			},
+		{draw_elements_base_vertex_primitive_mode_mismatch,				"draw_elements_base_vertex_primitive_mode_mismatch",			"Invalid glDrawElementsBaseVertex() usage"			},
+		{draw_elements_invalid_program,									"draw_elements_invalid_program",								"Invalid glDrawElements() usage"					},
+		{draw_elements_incomplete_primitive,							"draw_elements_incomplete_primitive",							"Invalid glDrawElements() usage"					},
+		{draw_arrays_instanced,											"draw_arrays_instanced",										"Invalid glDrawArraysInstanced() usage"				},
+		{draw_arrays_instanced_invalid_program,							"draw_arrays_instanced_invalid_program",						"Invalid glDrawArraysInstanced() usage"				},
+		{draw_arrays_instanced_incomplete_primitive,					"draw_arrays_instanced_incomplete_primitive",					"Invalid glDrawArraysInstanced() usage"				},
+		{draw_elements_instanced,										"draw_elements_instanced",										"Invalid glDrawElementsInstanced() usage"			},
+		{draw_elements_instanced_invalid_program,						"draw_elements_instanced_invalid_program",						"Invalid glDrawElementsInstanced() usage"			},
+		{draw_elements_instanced_incomplete_primitive,					"draw_elements_instanced_incomplete_primitive",					"Invalid glDrawElementsInstanced() usage"			},
+		{draw_elements_instanced_base_vertex,							"draw_elements_instanced_base_vertex",							"Invalid glDrawElementsInstancedBaseVertex() usage"	},
+		{draw_elements_instanced_base_vertex_primitive_mode_mismatch,	"draw_elements_instanced_base_vertex_primitive_mode_mismatch",	"Invalid glDrawElementsInstancedBaseVertex() usage"	},
+		{draw_range_elements,											"draw_range_elements",											"Invalid glDrawRangeElements() usage"				},
+		{draw_range_elements_invalid_program,							"draw_range_elements_invalid_program",							"Invalid glDrawRangeElements() usage"				},
+		{draw_range_elements_incomplete_primitive,						"draw_range_elements_incomplete_primitive",						"Invalid glDrawRangeElements() usage"				},
+		{draw_range_elements_base_vertex,								"draw_range_elements_base_vertex",								"Invalid glDrawRangeElementsBaseVertex() usage"		},
+		{draw_range_elements_base_vertex_primitive_mode_mismatch,		"draw_range_elements_base_vertex_primitive_mode_mismatch",		"Invalid glDrawRangeElementsBaseVertex() usage"		},
 	};
 
 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
diff --git a/modules/gles31/functional/es31fSRGBDecodeTests.cpp b/modules/gles31/functional/es31fSRGBDecodeTests.cpp
index 41e3a8c..9a6cdf4 100644
--- a/modules/gles31/functional/es31fSRGBDecodeTests.cpp
+++ b/modules/gles31/functional/es31fSRGBDecodeTests.cpp
@@ -312,11 +312,9 @@
 	void		setTextureUnit		(const deUint32 textureUnit);
 	void		setIsActive			(const bool isActive);
 
-	deUint32	getHandle			(void) const;
 	bool		getIsActive			(void) const;
 
 	void		bindToTexture		(void);
-	void		unbindFromTexture	(void);
 
 private:
 	const glw::Functions*		m_gl;
@@ -388,11 +386,6 @@
 	m_isActive = isActive;
 }
 
-deUint32 SRGBTestSampler::getHandle (void) const
-{
-	return m_samplerHandle;
-}
-
 bool SRGBTestSampler::getIsActive (void) const
 {
 	return m_isActive;
@@ -403,11 +396,6 @@
 	m_gl->bindSampler(m_textureUnit, m_samplerHandle);
 }
 
-void SRGBTestSampler::unbindFromTexture (void)
-{
-	m_gl->bindSampler(m_textureUnit, 0);
-}
-
 class SRGBTestTexture
 {
 public:
@@ -431,7 +419,6 @@
 	deUint32	getHandle			(void) const;
 	deUint32	getGLTargetType		(void) const;
 	SRGBDecode	getDecode			(void) const;
-	bool		getHasSampler		(void) const;
 
 	void		upload				(void);
 
@@ -566,11 +553,6 @@
 	return m_decoding;
 }
 
-bool SRGBTestTexture::getHasSampler (void) const
-{
-	return m_hasSampler;
-}
-
 void SRGBTestTexture::upload (void)
 {
 	m_source.upload();
@@ -605,14 +587,10 @@
 	void							setToggleRequired		(bool toggleRequired);
 	void							setUniformToggle		(int location, bool toggleDecodeValue);
 
-	int								getUniformTotal			(void) const;
 	const std::vector<UniformData>&	getUniformDataList		(void) const;
-	const UniformData&				getUniformAtLocation	(int location) const;
 	int								getUniformLocation		(const std::string& name);
 	deUint32						getHandle				(void) const;
 	bool							getBlendRequired		(void) const;
-	bool							getToggleRequired		(void) const;
-	const std::string&				getFragmentShader		(void) const;
 
 private:
 	std::string						genFunctionCall			(ShaderSamplingType samplingType, const int uniformIdx);
@@ -714,21 +692,11 @@
 	}
 }
 
-int SRGBTestProgram::getUniformTotal (void) const
-{
-	return (int)m_uniformDataList.size();
-}
-
 const std::vector<UniformData>& SRGBTestProgram::getUniformDataList (void) const
 {
 	return m_uniformDataList;
 }
 
-const UniformData& SRGBTestProgram::getUniformAtLocation (int location) const
-{
-	return m_uniformDataList[location];
-}
-
 int SRGBTestProgram::getUniformLocation (const std::string& name)
 {
 	for (std::size_t idx = 0; idx < m_uniformDataList.size(); idx++)
@@ -753,16 +721,6 @@
 	return m_blendRequired;
 }
 
-bool SRGBTestProgram::getToggleRequired (void) const
-{
-	return m_toggleRequired;
-}
-
-const std::string& SRGBTestProgram::getFragmentShader (void) const
-{
-	return m_shaderFragment;
-}
-
 std::string SRGBTestProgram::genFunctionCall (ShaderSamplingType samplingType, const int uniformIdx)
 {
 	std::ostringstream functionCall;
@@ -905,13 +863,8 @@
 
 	void					setSamplingGroup				(const ShaderSamplingGroup samplingGroup);
 	void					setSamplingLocations			(const int px, const int py);
-	void					setShaderProgramBlendRequired	(const int programIdx, const bool blend);
-	void					setShaderProgramToggleRequired	(const int programIdx, const bool toggle);
 	void					setUniformToggle				(const int programIdx, const std::string& uniformName, bool toggleDecode);
 
-	deUint32				getShaderProgramHandle			(const int programIdx) const;
-	deUint32				getTextureHandle				(const int textureIdx) const;
-
 	void					addTexture						(const glu::TextureTestUtil::TextureType	targetType,
 															 const int									width,
 															 const int									height,
@@ -1105,32 +1058,6 @@
 	m_py = py;
 }
 
-void SRGBTestCase::setShaderProgramBlendRequired (const int programIdx, const bool blend)
-{
-	m_shaderProgramList[programIdx]->setBlendRequired(blend);
-}
-
-void SRGBTestCase::setShaderProgramToggleRequired (const int programIdx, const bool toggle)
-{
-	m_shaderProgramList[programIdx]->setToggleRequired(toggle);
-}
-
-void SRGBTestCase::setUniformToggle (const int programIdx, const std::string& uniformName, bool toggleDecodeValue)
-{
-	int uniformLocation = m_shaderProgramList[programIdx]->getUniformLocation(uniformName);
-	m_shaderProgramList[programIdx]->setUniformToggle(uniformLocation, toggleDecodeValue);
-}
-
-deUint32 SRGBTestCase::getShaderProgramHandle (const int programIdx) const
-{
-	return m_shaderProgramList[programIdx]->getHandle();
-}
-
-deUint32 SRGBTestCase::getTextureHandle (const int textureIdx) const
-{
-	return m_textureSourceList[textureIdx]->getHandle();
-}
-
 void SRGBTestCase::addTexture (	const glu::TextureTestUtil::TextureType	targetType,
 								const int								width,
 								const int								height,
diff --git a/modules/gles31/functional/es31fShaderFramebufferFetchTests.cpp b/modules/gles31/functional/es31fShaderFramebufferFetchTests.cpp
new file mode 100644
index 0000000..c9b0c69
--- /dev/null
+++ b/modules/gles31/functional/es31fShaderFramebufferFetchTests.cpp
@@ -0,0 +1,1426 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief EXT Shader Framebuffer Fetch Tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fShaderFramebufferFetchTests.hpp"
+#include "es31fFboTestUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuSurface.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuVectorUtil.hpp"
+
+#include "gluShaderProgram.hpp"
+#include "gluPixelTransfer.hpp"
+#include "gluTextureUtil.hpp"
+#include "gluContextInfo.hpp"
+#include "gluObjectWrapper.hpp"
+
+#include "glwFunctions.hpp"
+#include "glwEnums.hpp"
+
+#include "deStringUtil.hpp"
+
+#include <vector>
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace
+{
+
+using std::vector;
+using std::string;
+using tcu::TestLog;
+
+using namespace glw;
+using namespace FboTestUtil;
+
+static void checkExtensionSupport (Context& context, const char* extName)
+{
+	if (!context.getContextInfo().isExtensionSupported(extName))
+		throw tcu::NotSupportedError(string(extName) + " not supported");
+}
+
+static void checkFramebufferFetchSupport (Context& context)
+{
+	checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
+}
+
+static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
+{
+	const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
+	switch (format)
+	{
+		// Color-renderable formats
+		case GL_RGBA32I:
+		case GL_RGBA32UI:
+		case GL_RGBA16I:
+		case GL_RGBA16UI:
+		case GL_RGBA8:
+		case GL_RGBA8I:
+		case GL_RGBA8UI:
+		case GL_SRGB8_ALPHA8:
+		case GL_RGB10_A2:
+		case GL_RGB10_A2UI:
+		case GL_RGBA4:
+		case GL_RGB5_A1:
+		case GL_RGB8:
+		case GL_RGB565:
+		case GL_RG32I:
+		case GL_RG32UI:
+		case GL_RG16I:
+		case GL_RG16UI:
+		case GL_RG8:
+		case GL_RG8I:
+		case GL_RG8UI:
+		case GL_R32I:
+		case GL_R32UI:
+		case GL_R16I:
+		case GL_R16UI:
+		case GL_R8:
+		case GL_R8I:
+		case GL_R8UI:
+			return true;
+
+		// Float format
+		case GL_RGBA32F:
+		case GL_RGB32F:
+		case GL_R11F_G11F_B10F:
+		case GL_RG32F:
+		case GL_R32F:
+			return isES32;
+
+		default:
+			return false;
+	}
+}
+
+tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
+{
+	switch (tcu::getTextureChannelClass(format.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
+
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
+
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
+
+		default:
+			DE_ASSERT(false);
+			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
+	}
+}
+
+tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
+{
+	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
+	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
+
+	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
+	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
+
+	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
+	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
+
+	const tcu::IVec4	srcBits		= tcu::getTextureFormatBitDepth(sourceFormat);
+	const tcu::IVec4	readBits	= tcu::getTextureFormatBitDepth(readPixelsFormat);
+
+	return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
+}
+
+tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
+{
+	const tcu::IVec4	srcMantissaBits		= tcu::getTextureFormatMantissaBitDepth(sourceFormat);
+	const tcu::IVec4	readMantissaBits	= tcu::getTextureFormatMantissaBitDepth(readPixelsFormat);
+	tcu::IVec4			ULPDiff(0);
+
+	for (int i = 0; i < 4; i++)
+		if (readMantissaBits[i] >= srcMantissaBits[i])
+			ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i];
+
+	return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>()));
+}
+
+static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
+{
+	for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
+	{
+		const std::string& extension = *iter;
+
+		if (context.getContextInfo().isExtensionSupported(extension.c_str()))
+			return true;
+	}
+
+	return false;
+}
+
+static std::string getColorOutputType(tcu::TextureFormat format)
+{
+	switch (tcu::getTextureChannelClass(format.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:		return "uvec4";
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:		return "ivec4";
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:		return "vec4";
+		default:
+			DE_FATAL("Unsupported TEXTURECHANNELCLASS");
+			return "";
+	}
+}
+
+static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
+{
+	const bool					isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
+	std::vector<std::string>	out;
+
+	DE_ASSERT(!isRequiredFormat(format, renderContext));
+
+	switch (format)
+	{
+		case GL_RGB16F:
+			out.push_back("GL_EXT_color_buffer_half_float");
+			break;
+
+		case GL_RGBA16F:
+		case GL_RG16F:
+		case GL_R16F:
+			out.push_back("GL_EXT_color_buffer_half_float");
+
+		case GL_RGBA32F:
+		case GL_RGB32F:
+		case GL_R11F_G11F_B10F:
+		case GL_RG32F:
+		case GL_R32F:
+			if (!isES32)
+				out.push_back("GL_EXT_color_buffer_float");
+			break;
+
+		default:
+			break;
+	}
+
+	return out;
+}
+
+void checkFormatSupport (Context& context, deUint32 sizedFormat)
+{
+	const bool						isCoreFormat	= isRequiredFormat(sizedFormat, context.getRenderContext());
+	const std::vector<std::string>	requiredExts	= (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
+
+	// Check that we don't try to use invalid formats.
+	DE_ASSERT(isCoreFormat || !requiredExts.empty());
+
+	if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
+		throw tcu::NotSupportedError("Format not supported");
+}
+
+tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
+{
+	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(format);
+	const tcu::Vec4					cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
+	const tcu::Vec4					cBias			= fmtInfo.valueMin;
+
+	return tcu::RGBA(color).toVec() * cScale + cBias;
+}
+
+// Base class for framebuffer fetch test cases
+
+class FramebufferFetchTestCase : public TestCase
+{
+public:
+									FramebufferFetchTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+									~FramebufferFetchTestCase		(void);
+
+	void							init							(void);
+	void							deinit							(void);
+
+protected:
+	string							genPassThroughVertSource		(void);
+	virtual glu::ProgramSources		genShaderSources				(void);
+
+	void							genFramebufferWithTexture		(const tcu::Vec4& color);
+	void							genAttachementTexture			(const tcu::Vec4& color);
+	void							genUniformColor					(const tcu::Vec4& color);
+
+	void							render							(void);
+	void							verifyRenderbuffer				(TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
+
+	const glw::Functions&			m_gl;
+	const deUint32					m_format;
+
+	glu::ShaderProgram*				m_program;
+	GLuint							m_framebuffer;
+	GLuint							m_texColorBuffer;
+
+	tcu::TextureFormat				m_texFmt;
+	glu::TransferFormat				m_transferFmt;
+	bool							m_isFilterable;
+
+	enum
+	{
+		VIEWPORT_WIDTH	= 64,
+		VIEWPORT_HEIGHT = 64,
+	};
+};
+
+FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: TestCase (context, name, desc)
+	, m_gl					(m_context.getRenderContext().getFunctions())
+	, m_format				(format)
+	, m_program				(DE_NULL)
+	, m_framebuffer			(0)
+	, m_texColorBuffer		(0)
+	, m_texFmt				(glu::mapGLInternalFormat(m_format))
+	, m_transferFmt			(glu::getTransferFormat(m_texFmt))
+	, m_isFilterable		(glu::isGLInternalColorFormatFilterable(m_format))
+{
+}
+
+FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
+{
+	FramebufferFetchTestCase::deinit();
+}
+
+void FramebufferFetchTestCase::init (void)
+{
+	checkFramebufferFetchSupport (m_context);
+	checkFormatSupport(m_context, m_format);
+
+	DE_ASSERT(!m_program);
+	m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
+
+	m_testCtx.getLog() << *m_program;
+
+	if (!m_program->isOk())
+	{
+		delete m_program;
+		m_program = DE_NULL;
+		TCU_FAIL("Failed to compile shader program");
+	}
+
+	m_gl.useProgram(m_program->getProgram());
+}
+
+void FramebufferFetchTestCase::deinit (void)
+{
+	delete m_program;
+	m_program = DE_NULL;
+
+	if (m_framebuffer)
+	{
+		m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+		m_gl.deleteFramebuffers(1, &m_framebuffer);
+		m_framebuffer = 0;
+	}
+
+	if (m_texColorBuffer)
+	{
+		m_gl.deleteTextures(1, &m_texColorBuffer);
+		m_texColorBuffer = 0;
+	}
+}
+
+string FramebufferFetchTestCase::genPassThroughVertSource (void)
+{
+	std::ostringstream vertShaderSource;
+
+	vertShaderSource	<< "#version 310 es\n"
+						<< "in highp vec4 a_position;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	gl_Position = a_position;\n"
+						<< "}\n";
+
+	return vertShaderSource.str();
+}
+
+glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
+{
+	const string		vecType	= getColorOutputType(m_texFmt);
+	std::ostringstream	fragShaderSource;
+
+	fragShaderSource	<< "#version 310 es\n"
+						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
+						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
+						<< "uniform highp " << vecType << " u_color;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	o_color += u_color;\n"
+						<< "}\n";
+
+	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
+}
+
+void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
+{
+	m_gl.genFramebuffers(1, &m_framebuffer);
+	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
+
+	genAttachementTexture(color);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
+
+	m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
+	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+}
+
+void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
+{
+	tcu::TextureLevel			data					(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	tcu::TextureChannelClass	textureChannelClass =	tcu::getTextureChannelClass(m_texFmt.type);
+
+	m_gl.genTextures(1, &m_texColorBuffer);
+	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
+
+	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
+	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
+	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
+	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
+	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
+
+	if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
+		tcu::clear(data.getAccess(), color.asUint());
+	else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
+		tcu::clear(data.getAccess(), color.asInt());
+	else
+		tcu::clear(data.getAccess(), color);
+
+	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
+	m_gl.bindTexture(GL_TEXTURE_2D, 0);
+}
+
+void FramebufferFetchTestCase::verifyRenderbuffer (TestLog&	log, const tcu::TextureFormat& format, const tcu::TextureLevel&	reference, const tcu::TextureLevel&	result)
+{
+	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+
+	switch (tcu::getTextureChannelClass(format.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		{
+			const string		name		= "Renderbuffer";
+			const string		desc		= "Compare renderbuffer (floating_point)";
+			const tcu::UVec4	threshold	= getFloatULPThreshold(format, result.getFormat());
+
+			if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
+				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+		{
+			const string		name		= "Renderbuffer";
+			const string		desc		= "Compare renderbuffer (integer)";
+			const tcu::UVec4	threshold	(1, 1, 1, 1);
+
+			if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
+				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		{
+			const string		name		= "Renderbuffer";
+			const string		desc		= "Compare renderbuffer (fixed point)";
+			const tcu::Vec4		threshold	= getFixedPointFormatThreshold(format, result.getFormat());
+
+			if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
+				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+			break;
+		}
+
+		default:
+		{
+			DE_ASSERT(DE_FALSE);
+			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+		}
+	}
+}
+
+void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
+{
+	const GLuint colorLocation	= m_gl.getUniformLocation(m_program->getProgram(), "u_color");
+
+	switch (tcu::getTextureChannelClass(m_texFmt.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+		{
+			m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		{
+			m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
+			break;
+		}
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		{
+			m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
+			break;
+		}
+		default:
+			DE_ASSERT(DE_FALSE);
+	}
+
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
+}
+
+void FramebufferFetchTestCase::render (void)
+{
+	const GLfloat coords[] =
+	{
+		-1.0f, -1.0f,
+		+1.0f, -1.0f,
+		+1.0f, +1.0f,
+		-1.0f, +1.0f,
+	};
+
+	const GLushort indices[] =
+	{
+		0, 1, 2, 2, 3, 0,
+	};
+
+	const GLuint	coordLocation	= m_gl.getAttribLocation(m_program->getProgram(), "a_position");
+
+	m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	glu::Buffer coordinatesBuffer(m_context.getRenderContext());
+	glu::Buffer elementsBuffer(m_context.getRenderContext());
+
+	m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
+	m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
+	m_gl.enableVertexAttribArray(coordLocation);
+	m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
+
+	m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
+	m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
+
+	m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
+}
+
+// Test description:
+// - Attach texture containing solid color to framebuffer.
+// - Draw full quad covering the entire viewport.
+// - Sum framebuffer read color with passed in uniform color.
+// - Compare resulting surface with reference.
+
+class TextureFormatTestCase : public FramebufferFetchTestCase
+{
+public:
+						TextureFormatTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+						~TextureFormatTestCase		(void) {};
+
+	IterateResult		iterate						(void);
+
+private:
+	tcu::TextureLevel	genReferenceTexture			(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
+};
+
+TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+{
+}
+
+tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
+{
+	tcu::TextureLevel			reference			(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	tcu::TextureChannelClass	textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
+
+	if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
+	{
+		tcu::clear(reference.getAccess(), fbColor.asUint() + uniformColor.asUint());
+	}
+	else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
+	{
+		tcu::clear(reference.getAccess(), fbColor.asInt() + uniformColor.asInt());
+	}
+	else
+	{
+		if (tcu::isSRGB(m_texFmt))
+		{
+			const tcu::Vec4	fragmentColor = tcu::sRGBToLinear(fbColor) + uniformColor;
+			tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
+		}
+		else
+		{
+			tcu::clear(reference.getAccess(), fbColor + uniformColor);
+		}
+	}
+
+	return reference;
+}
+
+TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
+{
+	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
+	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
+
+	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	genFramebufferWithTexture(fbColor);
+	genUniformColor(uniformColor);
+	render();
+
+	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+	return STOP;
+}
+
+// Test description:
+// - Attach multiple textures containing solid colors to framebuffer.
+// - Draw full quad covering the entire viewport.
+// - For each render target sum framebuffer read color with passed in uniform color.
+// - Compare resulting surfaces with references.
+
+class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
+{
+public:
+						MultipleRenderTargetsTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+						~MultipleRenderTargetsTestCase		(void);
+
+	IterateResult		iterate								(void);
+	void				deinit								(void);
+
+private:
+	void				genFramebufferWithTextures			(const vector<tcu::Vec4>& colors);
+	void				genAttachmentTextures				(const vector<tcu::Vec4>& colors);
+	tcu::TextureLevel	genReferenceTexture					(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
+	glu::ProgramSources genShaderSources					(void);
+
+	enum
+	{
+		MAX_COLOR_BUFFERS = 4
+	};
+
+	GLuint				m_texColorBuffers					[MAX_COLOR_BUFFERS];
+	GLenum				m_colorBuffers						[MAX_COLOR_BUFFERS];
+};
+
+MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+	, m_texColorBuffers ()
+{
+	m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
+	m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
+	m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
+	m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
+}
+
+MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
+{
+	MultipleRenderTargetsTestCase::deinit();
+}
+
+void MultipleRenderTargetsTestCase::deinit (void)
+{
+	// Clean up texture data
+	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
+	{
+		if (m_texColorBuffers[i])
+			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
+	}
+
+	FramebufferFetchTestCase::deinit();
+}
+
+void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
+{
+	m_gl.genFramebuffers(1, &m_framebuffer);
+	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
+
+	genAttachmentTextures(colors);
+
+	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
+		m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
+
+	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+	m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
+}
+
+void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
+{
+	tcu::TextureLevel	data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+
+	m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
+
+	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
+	{
+		m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
+
+		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
+		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
+		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
+		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
+		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
+
+		clear(data.getAccess(), colors[i]);
+		m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
+	}
+
+	m_gl.bindTexture(GL_TEXTURE_2D, 0);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
+}
+
+tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	tcu::clear(reference.getAccess(), fbColor + uniformColor);
+
+	return reference;
+}
+
+glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
+{
+	const string		vecType	= getColorOutputType(m_texFmt);
+	std::ostringstream	fragShaderSource;
+
+	fragShaderSource	<< "#version 310 es\n"
+						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
+						<< "layout(location = 0) inout highp " << vecType << " o_color0;\n"
+						<< "layout(location = 1) inout highp " << vecType << " o_color1;\n"
+						<< "layout(location = 2) inout highp " << vecType << " o_color2;\n"
+						<< "layout(location = 3) inout highp " << vecType << " o_color3;\n"
+						<< "uniform highp " << vecType << " u_color;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	o_color0 += u_color;\n"
+						<< "	o_color1 += u_color;\n"
+						<< "	o_color2 += u_color;\n"
+						<< "	o_color3 += u_color;\n"
+						<< "}\n";
+
+	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
+}
+
+MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
+{
+	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	vector<tcu::Vec4> colors;
+	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
+	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
+	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
+	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
+
+	genFramebufferWithTextures(colors);
+	genUniformColor(uniformColor);
+	render();
+
+	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
+	{
+		tcu::TextureLevel	reference		= genReferenceTexture(colors[i], uniformColor);
+
+		m_gl.readBuffer(m_colorBuffers[i]);
+		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+	}
+
+	return STOP;
+}
+
+// Test description:
+// - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
+
+class LastFragDataTestCase : public FramebufferFetchTestCase
+{
+public:
+						LastFragDataTestCase			(Context& context, const char* name, const char* desc, deUint32 format);
+						~LastFragDataTestCase			(void) {};
+
+	IterateResult		iterate							(void);
+
+private:
+	glu::ProgramSources genShaderSources				(void);
+	tcu::TextureLevel	genReferenceTexture				(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
+};
+
+LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+{
+}
+
+glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
+{
+	const string		vecType	= getColorOutputType(m_texFmt);
+	std::ostringstream	vertShaderSource;
+	std::ostringstream	fragShaderSource;
+
+	vertShaderSource	<< "#version 100\n"
+						<< "attribute vec4 a_position;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	gl_Position = a_position;\n"
+						<< "}\n";
+
+	fragShaderSource	<< "#version 100\n"
+						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
+						<< "uniform highp " << vecType << " u_color;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	gl_FragColor = u_color + gl_LastFragData[0];\n"
+						<< "}\n";
+
+	return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
+}
+
+tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	tcu::clear(reference.getAccess(), fbColor + uniformColor);
+
+	return reference;
+}
+
+LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
+{
+	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
+	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
+
+	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	genFramebufferWithTexture(fbColor);
+	genUniformColor(uniformColor);
+	render();
+
+	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+	return STOP;
+}
+
+// Test description:
+// - Attach texture containing solid color to framebuffer.
+// - Create one 2D texture for sampler with a grid pattern
+// - Draw full screen quad covering the entire viewport.
+// - Sum color values taken from framebuffer texture and sampled texture
+// - Compare resulting surface with reference.
+
+class TexelFetchTestCase : public FramebufferFetchTestCase
+{
+public:
+						TexelFetchTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+						~TexelFetchTestCase		(void) {}
+
+	IterateResult		iterate					(void);
+
+private:
+	glu::ProgramSources genShaderSources		(void);
+	tcu::TextureLevel	genReferenceTexture		(const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
+	void				genSamplerTexture		(const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
+
+	GLuint				m_samplerTexture;
+};
+
+TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+	, m_samplerTexture(0)
+{
+}
+
+void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
+{
+	tcu::TextureLevel	data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+
+	m_gl.activeTexture(GL_TEXTURE1);
+
+	m_gl.genTextures(1, &m_samplerTexture);
+	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
+	m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
+
+	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
+	m_gl.bindTexture(GL_TEXTURE_2D, 0);
+
+	const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
+	m_gl.uniform1i(samplerLocation, 1);
+
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
+}
+
+glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
+{
+	const string		vecType	= getColorOutputType(m_texFmt);
+	std::ostringstream	fragShaderSource;
+
+	fragShaderSource	<< "#version 310 es\n"
+						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
+						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
+						<< "\n"
+						<< "uniform sampler2D u_sampler;\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
+						<< "}\n";
+
+	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
+}
+
+tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
+
+	return reference;
+}
+
+TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
+{
+	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
+	const tcu::Vec4		colorEven		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
+	const tcu::Vec4		colorOdd		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
+
+	genSamplerTexture(colorEven, colorOdd);
+	tcu::TextureLevel	reference		= genReferenceTexture(colorEven, colorOdd, fbColor);
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	genFramebufferWithTexture(fbColor);
+	render();
+
+	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+	// cleanup
+	m_gl.deleteTextures(1, &m_samplerTexture);
+
+	return STOP;
+}
+
+// Test description:
+// - Attach texture containing solid color to framebuffer.
+// - Draw full screen quad covering the entire viewport.
+// - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
+// - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
+// - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
+// - Compare resulting surface with reference.
+
+class MultipleAssignmentTestCase : public FramebufferFetchTestCase
+{
+public:
+						MultipleAssignmentTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+						~MultipleAssignmentTestCase		(void) {}
+
+	IterateResult		iterate							(void);
+
+private:
+	glu::ProgramSources genShaderSources				(void);
+	tcu::TextureLevel	genReferenceTexture				(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
+};
+
+MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+{
+}
+
+glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
+{
+	const string		vecType = getColorOutputType(m_texFmt);
+	std::ostringstream	vertShaderSource;
+	std::ostringstream	fragShaderSource;
+
+	vertShaderSource	<< "#version 310 es\n"
+						<< "in highp vec4 a_position;\n"
+						<< "out highp vec4 v_position;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	gl_Position = a_position;\n"
+						<< "	v_position  = gl_Position;\n"
+						<< "}\n";
+
+	fragShaderSource	<< "#version 310 es\n"
+						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
+						<< "in highp vec4 v_position;\n"
+						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
+						<< "uniform highp " << vecType << " u_color;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	if (v_position.x > 0.0f)\n"
+						<< "		o_color += u_color;\n"
+						<< "\n"
+						<< "	o_color += u_color;\n"
+						<< "}\n";
+
+	return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
+}
+
+tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+
+	int	width	= reference.getAccess().getWidth();
+	int	height	= reference.getAccess().getHeight();
+	int	left	= width /2;
+	int	top		= height/2;
+
+	tcu::Vec4 compositeColor(uniformColor * 2.0f);
+
+	tcu::clear(getSubregion(reference.getAccess(), left,		0,		0, width-left,	top,		1),	fbColor + compositeColor);
+	tcu::clear(getSubregion(reference.getAccess(), 0,			top,	0, left,		height-top,	1), fbColor + uniformColor);
+	tcu::clear(getSubregion(reference.getAccess(), left,		top,	0, width-left,	height-top, 1), fbColor + compositeColor);
+	tcu::clear(getSubregion(reference.getAccess(), 0,			0,		0, left,		top,		1),	fbColor + uniformColor);
+
+	return reference;
+}
+
+MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
+{
+	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
+	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
+
+	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+
+	genFramebufferWithTexture(fbColor);
+	genUniformColor(uniformColor);
+	render();
+
+	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+	return STOP;
+}
+
+// Test description:
+// - Attach texture containing grid pattern to framebuffer.
+// - Using framebuffer reads discard odd squares in the grid.
+// - The even squares framebuffer color is added to the passed in uniform color.
+
+class FragmentDiscardTestCase : public FramebufferFetchTestCase
+{
+public:
+						FragmentDiscardTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+						~FragmentDiscardTestCase	(void) {}
+
+	IterateResult		iterate						(void);
+
+private:
+	glu::ProgramSources genShaderSources			(void);
+	void				genFramebufferWithGrid		(const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
+	tcu::TextureLevel	genReferenceTexture			(const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
+};
+
+FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+{
+}
+
+glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
+{
+	const string		vecType	= getColorOutputType(m_texFmt);
+	std::ostringstream	fragShaderSource;
+
+	fragShaderSource	<< "#version 310 es\n"
+						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
+						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
+						<< "uniform highp " << vecType << " u_color;\n"
+						<< "\n"
+						<< "void main (void)\n"
+						<< "{\n"
+						<< "	const highp float threshold = 0.0005f;\n"
+						<< "	bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
+						<< "	if (valuesEqual)\n"
+						<< "		o_color += u_color;\n"
+						<< "	else\n"
+						<< "		discard;\n"
+						<< "}\n";
+
+	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
+}
+
+void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
+{
+	tcu::TextureLevel data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+
+	m_gl.genFramebuffers(1, &m_framebuffer);
+	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
+
+	m_gl.genTextures(1, &m_texColorBuffer);
+	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
+
+	tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
+
+	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
+	m_gl.bindTexture(GL_TEXTURE_2D, 0);
+
+	m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
+	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+}
+
+tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
+
+	return reference;
+}
+
+FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
+{
+	const tcu::Vec4		fbColorEven		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
+	const tcu::Vec4		fbColorOdd		= scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
+
+	tcu::TextureLevel	reference		= genReferenceTexture(fbColorEven, fbColorOdd);
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+	genFramebufferWithGrid(fbColorEven, fbColorOdd);
+
+	genUniformColor(fbColorEven);
+	render();
+
+	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+	return STOP;
+}
+
+// Test description:
+// - Create 2D texture array containing three mipmaps.
+// - Each mipmap level is assigned a different color.
+// - Attach single mipmap level to framebuffer and draw full screen quad.
+// - Sum framebuffer read color with passed in uniform color.
+// - Compare resulting surface with reference.
+// - Repeat for subsequent mipmap levels.
+
+class TextureLevelTestCase : public FramebufferFetchTestCase
+{
+public:
+						TextureLevelTestCase			(Context& context, const char* name, const char* desc, deUint32 format);
+						~TextureLevelTestCase			(void) {}
+
+	IterateResult		iterate							(void);
+
+private:
+	void				create2DTextureArrayMipMaps		(const vector<tcu::Vec4>& colors);
+	tcu::TextureLevel	genReferenceTexture				(int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
+	void				genReferenceMipmap				(const tcu::Vec4& color, tcu::TextureLevel& reference);
+};
+
+TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+{
+}
+
+void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
+{
+	int						numLevels	= (int)colors.size();
+	tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
+
+	m_gl.genTextures(1, &m_texColorBuffer);
+	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
+
+	m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
+	m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
+
+	for (int level = 0; level < numLevels; level++)
+	{
+		int		levelW		= de::max(1, VIEWPORT_WIDTH		>> level);
+		int		levelH		= de::max(1, VIEWPORT_HEIGHT	>> level);
+
+		levelData.setSize(levelW, levelH, 1);
+
+		clear(levelData.getAccess(), colors[level]);
+		m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
+	}
+
+	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
+}
+
+tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
+
+	genReferenceMipmap(colors[level] + uniformColor, reference);
+
+	return reference;
+}
+
+void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
+{
+	const int	width	= reference.getAccess().getWidth();
+	const int	height	= reference.getAccess().getHeight();
+	const int	left	= width  / 2;
+	const int	top		= height / 2;
+
+	clear(getSubregion(reference.getAccess(), left,		0,		0, width-left,	top,		1),	color);
+	clear(getSubregion(reference.getAccess(), 0,		top,	0, left,		height-top,	1), color);
+	clear(getSubregion(reference.getAccess(), left,		top,	0, width-left,	height-top, 1), color);
+	clear(getSubregion(reference.getAccess(), 0,		0,		0, left,		top,		1),	color);
+}
+
+TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
+{
+	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
+	vector<tcu::Vec4>	levelColors;
+
+	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
+	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
+	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
+
+	m_gl.genFramebuffers(1, &m_framebuffer);
+	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
+
+	create2DTextureArrayMipMaps(levelColors);
+
+	// attach successive mipmap layers to framebuffer and render
+	for (int level = 0; level < (int)levelColors.size(); ++level)
+	{
+		std::ostringstream name, desc;
+		name << "Level "		<< level;
+		desc << "Mipmap level " << level;
+
+		const tcu::ScopedLogSection	section			(m_testCtx.getLog(), name.str(), desc.str());
+		tcu::TextureLevel			result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
+		tcu::TextureLevel			reference		= genReferenceTexture(level, levelColors, uniformColor);
+
+		m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
+
+		genUniformColor(uniformColor);
+		render();
+
+		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+		if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
+			return STOP;
+	}
+
+	return STOP;
+}
+
+class TextureLayerTestCase : public FramebufferFetchTestCase
+{
+public:
+						TextureLayerTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
+						~TextureLayerTestCase		(void) {}
+
+	IterateResult		iterate						(void);
+
+private:
+	void				create2DTextureArrayLayers	(const vector<tcu::Vec4>&  colors);
+	tcu::TextureLevel	genReferenceTexture			(int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
+};
+
+TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
+	: FramebufferFetchTestCase(context, name, desc, format)
+{
+}
+
+void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
+{
+	int						numLayers	= (int)colors.size();
+	tcu::TextureLevel		layerData	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
+
+	m_gl.genTextures(1, &m_texColorBuffer);
+	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
+	m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
+	m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
+
+	layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
+
+	for (int layer = 0; layer < numLayers; layer++)
+	{
+		clear(layerData.getAccess(), colors[layer]);
+		m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr());
+	}
+
+	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+	GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
+}
+
+tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
+{
+	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
+	clear(reference.getAccess(), colors[layer] + uniformColor);
+
+	return reference;
+}
+
+// Test description
+// - Create 2D texture array containing three layers.
+// - Each layer is assigned a different color.
+// - Attach single layer to framebuffer and draw full screen quad.
+// - Sum framebuffer read color with passed in uniform color.
+// - Compare resulting surface with reference.
+// - Repeat for subsequent texture layers.
+
+TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
+{
+	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
+	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+	vector<tcu::Vec4>	layerColors;
+
+	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
+	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
+	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
+
+	m_gl.genFramebuffers(1, &m_framebuffer);
+	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
+
+	create2DTextureArrayLayers(layerColors);
+
+	for (int layer = 0; layer < (int)layerColors.size(); ++layer)
+	{
+		std::ostringstream name, desc;
+		name << "Layer " << layer;
+		desc << "Layer " << layer;
+
+		const tcu::ScopedLogSection section		(m_testCtx.getLog(), name.str(), desc.str());
+		tcu::TextureLevel			reference	= genReferenceTexture(layer, layerColors, uniformColor);
+
+		m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
+
+		genUniformColor(uniformColor);
+		render();
+
+		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
+		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
+
+		if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
+			return STOP;
+	}
+
+	return STOP;
+}
+
+} // Anonymous
+
+ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
+	: TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
+{
+}
+
+ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
+{
+}
+
+void ShaderFramebufferFetchTests::init (void)
+{
+	tcu::TestCaseGroup* const basicTestGroup				= new tcu::TestCaseGroup(m_testCtx, "basic",				"Basic framebuffer shader fetch tests");
+	tcu::TestCaseGroup* const framebufferFormatTestGroup	= new tcu::TestCaseGroup(m_testCtx, "framebuffer_format",	"Texture render target formats tests");
+
+	// basic
+	{
+		basicTestGroup->addChild(new TexelFetchTestCase				(m_context,		"texel_fetch",					"Framebuffer fetches in conjunction with shader texel fetches",			GL_RGBA8));
+		basicTestGroup->addChild(new LastFragDataTestCase			(m_context,		"last_frag_data",				"Framebuffer fetches with built-in fragment output of ES 2.0",			GL_RGBA8));
+		basicTestGroup->addChild(new FragmentDiscardTestCase		(m_context,		"fragment_discard",				"Framebuffer fetches in combination with fragment discards",			GL_RGBA8));
+		basicTestGroup->addChild(new MultipleAssignmentTestCase		(m_context,		"multiple_assignment",			"Multiple assignments to fragment color inout",							GL_RGBA8));
+		basicTestGroup->addChild(new MultipleRenderTargetsTestCase	(m_context,		"multiple_render_targets",		"Framebuffer fetches used in combination with multiple render targets",	GL_RGBA8));
+		basicTestGroup->addChild(new TextureLevelTestCase			(m_context,		"framebuffer_texture_level",	"Framebuffer fetches with individual texture render target mipmaps",	GL_RGBA8));
+		basicTestGroup->addChild(new TextureLayerTestCase			(m_context,		"framebuffer_texture_layer",	"Framebuffer fetches with individual texture render target layers",		GL_RGBA8));
+	}
+
+	// framebuffer formats
+	{
+		static const deUint32 colorFormats[] =
+		{
+			// RGBA formats
+			GL_RGBA32I,
+			GL_RGBA32UI,
+			GL_RGBA16I,
+			GL_RGBA16UI,
+			GL_RGBA8,
+			GL_RGBA8I,
+			GL_RGBA8UI,
+			GL_SRGB8_ALPHA8,
+			GL_RGB10_A2,
+			GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
+
+			// RGB formats
+			GL_RGB8,
+			GL_RGB565,
+
+			// RG formats
+			GL_RG32I,
+			GL_RG32UI,
+			GL_RG16I,
+			GL_RG16UI,
+			GL_RG8,
+			GL_RG8I,
+			GL_RG8UI,
+
+			// R formats
+			GL_R32I,
+			GL_R32UI,
+			GL_R16I,
+			GL_R16UI,
+			GL_R8,
+			GL_R8I,
+			GL_R8UI,
+
+			// GL_EXT_color_buffer_float
+			GL_RGBA32F,
+			GL_RGBA16F,
+			GL_R11F_G11F_B10F,
+			GL_RG32F,
+			GL_RG16F,
+			GL_R32F,
+			GL_R16F,
+
+			// GL_EXT_color_buffer_half_float
+			GL_RGB16F
+		};
+
+		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
+			framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
+	}
+
+	addChild(basicTestGroup);
+	addChild(framebufferFormatTestGroup);
+}
+
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fShaderFramebufferFetchTests.hpp b/modules/gles31/functional/es31fShaderFramebufferFetchTests.hpp
new file mode 100644
index 0000000..ec02d79
--- /dev/null
+++ b/modules/gles31/functional/es31fShaderFramebufferFetchTests.hpp
@@ -0,0 +1,54 @@
+#ifndef _ES31FSHADERFRAMEBUFFERFETCHTESTS_HPP
+#define _ES31FSHADERFRAMEBUFFERFETCHTESTS_HPP
+
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief EXT Shader Framebuffer Fetch Tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes31TestCase.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+
+class ShaderFramebufferFetchTests : public TestCaseGroup
+{
+public:
+									ShaderFramebufferFetchTests		(Context& context);
+									~ShaderFramebufferFetchTests	(void);
+
+	void							init							(void);
+
+private:
+	ShaderFramebufferFetchTests&	operator=						(const ShaderFramebufferFetchTests&);
+	ShaderFramebufferFetchTests										(const ShaderFramebufferFetchTests&);
+};
+
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FSHADERFRAMEBUFFERFETCHTESTS_HPP
diff --git a/modules/glshared/glsDrawTest.cpp b/modules/glshared/glsDrawTest.cpp
index c74dd4c..c485b6e 100644
--- a/modules/glshared/glsDrawTest.cpp
+++ b/modules/glshared/glsDrawTest.cpp
@@ -43,6 +43,7 @@
 #include "tcuFloat.hpp"
 #include "tcuTextureUtil.hpp"
 
+#include "gluContextInfo.hpp"
 #include "gluPixelTransfer.hpp"
 #include "gluCallLogWrapper.hpp"
 
@@ -3034,6 +3035,7 @@
 DrawTest::DrawTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const DrawTestSpec& spec, const char* name, const char* desc)
 	: TestCase			(testCtx, name, desc)
 	, m_renderCtx		(renderCtx)
+	, m_contextInfo		(DE_NULL)
 	, m_refBuffers		(DE_NULL)
 	, m_refContext		(DE_NULL)
 	, m_glesContext		(DE_NULL)
@@ -3051,6 +3053,7 @@
 DrawTest::DrawTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc)
 	: TestCase			(testCtx, name, desc)
 	, m_renderCtx		(renderCtx)
+	, m_contextInfo		(DE_NULL)
 	, m_refBuffers		(DE_NULL)
 	, m_refContext		(DE_NULL)
 	, m_glesContext		(DE_NULL)
@@ -3130,6 +3133,7 @@
 	m_maxDiffRed	= deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits)));
 	m_maxDiffGreen	= deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits)));
 	m_maxDiffBlue	= deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits)));
+	m_contextInfo	= glu::ContextInfo::create(m_renderCtx);
 }
 
 void DrawTest::deinit (void)
@@ -3139,21 +3143,32 @@
 	delete m_refBuffers;
 	delete m_refContext;
 	delete m_glesContext;
+	delete m_contextInfo;
 
 	m_glArrayPack	= DE_NULL;
 	m_rrArrayPack	= DE_NULL;
 	m_refBuffers	= DE_NULL;
 	m_refContext	= DE_NULL;
 	m_glesContext	= DE_NULL;
+	m_contextInfo	= DE_NULL;
 }
 
 DrawTest::IterateResult DrawTest::iterate (void)
 {
 	const int					specNdx			= (m_iteration / 2);
+	const DrawTestSpec&			spec			= m_specs[specNdx];
+
+	if (spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX ||
+		spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX ||
+		spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
+	{
+		const bool supportsES32 = contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 2));
+		TCU_CHECK_AND_THROW(NotSupportedError, supportsES32 || m_contextInfo->isExtensionSupported("GL_EXT_draw_elements_base_vertex"), "GL_EXT_draw_elements_base_vertex is not supported.");
+	}
+
 	const bool					drawStep		= (m_iteration % 2) == 0;
 	const bool					compareStep		= (m_iteration % 2) == 1;
 	const IterateResult			iterateResult	= ((size_t)m_iteration + 1 == m_specs.size()*2) ? (STOP) : (CONTINUE);
-	const DrawTestSpec&			spec			= m_specs[specNdx];
 	const bool					updateProgram	= (m_iteration == 0) || (drawStep && !checkSpecsShaderCompatible(m_specs[specNdx], m_specs[specNdx-1])); // try to use the same shader in all iterations
 	IterationLogSectionEmitter	sectionEmitter	(m_testCtx.getLog(), specNdx, m_specs.size(), m_iteration_descriptions[specNdx], drawStep && m_specs.size()!=1);
 
diff --git a/modules/glshared/glsDrawTest.hpp b/modules/glshared/glsDrawTest.hpp
index 5347269..8c04ef5 100644
--- a/modules/glshared/glsDrawTest.hpp
+++ b/modules/glshared/glsDrawTest.hpp
@@ -27,6 +27,11 @@
 #include "tcuResultCollector.hpp"
 #include "gluRenderContext.hpp"
 
+namespace glu
+{
+class ContextInfo;
+}
+
 namespace sglr
 {
 
@@ -259,6 +264,7 @@
 
 	glu::RenderContext&				m_renderCtx;
 
+	glu::ContextInfo*				m_contextInfo;
 	sglr::ReferenceContextBuffers*	m_refBuffers;
 	sglr::ReferenceContext*			m_refContext;
 	sglr::Context*					m_glesContext;
diff --git a/scripts/build_android_mustpass.py b/scripts/build_android_mustpass.py
index dae0b99..f63c9f6 100644
--- a/scripts/build_android_mustpass.py
+++ b/scripts/build_android_mustpass.py
@@ -441,7 +441,7 @@
 		exclude("gles31-hw-issues.txt"),
 		exclude("gles31-driver-issues.txt"),
 		exclude("gles31-test-issues.txt"),
-		exclude("gles31-spec-issues.txt")
+		exclude("gles31-spec-issues.txt"),
 	]
 MASTER_GLES31_PKG				= Package(module = GLES31_MODULE, configurations = [
 		# Master
@@ -501,7 +501,7 @@
 		exclude("vk-not-applicable.txt"),
 		exclude("vk-excluded-tests.txt"),
 		exclude("vk-test-issues.txt"),
-		exclude("vk-waivers.txt")
+		exclude("vk-waivers.txt"),
 	]
 MASTER_VULKAN_PKG				= Package(module = VULKAN_MODULE, configurations = [
 		Configuration(name			= "master",
diff --git a/scripts/egl/common.py b/scripts/egl/common.py
index c8761ce..919fece 100644
--- a/scripts/egl/common.py
+++ b/scripts/egl/common.py
@@ -4,7 +4,7 @@
 # drawElements Quality Program utilities
 # --------------------------------------
 #
-# Copyright 2015 The Android Open Source Project
+# Copyright 2015-2017 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -38,9 +38,10 @@
 EGL_WRAPPER_DIR		= os.path.normpath(os.path.join(EGL_DIR, "wrapper"))
 
 EGL_SOURCE			= khr_util.registry_cache.RegistrySource(
-						"egl.xml",
-						33315,
-						"19f3b517f0dede56a6a94b820d08149ef5e1726f58202f47d69fa27f6f483bd2")
+						"https://raw.githubusercontent.com/KhronosGroup/EGL-Registry",
+						"api/egl.xml",
+						"13a26984991216cbf9a44fbf390f95dc05b5493a",
+						"1c59e6b6b89d2b9047a8f5c680a6bb240b8048700ce91cefa0e870798da4f3db")
 
 VERSION				= '1.5'
 
@@ -66,7 +67,14 @@
 	"EGL_KHR_partial_update",
 	"EGL_KHR_swap_buffers_with_damage",
 	"EGL_KHR_mutable_render_buffer",
-	"EGL_EXT_pixel_format_float"
+	"EGL_EXT_pixel_format_float",
+	"EGL_KHR_gl_colorspace",
+	"EGL_EXT_gl_colorspace_bt2020_linear",
+	"EGL_EXT_gl_colorspace_bt2020_pq",
+	"EGL_EXT_gl_colorspace_display_p3",
+	"EGL_EXT_gl_colorspace_display_p3_linear",
+	"EGL_EXT_gl_colorspace_scrgb",
+	"EGL_EXT_gl_colorspace_scrgb_linear"
 ]
 PROTECTS			= [
 	"KHRONOS_SUPPORT_INT64"
diff --git a/scripts/egl/enums.py b/scripts/egl/enums.py
index 353062e..9ba4d4d 100644
--- a/scripts/egl/enums.py
+++ b/scripts/egl/enums.py
@@ -41,7 +41,11 @@
 
 def enumValue (enum, typePrefix = ""):
 	if enum.name in TYPED_VALUES:
-		return enum.value.replace("(EGL", "(%sEGL" % typePrefix)
+          # incoming is EGL_CAST(<type>, <value>)
+          n,v = enum.value.split(",", 1)
+          # output is ((<typePrefix>::<type>)<value>)
+          return "((%s%s)%s" % (typePrefix, n.replace("EGL_CAST(", ""), v)
+
 	else:
 		return normalizeConstant(enum.value)
 
diff --git a/scripts/khr_util/registry_cache.py b/scripts/khr_util/registry_cache.py
index 47f06e0..e8124a4 100644
--- a/scripts/khr_util/registry_cache.py
+++ b/scripts/khr_util/registry_cache.py
@@ -4,7 +4,7 @@
 # drawElements Quality Program utilities
 # --------------------------------------
 #
-# Copyright 2015 The Android Open Source Project
+# Copyright 2015-2017 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -29,22 +29,23 @@
 BASE_URL = ""
 
 class RegistrySource:
-	def __init__(self, filename, revision, checksum):
+	def __init__(self, repository, filename, revision, checksum):
+		self.repository	= repository
 		self.filename	= filename
 		self.revision	= revision
 		self.checksum	= checksum
 
 	def __hash__(self):
-		return hash((self.filename, self.revision, self.checksum))
+		return hash((self.repository, self.filename, self.revision, self.checksum))
 
 	def __eq__(self, other):
-		return (self.filename, self.revision, self.checksum) == (other.filename, other.revision, other.checksum)
+		return (self.repository, self.filename, self.revision, self.checksum) == (other.repository, other.filename, other.revision, other.checksum)
 
 	def getFilename (self):
-		return self.filename
+		return os.path.basename(self.filename)
 
 	def getCacheFilename (self):
-		return "r%d-%s" % (self.revision, self.filename)
+		return "r%s-%s" % (self.revision, self.getFilename())
 
 	def getChecksum (self):
 		return self.checksum
@@ -53,7 +54,7 @@
 		return self.revision
 
 	def getSourceUrl (self):
-		return "https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/%s?r=%d" % (self.filename, self.revision)
+		return "%s/%s/%s" % (self.repository, self.revision, self.filename)
 
 def computeChecksum (data):
 	return hashlib.sha256(data).hexdigest()
@@ -77,7 +78,7 @@
 	gotChecksum	= computeChecksum(data)
 
 	if checksum != gotChecksum:
-		raise Exception("Checksum mismatch, exepected %s, got %s" % (checksum, gotChecksum))
+		raise Exception("Checksum mismatch, expected %s, got %s" % (checksum, gotChecksum))
 
 	writeFile(dstPath, data)
 
diff --git a/scripts/opengl/src_util.py b/scripts/opengl/src_util.py
index 03b3051..6494273 100644
--- a/scripts/opengl/src_util.py
+++ b/scripts/opengl/src_util.py
@@ -4,7 +4,7 @@
 # drawElements Quality Program utilities
 # --------------------------------------
 #
-# Copyright 2015 The Android Open Source Project
+# Copyright 2015-2017 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -36,9 +36,10 @@
 OPENGL_INC_DIR		= os.path.join(OPENGL_DIR, "wrapper")
 
 GL_SOURCE			= khr_util.registry_cache.RegistrySource(
-						"gl.xml",
-						32093,
-						"3292120320cacbc27009e7507656d7be17bb25f06876814c67eeffa369281eed")
+						"https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry",
+						"xml/gl.xml",
+						"7ac9c857db1e3a6065485e4e2144151f48a4f1c4",
+						"2475e1ff6d69048e67a49188d8be09195b261ed96b2b4108a0f7d7a459834674")
 
 EXTENSIONS			= [
 	'GL_KHR_texture_compression_astc_ldr',
@@ -69,6 +70,8 @@
 	'GL_EXT_debug_marker',
 	'GL_EXT_robustness',
 	'GL_KHR_robustness',
+	'GL_EXT_draw_elements_base_vertex',
+	'GL_OES_draw_elements_base_vertex',
 ]
 
 def getGLRegistry ():
diff --git a/targets/x11_egl/x11_egl.cmake b/targets/x11_egl/x11_egl.cmake
index 8e8155b..dca529a 100644
--- a/targets/x11_egl/x11_egl.cmake
+++ b/targets/x11_egl/x11_egl.cmake
@@ -30,5 +30,26 @@
 	message(FATAL_ERROR "X11 development package not found")
 endif ()
 
+# Support GLES1, we use pkg-config because some distributions do not ship
+# GLES1 libraries and headers, this way user can override search path by
+# using PKG_CONFIG_PATH environment variable
+FIND_PACKAGE(PkgConfig)
+PKG_CHECK_MODULES(GLES1 glesv1_cm)
+if (GLES1_LIBRARIES)
+	set(DEQP_SUPPORT_GLES1	ON)
+	set(DEQP_GLES1_LIBRARIES ${GLES1_LIBRARIES})
+	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${GLES1_LIBRARY_DIRS}")
+	if ("${PKG_GLES1_INCLUDE_DIRS}" STREQUAL "")
+		# PKG_GLES1_INCLUDE_DIRS empty, see if matching include
+		# path (GLES/gl.h) exists beside library directory
+		set(GLES1_INCLUDE "${GLES1_LIBDIR}/../include")
+		if (EXISTS ${GLES1_INCLUDE}/GLES/gl.h)
+			include_directories(${GLES1_INCLUDE})
+		else()
+			message(FATAL_ERROR "Could not find include path for GLES1 headers")
+		endif (EXISTS ${GLES1_INCLUDE}/GLES/gl.h)
+	endif ("${PKG_GLES1_INCLUDE_DIRS}" STREQUAL "")
+endif (GLES1_LIBRARIES)
+
 set(DEQP_PLATFORM_LIBRARIES ${X11_LIBRARIES})
 include_directories(${X11_INCLUDE_DIR})