teglImageFormatTests: call glFinish after creating the buffer in the client API am: 84c981292b
am: 18638d541a

Change-Id: If19a6a3ff7941199488fc4315f366972af7589fb
diff --git a/Android.mk b/Android.mk
index 67c1f4e..fa97deb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -30,6 +30,7 @@
 	-Werror \
 	-Wconversion \
 	-fwrapv \
+	-Wno-implicit-fallthrough \
 	-Wno-sign-conversion
 
 LOCAL_SHARED_LIBRARIES := \
@@ -65,4 +66,4 @@
 # Build the test APKs using their own makefiles
 # include $(call all-makefiles-under,$(LOCAL_PATH)/android)
 
-include $(LOCAL_PATH)/android/package/Android.mk $(LOCAL_PATH)/android/cts/Android.mk
+include $(LOCAL_PATH)/android/package/Android.mk
diff --git a/android/cts/Android.bp b/android/cts/Android.bp
new file mode 100644
index 0000000..9f68df4
--- /dev/null
+++ b/android/cts/Android.bp
@@ -0,0 +1,60 @@
+// Copyright (C) 2015 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.
+//
+
+filegroup {
+    name: "deqp_master_caselists",
+    srcs: [
+        "master/*.txt",
+    ],
+    path: "master",
+}
+
+genrule {
+    name: "deqp_nyc_caselists",
+    srcs: [
+        "nyc/vk-master.txt",
+        "nyc/gles31-master.txt",
+        "nyc/egl-master.txt",
+    ],
+    out: [
+        "nyc-vk-master.txt",
+        "nyc-gles31-master.txt",
+        "nyc-egl-master.txt",
+    ],
+    cmd: "for i in $(in); do cp $$i $(genDir)/nyc-$$(basename $$i); done",
+}
+
+java_test_host {
+    name: "CtsDeqpTestCases",
+
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+
+    srcs: ["runner/src/**/*.java"],
+    libs: [
+        "cts-tradefed",
+        "compatibility-host-util",
+        "tradefed",
+    ],
+
+    data: [
+        ":deqp_master_caselists",
+        ":deqp_nyc_caselists",
+    ],
+}
diff --git a/android/cts/Android.mk b/android/cts/Android.mk
deleted file mode 100644
index 762eb2a..0000000
--- a/android/cts/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2015 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.
-#
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := CtsDeqpTestCases
-
-LOCAL_MODULE_TAGS := optional
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-LOCAL_SDK_VERSION := 22
-
-LOCAL_SRC_FILES := $(call all-java-files-under, runner/src)
-LOCAL_JAVA_LIBRARIES := cts-tradefed compatibility-host-util tradefed
-
-DEQP_CASELISTS:=$(sort $(patsubst master/%,%, \
-  $(shell cd $(LOCAL_PATH) ; \
-          find -L master -maxdepth 1 -name "*.txt") \
-  ))
-LOCAL_COMPATIBILITY_SUPPORT_FILES := $(foreach file, $(DEQP_CASELISTS), $(LOCAL_PATH)/master/$(file):$(file))
-LOCAL_COMPATIBILITY_SUPPORT_FILES += $(LOCAL_PATH)/nyc/vk-master.txt:nyc-vk-master.txt
-LOCAL_COMPATIBILITY_SUPPORT_FILES += $(LOCAL_PATH)/nyc/gles31-master.txt:nyc-gles31-master.txt
-LOCAL_COMPATIBILITY_SUPPORT_FILES += $(LOCAL_PATH)/nyc/egl-master.txt:nyc-egl-master.txt
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/android/cts/master/gles2-master.txt b/android/cts/master/gles2-master.txt
index f5b29ed..ddc36bd 100644
--- a/android/cts/master/gles2-master.txt
+++ b/android/cts/master/gles2-master.txt
@@ -6813,8 +6813,20 @@
 dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment
 dEQP-GLES2.functional.shaders.struct.local.parameter_vertex
 dEQP-GLES2.functional.shaders.struct.local.parameter_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_fragment
 dEQP-GLES2.functional.shaders.struct.local.parameter_nested_vertex
 dEQP-GLES2.functional.shaders.struct.local.parameter_nested_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_fragment
 dEQP-GLES2.functional.shaders.struct.local.return_vertex
 dEQP-GLES2.functional.shaders.struct.local.return_fragment
 dEQP-GLES2.functional.shaders.struct.local.return_nested_vertex
diff --git a/android/cts/master/gles3-master.txt b/android/cts/master/gles3-master.txt
index 34f8f3f..8b61a93 100644
--- a/android/cts/master/gles3-master.txt
+++ b/android/cts/master/gles3-master.txt
@@ -16259,8 +16259,20 @@
 dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment
 dEQP-GLES3.functional.shaders.struct.local.parameter_vertex
 dEQP-GLES3.functional.shaders.struct.local.parameter_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_fragment
 dEQP-GLES3.functional.shaders.struct.local.parameter_nested_vertex
 dEQP-GLES3.functional.shaders.struct.local.parameter_nested_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_fragment
 dEQP-GLES3.functional.shaders.struct.local.return_vertex
 dEQP-GLES3.functional.shaders.struct.local.return_fragment
 dEQP-GLES3.functional.shaders.struct.local.return_nested_vertex
@@ -18715,6 +18727,15 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.distance.highp_fragment.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.distance.highp_fragment.vec3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.distance.highp_fragment.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_vertex.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_vertex.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_fragment.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_fragment.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.mediump_vertex.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.mediump_vertex.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.mediump_fragment.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.highp_vertex.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.highp_fragment.vec3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.cross.lowp_vertex
 dEQP-GLES3.functional.shaders.builtin_functions.precision.cross.lowp_fragment
 dEQP-GLES3.functional.shaders.builtin_functions.precision.cross.mediump_vertex
@@ -18758,7 +18779,17 @@
 dEQP-GLES3.functional.shaders.builtin_functions.precision.faceforward.highp_fragment.vec3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.faceforward.highp_fragment.vec4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_vertex.scalar
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_vertex.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_vertex.vec4
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_fragment.scalar
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_fragment.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_fragment.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_vertex.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_vertex.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_fragment.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_fragment.vec4
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.highp_vertex.vec3
+dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.highp_fragment.vec3
 dEQP-GLES3.functional.shaders.builtin_functions.precision.refract.lowp_vertex.scalar
 dEQP-GLES3.functional.shaders.builtin_functions.precision.refract.lowp_vertex.vec2
 dEQP-GLES3.functional.shaders.builtin_functions.precision.refract.lowp_vertex.vec3
diff --git a/android/cts/master/gles31-master.txt b/android/cts/master/gles31-master.txt
index 2f1dc0d..be69663 100644
--- a/android/cts/master/gles31-master.txt
+++ b/android/cts/master/gles31-master.txt
@@ -2635,10 +2635,15 @@
 dEQP-GLES31.functional.shaders.builtin_functions.precision.distance.highp_compute.vec4
 dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.scalar
 dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec2
+dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec3
+dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec4
 dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.scalar
 dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec2
+dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec3
+dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec4
 dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.scalar
 dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec2
+dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec3
 dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.lowp_compute
 dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.mediump_compute
 dEQP-GLES31.functional.shaders.builtin_functions.precision.cross.highp_compute
@@ -2668,8 +2673,13 @@
 dEQP-GLES31.functional.shaders.builtin_functions.precision.faceforward.highp_compute.vec4
 dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.scalar
 dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec2
+dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec3
+dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec4
 dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec2
+dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec3
+dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec4
 dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec2
+dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec3
 dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.scalar
 dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec2
 dEQP-GLES31.functional.shaders.builtin_functions.precision.refract.lowp_compute.vec3
diff --git a/android/cts/master/src/gles3-test-issues.txt b/android/cts/master/src/gles3-test-issues.txt
index 19940c1..39b560b 100644
--- a/android/cts/master/src/gles3-test-issues.txt
+++ b/android/cts/master/src/gles3-test-issues.txt
@@ -150,27 +150,5 @@
 # Bug 26651667
 dEQP-GLES3.functional.draw.draw_elements_instanced.indices.buffer.index_byte
 
-# Bug 28767510
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_vertex.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_vertex.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_fragment.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.lowp_fragment.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.mediump_vertex.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.mediump_vertex.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.mediump_fragment.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.highp_vertex.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.highp_fragment.vec3
-
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_vertex.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_vertex.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_fragment.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.lowp_fragment.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_vertex.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_vertex.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_fragment.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.mediump_fragment.vec4
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.highp_vertex.vec3
-dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.highp_fragment.vec3
-
 # b/73070970
 dEQP-GLES3.functional.shaders.declarations.unspecified_precision.*
diff --git a/android/cts/master/src/gles31-test-issues.txt b/android/cts/master/src/gles31-test-issues.txt
index 545ba85..f0181d4 100644
--- a/android/cts/master/src/gles31-test-issues.txt
+++ b/android/cts/master/src/gles31-test-issues.txt
@@ -36,16 +36,3 @@
 
 # Bug 28813504
 dEQP-GLES31.functional.ubo.random.all_per_block_buffers.41
-
-# Bug 28767510
-dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec3
-dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.lowp_compute.vec4
-dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec3
-dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.mediump_compute.vec4
-dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.highp_compute.vec3
-
-dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec3
-dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.lowp_compute.vec4
-dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec3
-dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.mediump_compute.vec4
-dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.highp_compute.vec3
diff --git a/android/cts/runner/Android.mk b/android/cts/runner/Android.mk
deleted file mode 100644
index cb61b2a..0000000
--- a/android/cts/runner/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2015 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.
-#
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java b/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
index 3721712..8874194 100644
--- a/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
+++ b/android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
@@ -38,7 +38,6 @@
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.testtype.IRuntimeHintProvider;
 import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.testtype.IStrictShardableTest;
 import com.android.tradefed.testtype.ITestCollector;
 import com.android.tradefed.testtype.ITestFilterReceiver;
 import com.android.tradefed.util.AbiUtils;
@@ -77,7 +76,7 @@
 @OptionClass(alias="deqp-test-runner")
 public class DeqpTestRunner implements IBuildReceiver, IDeviceTest,
         ITestFilterReceiver, IAbiReceiver, IShardableTest, ITestCollector,
-        IRuntimeHintProvider, IStrictShardableTest {
+        IRuntimeHintProvider {
     private static final String DEQP_ONDEVICE_APK = "com.drawelements.deqp.apk";
     private static final String DEQP_ONDEVICE_PKG = "com.drawelements.deqp";
     private static final String INCOMPLETE_LOG_MESSAGE = "Crash: Incomplete test log";
@@ -2101,6 +2100,22 @@
      * {@inheritDoc}
      */
     @Override
+    public Set<String> getIncludeFilters() {
+        return new HashSet<>(mIncludeFilters);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clearIncludeFilters() {
+        mIncludeFilters.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public void addExcludeFilter(String filter) {
         mExcludeFilters.add(filter);
     }
@@ -2117,6 +2132,22 @@
      * {@inheritDoc}
      */
     @Override
+    public Set<String> getExcludeFilters() {
+        return new HashSet<>(mExcludeFilters);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clearExcludeFilters() {
+        mExcludeFilters.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public void setCollectTestsOnly(boolean collectTests) {
         mCollectTestsOnly = collectTests;
     }
@@ -2193,51 +2224,6 @@
     }
 
     /**
-     * This sharding should be deterministic for the same input and independent.
-     * Through this API, each shard could be executed on different machine.
-     */
-    @Override
-    public IRemoteTest getTestShard(int shardCount, int shardIndex) {
-        // TODO: refactor getTestshard and split to share some logic.
-        if (mTestInstances == null) {
-            loadTests();
-        }
-
-        List<IRemoteTest> runners = new ArrayList<>();
-        // NOTE: Use linked hash map to keep the insertion order in iteration
-        Map<TestDescription, Set<BatchRunConfiguration>> currentSet = new LinkedHashMap<>();
-        Map<TestDescription, Set<BatchRunConfiguration>> iterationSet = this.mTestInstances;
-
-        int batchLimit = iterationSet.keySet().size() / shardCount;
-        int i = 1;
-        // Go through tests, split
-        for (TestDescription test: iterationSet.keySet()) {
-            currentSet.put(test, iterationSet.get(test));
-            if (currentSet.size() >= batchLimit && i < shardCount) {
-                runners.add(new DeqpTestRunner(this, currentSet));
-                i++;
-                // NOTE: Use linked hash map to keep the insertion order in iteration
-                currentSet = new LinkedHashMap<>();
-            }
-        }
-        runners.add(new DeqpTestRunner(this, currentSet));
-
-        // Compute new runtime hints
-        updateRuntimeHint(iterationSet.size(), runners);
-
-        // If too many shards were requested, we complete with placeholder.
-        if (runners.size() < shardCount) {
-            for (int j = runners.size(); j < shardCount; j++) {
-                runners.add(new DeqpTestRunner(this,
-                        new LinkedHashMap<TestDescription, Set<BatchRunConfiguration>>()));
-            }
-        }
-
-        CLog.i("Split deqp tests into %d shards, return shard: %s", runners.size(), shardIndex);
-        return runners.get(shardIndex);
-    }
-
-    /**
      * {@inheritDoc}
      */
     @Override
diff --git a/android/cts/runner/tests/Android.bp b/android/cts/runner/tests/Android.bp
new file mode 100644
index 0000000..987cea8
--- /dev/null
+++ b/android/cts/runner/tests/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2010 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.
+
+java_test_host {
+    name: "CtsDeqpRunnerTests",
+
+    // Only compile source java files in this lib.
+    srcs: ["src/**/*.java"],
+
+    libs: [
+        "cts-tradefed",
+        "compatibility-host-util",
+        "tradefed",
+        "CtsDeqpTestCases",
+    ],
+    static_libs: ["easymock"],
+}
diff --git a/android/cts/runner/tests/Android.mk b/android/cts/runner/tests/Android.mk
deleted file mode 100644
index 81ba834..0000000
--- a/android/cts/runner/tests/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2010 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := CtsDeqpRunnerTests
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := cts-tradefed compatibility-host-util tradefed CtsDeqpTestCases
-LOCAL_STATIC_JAVA_LIBRARIES := easymock
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java b/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java
index 5aaae41..c3eca58 100644
--- a/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java
+++ b/android/cts/runner/tests/src/com/drawelements/deqp/runner/DeqpTestRunnerTest.java
@@ -2147,100 +2147,6 @@
                  ((IRuntimeHintProvider)shards.get(1)).getRuntimeHint());
     }
 
-    /**
-     * Test that strict shardable is able to split deterministically the set of tests.
-     */
-    public void testGetTestShard() throws Exception {
-        final int TEST_COUNT = 2237;
-        final int SHARD_COUNT = 4;
-
-        ArrayList<TestDescription> testIds = new ArrayList<>(TEST_COUNT);
-        for (int i = 0; i < TEST_COUNT; i++) {
-            testIds.add(new TestDescription("dEQP-GLES3.funny.group", String.valueOf(i)));
-        }
-
-        DeqpTestRunner deqpTest = buildGlesTestRunner(3, 0, testIds, mTestsDir);
-        OptionSetter setter = new OptionSetter(deqpTest);
-        final long fullRuntimeMs = testIds.size()*100;
-        setter.setOptionValue("runtime-hint", String.valueOf(fullRuntimeMs));
-
-        DeqpTestRunner shard1 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 0);
-        assertEquals(559, shard1.getTestInstance().size());
-        int j = 0;
-        // Ensure numbers, and that order is stable
-        for (TestDescription t : shard1.getTestInstance().keySet()) {
-            assertEquals(String.format("dEQP-GLES3.funny.group#%s", j),
-                    String.format("%s#%s", t.getClassName(), t.getTestName()));
-            j++;
-        }
-        DeqpTestRunner shard2 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 1);
-        assertEquals(559, shard2.getTestInstance().size());
-        for (TestDescription t : shard2.getTestInstance().keySet()) {
-            assertEquals(String.format("dEQP-GLES3.funny.group#%s", j),
-                    String.format("%s#%s", t.getClassName(), t.getTestName()));
-            j++;
-        }
-        DeqpTestRunner shard3 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 2);
-        assertEquals(559, shard3.getTestInstance().size());
-        for (TestDescription t : shard3.getTestInstance().keySet()) {
-            assertEquals(String.format("dEQP-GLES3.funny.group#%s", j),
-                    String.format("%s#%s", t.getClassName(), t.getTestName()));
-            j++;
-        }
-        DeqpTestRunner shard4 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 3);
-        assertEquals(560, shard4.getTestInstance().size());
-        for (TestDescription t : shard4.getTestInstance().keySet()) {
-            assertEquals(String.format("dEQP-GLES3.funny.group#%s", j),
-                    String.format("%s#%s", t.getClassName(), t.getTestName()));
-            j++;
-        }
-        assertEquals(TEST_COUNT, j);
-    }
-
-    /**
-     * Test that strict shardable is creating an empty shard of the runner when too many shards
-     * are requested.
-     */
-    public void testGetTestShard_tooManyShardRequested() throws Exception {
-        final int TEST_COUNT = 2;
-        final int SHARD_COUNT = 3;
-
-        ArrayList<TestDescription> testIds = new ArrayList<>(TEST_COUNT);
-        for (int i = 0; i < TEST_COUNT; i++) {
-            testIds.add(new TestDescription("dEQP-GLES3.funny.group", String.valueOf(i)));
-        }
-        DeqpTestRunner deqpTest = buildGlesTestRunner(3, 0, testIds, mTestsDir);
-        OptionSetter setter = new OptionSetter(deqpTest);
-        final long fullRuntimeMs = testIds.size()*100;
-        setter.setOptionValue("runtime-hint", String.valueOf(fullRuntimeMs));
-        DeqpTestRunner shard1 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 0);
-        assertEquals(1, shard1.getTestInstance().size());
-        int j = 0;
-        // Ensure numbers, and that order is stable
-        for (TestDescription t : shard1.getTestInstance().keySet()) {
-            assertEquals(String.format("dEQP-GLES3.funny.group#%s", j),
-                    String.format("%s#%s", t.getClassName(), t.getTestName()));
-            j++;
-        }
-        DeqpTestRunner shard2 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 1);
-        assertEquals(1, shard2.getTestInstance().size());
-        for (TestDescription t : shard2.getTestInstance().keySet()) {
-            assertEquals(String.format("dEQP-GLES3.funny.group#%s", j),
-                    String.format("%s#%s", t.getClassName(), t.getTestName()));
-            j++;
-        }
-        DeqpTestRunner shard3 = (DeqpTestRunner)deqpTest.getTestShard(SHARD_COUNT, 2);
-        assertTrue(shard3.getTestInstance().isEmpty());
-        assertEquals(TEST_COUNT, j);
-        ITestInvocationListener mockListener
-                = EasyMock.createStrictMock(ITestInvocationListener.class);
-        mockListener.testRunStarted(EasyMock.anyObject(), EasyMock.eq(0));
-        mockListener.testRunEnded(EasyMock.anyLong(), (Map<String, String>) EasyMock.anyObject());
-        EasyMock.replay(mockListener);
-        shard3.run(mockListener);
-        EasyMock.verify(mockListener);
-    }
-
     public void testRuntimeHint_optionNotSet() throws Exception {
         final TestDescription[] testIds = {
                 new TestDescription("dEQP-GLES3.info", "vendor"),
diff --git a/android/package/AndroidManifest.xml b/android/package/AndroidManifest.xml
index 322ad47..5d52274 100644
--- a/android/package/AndroidManifest.xml
+++ b/android/package/AndroidManifest.xml
@@ -34,8 +34,7 @@
 		</activity>
 	</application>
 
-	<uses-sdk android:minSdkVersion="13"/>
-	<uses-sdk android:targetSdkVersion="19"/>
+	<uses-sdk android:minSdkVersion="13" android:targetSdkVersion="19"/>
 	<uses-feature android:glEsVersion="0x00020000"/>
 	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 	<uses-permission android:name="android.permission.GET_TASKS" />
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt
index b593acc..0803920 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles2-master.txt
@@ -7800,8 +7800,20 @@
 dEQP-GLES2.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment
 dEQP-GLES2.functional.shaders.struct.local.parameter_vertex
 dEQP-GLES2.functional.shaders.struct.local.parameter_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_lowp_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_mediump_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_inout_highp_fragment
 dEQP-GLES2.functional.shaders.struct.local.parameter_nested_vertex
 dEQP-GLES2.functional.shaders.struct.local.parameter_nested_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_lowp_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_mediump_fragment
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_vertex
+dEQP-GLES2.functional.shaders.struct.local.parameter_out_highp_fragment
 dEQP-GLES2.functional.shaders.struct.local.return_vertex
 dEQP-GLES2.functional.shaders.struct.local.return_fragment
 dEQP-GLES2.functional.shaders.struct.local.return_nested_vertex
diff --git a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt
index e37db5d..c300c8c 100644
--- a/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt
+++ b/external/openglcts/data/mustpass/gles/aosp_mustpass/master/gles3-master.txt
@@ -16431,8 +16431,20 @@
 dEQP-GLES3.functional.shaders.struct.local.nested_struct_array_dynamic_index_fragment
 dEQP-GLES3.functional.shaders.struct.local.parameter_vertex
 dEQP-GLES3.functional.shaders.struct.local.parameter_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_lowp_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_mediump_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_inout_highp_fragment
 dEQP-GLES3.functional.shaders.struct.local.parameter_nested_vertex
 dEQP-GLES3.functional.shaders.struct.local.parameter_nested_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_lowp_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_mediump_fragment
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_vertex
+dEQP-GLES3.functional.shaders.struct.local.parameter_out_highp_fragment
 dEQP-GLES3.functional.shaders.struct.local.return_vertex
 dEQP-GLES3.functional.shaders.struct.local.return_fragment
 dEQP-GLES3.functional.shaders.struct.local.return_nested_vertex
diff --git a/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp b/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
index f1fb2d5..d175c0c 100644
--- a/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
+++ b/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
@@ -98,7 +98,10 @@
 	{
 		return m_driver;
 	}
-
+	const tcu::FunctionLibrary&		getFunctionLibrary		(void) const
+	{
+		return m_library;
+	}
 private:
 	const tcu::DynamicFunctionLibrary	m_library;
 	const vk::PlatformDriver			m_driver;
diff --git a/modules/gles2/functional/es2fShaderStructTests.cpp b/modules/gles2/functional/es2fShaderStructTests.cpp
index 21d84c5..b7354d8 100644
--- a/modules/gles2/functional/es2fShaderStructTests.cpp
+++ b/modules/gles2/functional/es2fShaderStructTests.cpp
@@ -56,6 +56,7 @@
 	FLAG_USES_TEXTURES				= (1<<0),
 	FLAG_REQUIRES_DYNAMIC_LOOPS		= (1<<1),
 	FLAG_REQUIRES_DYNAMIC_INDEXING	= (1<<2),
+	FLAG_REQUIRES_HIGHP_FRAGMENT	= (1<<3),
 };
 
 typedef void (*SetupUniformsFunc) (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords);
@@ -122,6 +123,10 @@
 		if (m_flags & FLAG_REQUIRES_DYNAMIC_INDEXING)
 			throw tcu::NotSupportedError("Dynamic indexing not supported");
 
+		if (!m_isVertexCase && (m_flags & FLAG_REQUIRES_HIGHP_FRAGMENT) &&
+			!m_ctxInfo.isFragmentHighPrecisionSupported())
+			throw tcu::NotSupportedError("Highp in fragment shaders not supported");
+
 		throw;
 	}
 
@@ -148,7 +153,7 @@
 		m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
 }
 
-static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc)
+static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map<std::string, std::string>* additionalParams)
 {
 	static const char* defaultVertSrc =
 		"attribute highp vec4 a_position;\n"
@@ -185,6 +190,8 @@
 		spParams["DST"]				= "gl_FragColor";
 		spParams["ASSIGN_POS"]		= "";
 	}
+	if (additionalParams)
+		spParams.insert(additionalParams->begin(), additionalParams->end());
 
 	if (isVertexCase)
 		return new ShaderStructCase(context, name, description, isVertexCase, flags, evalFunc, setupUniforms, StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc);
@@ -209,13 +216,16 @@
 
 void LocalStructTests::init (void)
 {
-	#define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY)																\
+	#define LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY, PARAMS)										\
 		do {																																	\
 			struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY };  /* NOLINT(EVAL_FUNC_BODY) */						\
-			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, &Eval_##NAME::eval, DE_NULL, SHADER_SRC));			\
-			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS,&Eval_##NAME::eval, DE_NULL, SHADER_SRC));		\
+			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));	\
+			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS,&Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\
 		} while (deGetFalse())
 
+	#define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY)	\
+		LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
+
 	LOCAL_STRUCT_CASE(basic, "Basic struct usage", 0,
 		LineStream()
 		<< "${DECLARATIONS}"
@@ -526,6 +536,61 @@
 			c.color.xyz() = c.coords.swizzle(0,1,2);
 		});
 
+	LineStream inoutSrc;
+	inoutSrc
+			<< "${DECLARATIONS}"
+			<< ""
+			<< "struct S {"
+			<< "	${PRECISION} vec3 red;"
+			<< "	${PRECISION} vec3 blue;"
+			<< "};"
+			<< ""
+			<< "void modify (inout S s)"
+			<< "{"
+			<< "	s.red += vec3(0.5, 0.0, 0.0);"
+			<< "	s.blue += vec3(0.0, 0.0, 0.5);"
+			<< "}"
+			<< ""
+			<< "void main (void)"
+			<< "{"
+			<< "	S s;"
+			<< "	s.red = vec3(0.5, 0.0, 0.0);"
+			<< "	s.blue = vec3(0.0, 0.0, 0.5);"
+			<< "	modify(s);"
+			<< "	${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
+			<< "	if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))"
+			<< "		${DST} = vec4(1.0, 1.0, 1.0, 1.0);"
+			<< "	${ASSIGN_POS}"
+			<< "}";
+
+	std::map<std::string, std::string> precisionParams;
+	precisionParams["PRECISION"] = "lowp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_inout_lowp, "Struct with lowp members as an inout function parameter", 0,
+		inoutSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "mediump";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_inout_mediump, "Struct with mediump members as an inout function parameter", 0,
+		inoutSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "highp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_inout_highp, "Struct with highp members as an inout function parameter", FLAG_REQUIRES_HIGHP_FRAGMENT,
+		inoutSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
 	LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter", 0,
 		LineStream()
 		<< "${DECLARATIONS}"
@@ -558,6 +623,58 @@
 			c.color.xyz() = c.coords.swizzle(0,1,2);
 		});
 
+	LineStream outSrc;
+	outSrc
+			<< "${DECLARATIONS}"
+			<< ""
+			<< "struct S {"
+			<< "	${PRECISION} vec3 red;"
+			<< "	${PRECISION} vec3 blue;"
+			<< "};"
+			<< ""
+			<< "void modify (out S s)"
+			<< "{"
+			<< "	s.red = vec3(1.0, 0.0, 0.0);"
+			<< "	s.blue = vec3(0.0, 0.0, 1.0);"
+			<< "}"
+			<< ""
+			<< "void main (void)"
+			<< "{"
+			<< "	S s;"
+			<< "	modify(s);"
+			<< "	${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
+			<< "	if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))"
+			<< "		${DST} = vec4(1.0, 1.0, 1.0, 1.0);"
+			<< "	${ASSIGN_POS}"
+			<< "}",
+
+
+	precisionParams["PRECISION"] = "lowp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_out_lowp, "Struct with lowp members as an out function parameter", 0,
+		outSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "mediump";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(parameter_out_mediump, "Struct with mediump members as an out function parameter", 0,
+		outSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "highp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_out_highp, "Struct with highp members as an out function parameter", FLAG_REQUIRES_HIGHP_FRAGMENT,
+		outSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
 	LOCAL_STRUCT_CASE(return, "Struct as a return value", 0,
 		LineStream()
 		<< "${DECLARATIONS}"
@@ -1221,8 +1338,8 @@
 				 static void setUniforms (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY /* NOLINT(SET_UNIFORMS_BODY) */ \
 			};																																							\
 			struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY };	/* NOLINT(EVAL_FUNC_BODY) */												\
-			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC));			\
-			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC));		\
+			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));	\
+			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\
 		} while (deGetFalse())
 
 	UNIFORM_STRUCT_CASE(basic, "Basic struct usage", 0,
diff --git a/modules/gles2/functional/es2fTextureSizeTests.cpp b/modules/gles2/functional/es2fTextureSizeTests.cpp
index 9e202ca..6b7516b 100644
--- a/modules/gles2/functional/es2fTextureSizeTests.cpp
+++ b/modules/gles2/functional/es2fTextureSizeTests.cpp
@@ -124,7 +124,7 @@
 	tcu::Surface			referenceFrame	(viewport.width, viewport.height);
 	const tcu::IVec4		texBits			= tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
 	const tcu::PixelFormat&	rtFmt			= m_renderCtx.getRenderTarget().getPixelFormat();
-	const tcu::PixelFormat	thresholdFormat(std::min(texBits[0], rtFmt.redBits), std::min(texBits[1], rtFmt.greenBits), std::min(texBits[2], rtFmt.blueBits), std::min(texBits[3], rtFmt.alphaBits));
+	const tcu::PixelFormat	thresholdFormat(de::min(texBits[0], rtFmt.redBits), de::min(texBits[1], rtFmt.greenBits), de::min(texBits[2], rtFmt.blueBits), de::min(texBits[3], rtFmt.alphaBits));
 	tcu::RGBA				threshold		= thresholdFormat.getColorThreshold() + tcu::RGBA(7,7,7,7);
 	deUint32				wrapS			= GL_CLAMP_TO_EDGE;
 	deUint32				wrapT			= GL_CLAMP_TO_EDGE;
@@ -272,7 +272,7 @@
 	tcu::Surface			referenceFrame	(viewport.width, viewport.height);
 	const tcu::IVec4		texBits			= tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
 	const tcu::PixelFormat&	rtFmt			= m_renderCtx.getRenderTarget().getPixelFormat();
-	const tcu::PixelFormat	thresholdFormat(std::min(texBits[0], rtFmt.redBits), std::min(texBits[1], rtFmt.greenBits), std::min(texBits[2], rtFmt.blueBits), std::min(texBits[3], rtFmt.alphaBits));
+	const tcu::PixelFormat	thresholdFormat(de::min(texBits[0], rtFmt.redBits), de::min(texBits[1], rtFmt.greenBits), de::min(texBits[2], rtFmt.blueBits), de::min(texBits[3], rtFmt.alphaBits));
 	tcu::RGBA				threshold		= thresholdFormat.getColorThreshold() + tcu::RGBA(7,7,7,7);
 	deUint32				wrapS			= GL_CLAMP_TO_EDGE;
 	deUint32				wrapT			= GL_CLAMP_TO_EDGE;
diff --git a/modules/gles3/functional/es3fShaderDerivateTests.cpp b/modules/gles3/functional/es3fShaderDerivateTests.cpp
index 70e61b4..15013bf 100644
--- a/modules/gles3/functional/es3fShaderDerivateTests.cpp
+++ b/modules/gles3/functional/es3fShaderDerivateTests.cpp
@@ -214,7 +214,7 @@
 {
 	const int		numGarbageBits	= 23-numAccurateBits;
 	const deUint32	mask			= (1u<<numGarbageBits)-1u;
-	const int		exp				= tcu::Float32(value).exponent();
+	const int		exp				= (tcu::Float32(value).exponent() < -3) ? -3 : tcu::Float32(value).exponent();
 
 	return tcu::Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - tcu::Float32::construct(+1, exp, 1u<<23).asFloat();
 }
@@ -323,6 +323,20 @@
 	INTERPOLATION_LOST_BITS = 3, // number mantissa of bits allowed to be lost in varying interpolation
 };
 
+static int getInterpolationLostBitsWarning (const glu::Precision precision)
+{
+	// number mantissa of bits allowed to be lost in varying interpolation
+	switch (precision)
+	{
+		case glu::PRECISION_HIGHP:		return 9;
+		case glu::PRECISION_MEDIUMP:	return 3;
+		case glu::PRECISION_LOWP:		return 3;
+		default:
+			DE_ASSERT(false);
+			return 0;
+	}
+}
+
 static inline tcu::Vec4 getDerivateThreshold (const glu::Precision precision, const tcu::Vec4& valueMin, const tcu::Vec4& valueMax, const tcu::Vec4& expectedDerivate)
 {
 	const int			baseBits		= getNumMantissaBits(precision);
@@ -337,6 +351,21 @@
 					 computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
 }
 
+static inline tcu::Vec4 getDerivateThresholdWarning (const glu::Precision precision, const tcu::Vec4& valueMin, const tcu::Vec4& valueMax, const tcu::Vec4& expectedDerivate)
+{
+	const int			baseBits		= getNumMantissaBits(precision);
+	const tcu::UVec4	derivExp		= getCompExpBits(expectedDerivate);
+	const tcu::UVec4	maxValueExp		= max(getCompExpBits(valueMin), getCompExpBits(valueMax));
+	const tcu::UVec4	numBitsLost		= maxValueExp - min(maxValueExp, derivExp);
+	const tcu::IVec4	numAccurateBits	= max(baseBits - numBitsLost.asInt() - getInterpolationLostBitsWarning(precision), tcu::IVec4(0));
+
+	return tcu::Vec4(computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
+					 computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
+					 computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
+					 computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
+}
+
+
 namespace
 {
 
@@ -369,7 +398,7 @@
 	LOG_NOTHING
 };
 
-static bool verifyConstantDerivate (tcu::TestLog&						log,
+static qpTestResult verifyConstantDerivate (tcu::TestLog&				log,
 									const tcu::ConstPixelBufferAccess&	result,
 									const tcu::PixelBufferAccess&		errorMask,
 									glu::DataType						dataType,
@@ -412,7 +441,7 @@
 	if (numFailedPixels > 0 && logPolicy == LOG_ALL)
 		log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;
 
-	return numFailedPixels == 0;
+	return (numFailedPixels == 0) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
 }
 
 struct Linear2DFunctionEvaluator
@@ -433,7 +462,7 @@
 	return matrix * position;
 }
 
-static bool reverifyConstantDerivateWithFlushRelaxations (tcu::TestLog&							log,
+static qpTestResult reverifyConstantDerivateWithFlushRelaxations (tcu::TestLog&							log,
 														  const tcu::ConstPixelBufferAccess&	result,
 														  const tcu::PixelBufferAccess&			errorMask,
 														  glu::DataType							dataType,
@@ -551,7 +580,7 @@
 	if (numFailedPixels > 0)
 		log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;
 
-	return numFailedPixels == 0;
+	return (numFailedPixels == 0) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
 }
 
 // TriangleDerivateCase
@@ -559,34 +588,34 @@
 class TriangleDerivateCase : public TestCase
 {
 public:
-						TriangleDerivateCase	(Context& context, const char* name, const char* description);
-						~TriangleDerivateCase	(void);
+							TriangleDerivateCase	(Context& context, const char* name, const char* description);
+							~TriangleDerivateCase	(void);
 
-	IterateResult		iterate					(void);
+	IterateResult			iterate					(void);
 
 protected:
-	virtual void		setupRenderState		(deUint32 program) { DE_UNREF(program); }
-	virtual bool		verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask) = DE_NULL;
+	virtual void			setupRenderState		(deUint32 program) { DE_UNREF(program); }
+	virtual qpTestResult	verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask) = DE_NULL;
 
-	tcu::IVec2			getViewportSize			(void) const;
-	tcu::Vec4			getSurfaceThreshold		(void) const;
+	tcu::IVec2				getViewportSize			(void) const;
+	tcu::Vec4				getSurfaceThreshold		(void) const;
 
-	glu::DataType		m_dataType;
-	glu::Precision		m_precision;
+	glu::DataType			m_dataType;
+	glu::Precision			m_precision;
 
-	glu::DataType		m_coordDataType;
-	glu::Precision		m_coordPrecision;
+	glu::DataType			m_coordDataType;
+	glu::Precision			m_coordPrecision;
 
-	std::string			m_fragmentSrc;
+	std::string				m_fragmentSrc;
 
-	tcu::Vec4			m_coordMin;
-	tcu::Vec4			m_coordMax;
-	tcu::Vec4			m_derivScale;
-	tcu::Vec4			m_derivBias;
+	tcu::Vec4				m_coordMin;
+	tcu::Vec4				m_coordMax;
+	tcu::Vec4				m_derivScale;
+	tcu::Vec4				m_derivBias;
 
-	SurfaceType			m_surfaceType;
-	int					m_numSamples;
-	deUint32			m_hint;
+	SurfaceType				m_surfaceType;
+	int						m_numSamples;
+	deUint32				m_hint;
 };
 
 TriangleDerivateCase::TriangleDerivateCase (Context& context, const char* name, const char* description)
@@ -825,18 +854,24 @@
 		tcu::Surface errorMask(result.getWidth(), result.getHeight());
 		tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
 
-		const bool isOk = verify(result.getAccess(), errorMask.getAccess());
+		const qpTestResult testResult = verify(result.getAccess(), errorMask.getAccess());
+		const char* failStr = "Fail";
 
 		m_testCtx.getLog() << TestLog::ImageSet("Result", "Result images")
 						   << TestLog::Image("Rendered", "Rendered image", result);
 
-		if (!isOk)
+		if (testResult != QP_TEST_RESULT_PASS)
 			m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
 
 		m_testCtx.getLog() << TestLog::EndImageSet;
 
-		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
-								isOk ? "Pass"				: "Image comparison failed");
+		if (testResult == QP_TEST_RESULT_PASS)
+			failStr = "Pass";
+		else if (testResult == QP_TEST_RESULT_QUALITY_WARNING)
+			failStr = "QualityWarning";
+
+		m_testCtx.setTestResult(testResult, failStr);
+
 	}
 
 	return STOP;
@@ -875,7 +910,7 @@
 	void				init						(void);
 
 protected:
-	bool				verify						(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
+	qpTestResult		verify						(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
 
 private:
 	DerivateFunc		m_func;
@@ -922,7 +957,7 @@
 	m_derivBias		= tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
 }
 
-bool ConstantDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
+qpTestResult ConstantDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
 {
 	const tcu::Vec4 reference	(0.0f); // Derivate of constant argument should always be 0
 	const tcu::Vec4	threshold	= getSurfaceThreshold() / abs(m_derivScale);
@@ -942,7 +977,7 @@
 	void				init					(void);
 
 protected:
-	bool				verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
+	qpTestResult		verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
 
 private:
 	DerivateFunc		m_func;
@@ -1049,7 +1084,7 @@
 	}
 }
 
-bool LinearDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
+qpTestResult LinearDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
 {
 	const tcu::Vec4		xScale				= tcu::Vec4(1.0f, 0.0f, 0.5f, -0.5f);
 	const tcu::Vec4		yScale				= tcu::Vec4(0.0f, 1.0f, 0.5f, -0.5f);
@@ -1057,13 +1092,15 @@
 
 	if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
 	{
-		const bool			isX			= m_func == DERIVATE_DFDX;
-		const float			div			= isX ? float(result.getWidth()) : float(result.getHeight());
-		const tcu::Vec4		scale		= isX ? xScale : yScale;
-		const tcu::Vec4		reference	= ((m_coordMax - m_coordMin) / div) * scale;
-		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_precision, m_coordMin*scale, m_coordMax*scale, reference);
-		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
-		const int			numComps	= glu::getDataTypeFloatScalars(m_dataType);
+		const bool			isX				= m_func == DERIVATE_DFDX;
+		const float			div				= isX ? float(result.getWidth()) : float(result.getHeight());
+		const tcu::Vec4		scale			= isX ? xScale : yScale;
+		const tcu::Vec4		reference		= ((m_coordMax - m_coordMin) / div) * scale;
+		const tcu::Vec4		opThreshold		= getDerivateThreshold(m_precision, m_coordMin*scale, m_coordMax*scale, reference);
+		const tcu::Vec4		opThresholdW	= getDerivateThresholdWarning(m_precision, m_coordMin*scale, m_coordMax*scale, reference);
+		const tcu::Vec4		threshold		= max(surfaceThreshold, opThreshold);
+		const tcu::Vec4		thresholdW		= max(surfaceThreshold, opThresholdW);
+		const int			numComps		= glu::getDataTypeFloatScalars(m_dataType);
 
 		m_testCtx.getLog()
 			<< tcu::TestLog::Message
@@ -1075,14 +1112,27 @@
 		// This improves performance significantly.
 		if (verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
 								   reference, threshold, m_derivScale, m_derivBias,
-								   LOG_NOTHING))
+								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
 		{
 			m_testCtx.getLog()
 				<< tcu::TestLog::Message
 				<< "No incorrect derivatives found, result valid."
 				<< tcu::TestLog::EndMessage;
 
-			return true;
+			return QP_TEST_RESULT_PASS;
+		}
+
+		// Check with relaxed threshold value
+		if (verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
+								   reference, thresholdW, m_derivScale, m_derivBias,
+								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
+		{
+			m_testCtx.getLog()
+				<< tcu::TestLog::Message
+				<< "No incorrect derivatives found, result valid with quality warning."
+				<< tcu::TestLog::EndMessage;
+
+			return QP_TEST_RESULT_QUALITY_WARNING;
 		}
 
 		// some pixels exceed error bounds calculated for normal values. Verify that these
@@ -1115,18 +1165,36 @@
 	else
 	{
 		DE_ASSERT(m_func == DERIVATE_FWIDTH);
-		const float			w			= float(result.getWidth());
-		const float			h			= float(result.getHeight());
+		const float			w				= float(result.getWidth());
+		const float			h				= float(result.getHeight());
 
-		const tcu::Vec4		dx			= ((m_coordMax - m_coordMin) / w) * xScale;
-		const tcu::Vec4		dy			= ((m_coordMax - m_coordMin) / h) * yScale;
-		const tcu::Vec4		reference	= tcu::abs(dx) + tcu::abs(dy);
-		const tcu::Vec4		dxThreshold	= getDerivateThreshold(m_precision, m_coordMin*xScale, m_coordMax*xScale, dx);
-		const tcu::Vec4		dyThreshold	= getDerivateThreshold(m_precision, m_coordMin*yScale, m_coordMax*yScale, dy);
-		const tcu::Vec4		threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));
+		const tcu::Vec4		dx				= ((m_coordMax - m_coordMin) / w) * xScale;
+		const tcu::Vec4		dy				= ((m_coordMax - m_coordMin) / h) * yScale;
+		const tcu::Vec4		reference		= tcu::abs(dx) + tcu::abs(dy);
+		const tcu::Vec4		dxThreshold		= getDerivateThreshold(m_precision, m_coordMin*xScale, m_coordMax*xScale, dx);
+		const tcu::Vec4		dyThreshold		= getDerivateThreshold(m_precision, m_coordMin*yScale, m_coordMax*yScale, dy);
+		const tcu::Vec4		dxThresholdW	= getDerivateThresholdWarning(m_precision, m_coordMin*xScale, m_coordMax*xScale, dx);
+		const tcu::Vec4		dyThresholdW	= getDerivateThresholdWarning(m_precision, m_coordMin*yScale, m_coordMax*yScale, dy);
+		const tcu::Vec4		threshold		= max(surfaceThreshold, max(dxThreshold, dyThreshold));
+		const tcu::Vec4		thresholdW		= max(surfaceThreshold, max(dxThresholdW, dyThresholdW));
+		qpTestResult        testResult		= QP_TEST_RESULT_FAIL;
 
-		return verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
+		testResult = verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
 									  reference, threshold, m_derivScale, m_derivBias);
+
+		// return if result is pass
+		if (testResult == QP_TEST_RESULT_PASS)
+			return testResult;
+
+		// re-check with relaxed threshold
+		testResult = verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
+									  reference, thresholdW, m_derivScale, m_derivBias);
+
+		// if with relaxed threshold test is passing then mark the result with quality warning.
+		if (testResult == QP_TEST_RESULT_PASS)
+			testResult = QP_TEST_RESULT_QUALITY_WARNING;
+
+		return testResult;
 	}
 }
 
@@ -1143,7 +1211,7 @@
 
 protected:
 	void				setupRenderState		(deUint32 program);
-	bool				verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
+	qpTestResult		verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
 
 private:
 	DerivateFunc		m_func;
@@ -1335,7 +1403,7 @@
 	gl.uniform1i		(gl.getUniformLocation(program, "u_sampler"), texUnit);
 }
 
-bool TextureDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
+qpTestResult TextureDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
 {
 	// \note Edges are ignored in comparison
 	if (result.getWidth() < 2 || result.getHeight() < 2)
@@ -1352,13 +1420,15 @@
 
 	if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
 	{
-		const bool			isX			= m_func == DERIVATE_DFDX;
-		const float			div			= isX ? w : h;
-		const tcu::Vec4		scale		= isX ? xScale : yScale;
-		const tcu::Vec4		reference	= ((m_texValueMax - m_texValueMin) / div) * scale;
-		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_precision, m_texValueMin*scale, m_texValueMax*scale, reference);
-		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
-		const int			numComps	= glu::getDataTypeFloatScalars(m_dataType);
+		const bool			isX				= m_func == DERIVATE_DFDX;
+		const float			div				= isX ? w : h;
+		const tcu::Vec4		scale			= isX ? xScale : yScale;
+		const tcu::Vec4		reference		= ((m_texValueMax - m_texValueMin) / div) * scale;
+		const tcu::Vec4		opThreshold		= getDerivateThreshold(m_precision, m_texValueMin*scale, m_texValueMax*scale, reference);
+		const tcu::Vec4		opThresholdW	= getDerivateThresholdWarning(m_precision, m_texValueMin*scale, m_texValueMax*scale, reference);
+		const tcu::Vec4		threshold		= max(surfaceThreshold, opThreshold);
+		const tcu::Vec4		thresholdW		= max(surfaceThreshold, opThresholdW);
+		const int			numComps		= glu::getDataTypeFloatScalars(m_dataType);
 
 		m_testCtx.getLog()
 			<< tcu::TestLog::Message
@@ -1370,16 +1440,36 @@
 		// This improves performance significantly.
 		if (verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
 								   reference, threshold, m_derivScale, m_derivBias,
-								   LOG_NOTHING))
+								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
 		{
 			m_testCtx.getLog()
 				<< tcu::TestLog::Message
 				<< "No incorrect derivatives found, result valid."
 				<< tcu::TestLog::EndMessage;
 
-			return true;
+			return QP_TEST_RESULT_PASS;
 		}
 
+		m_testCtx.getLog()
+			<< tcu::TestLog::Message
+			<< "Verifying result image.\n"
+			<< "\tValid derivative is " << LogVecComps(reference, numComps) << " with Warning threshold " << LogVecComps(thresholdW, numComps)
+			<< tcu::TestLog::EndMessage;
+
+		// Re-check with relaxed threshold
+		if (verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
+								   reference, thresholdW, m_derivScale, m_derivBias,
+								   LOG_NOTHING) == QP_TEST_RESULT_PASS)
+		{
+			m_testCtx.getLog()
+				<< tcu::TestLog::Message
+				<< "No incorrect derivatives found, result valid with quality warning."
+				<< tcu::TestLog::EndMessage;
+
+			return QP_TEST_RESULT_QUALITY_WARNING;
+		}
+
+
 		// some pixels exceed error bounds calculated for normal values. Verify that these
 		// potentially invalid pixels are in fact valid due to (for example) subnorm flushing.
 
@@ -1407,15 +1497,32 @@
 	else
 	{
 		DE_ASSERT(m_func == DERIVATE_FWIDTH);
-		const tcu::Vec4	dx			= ((m_texValueMax - m_texValueMin) / w) * xScale;
-		const tcu::Vec4	dy			= ((m_texValueMax - m_texValueMin) / h) * yScale;
-		const tcu::Vec4	reference	= tcu::abs(dx) + tcu::abs(dy);
-		const tcu::Vec4	dxThreshold	= getDerivateThreshold(m_precision, m_texValueMin*xScale, m_texValueMax*xScale, dx);
-		const tcu::Vec4	dyThreshold	= getDerivateThreshold(m_precision, m_texValueMin*yScale, m_texValueMax*yScale, dy);
-		const tcu::Vec4	threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));
+		const tcu::Vec4	dx				= ((m_texValueMax - m_texValueMin) / w) * xScale;
+		const tcu::Vec4	dy				= ((m_texValueMax - m_texValueMin) / h) * yScale;
+		const tcu::Vec4	reference		= tcu::abs(dx) + tcu::abs(dy);
+		const tcu::Vec4	dxThreshold		= getDerivateThreshold(m_precision, m_texValueMin*xScale, m_texValueMax*xScale, dx);
+		const tcu::Vec4	dyThreshold		= getDerivateThreshold(m_precision, m_texValueMin*yScale, m_texValueMax*yScale, dy);
+		const tcu::Vec4	dxThresholdW	= getDerivateThresholdWarning(m_precision, m_texValueMin*xScale, m_texValueMax*xScale, dx);
+		const tcu::Vec4	dyThresholdW	= getDerivateThresholdWarning(m_precision, m_texValueMin*yScale, m_texValueMax*yScale, dy);
+		const tcu::Vec4	threshold		= max(surfaceThreshold, max(dxThreshold, dyThreshold));
+		const tcu::Vec4	thresholdW		= max(surfaceThreshold, max(dxThresholdW, dyThresholdW));
+		qpTestResult	testResult		= QP_TEST_RESULT_FAIL;
 
-		return verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
+		testResult = verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
 									  reference, threshold, m_derivScale, m_derivBias);
+
+		if (testResult == QP_TEST_RESULT_PASS)
+			return testResult;
+
+		// Re-Check with relaxed threshold
+		testResult = verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
+									  reference, thresholdW, m_derivScale, m_derivBias);
+
+		// If test is passing with relaxed threshold then mark quality warning
+		if (testResult == QP_TEST_RESULT_PASS)
+			testResult = QP_TEST_RESULT_QUALITY_WARNING;
+
+		return testResult;
 	}
 }
 
diff --git a/modules/gles3/functional/es3fShaderStructTests.cpp b/modules/gles3/functional/es3fShaderStructTests.cpp
index 66b9559..526db73 100644
--- a/modules/gles3/functional/es3fShaderStructTests.cpp
+++ b/modules/gles3/functional/es3fShaderStructTests.cpp
@@ -115,7 +115,7 @@
 		m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
 }
 
-static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc)
+static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map<std::string, std::string>* additionalParams)
 {
 	static const char* defaultVertSrc =
 		"#version 300 es\n"
@@ -159,6 +159,8 @@
 		spParams["DST"]				= "o_color";
 		spParams["ASSIGN_POS"]		= "";
 	}
+	if (additionalParams)
+		spParams.insert(additionalParams->begin(), additionalParams->end());
 
 	if (isVertexCase)
 		return new ShaderStructCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc);
@@ -183,13 +185,16 @@
 
 void LocalStructTests::init (void)
 {
-	#define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY)																	\
+	#define LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS)												\
 		do {																																	\
 			struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY };	/* NOLINT(EVAL_FUNC_BODY) */						\
-			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC));			\
-			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, false,&Eval_##NAME::eval, DE_NULL, SHADER_SRC));		\
+			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));	\
+			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, false,&Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\
 		} while (deGetFalse())
 
+	#define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \
+		LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
+
 	LOCAL_STRUCT_CASE(basic, "Basic struct usage",
 		LineStream()
 		<< "${HEADER}"
@@ -500,6 +505,63 @@
 			c.color.xyz() = c.coords.swizzle(0,1,2);
 		});
 
+	LineStream inoutSrc;
+	inoutSrc
+			<< "${HEADER}"
+			<< ""
+			<< "struct S {"
+			<< "	${PRECISION} vec3 red;"
+			<< "	${PRECISION} vec3 blue;"
+			<< "};"
+			<< ""
+			<< "void modify (inout S s)"
+			<< "{"
+			<< "	s.red += vec3(0.5, 0.0, 0.0);"
+			<< "	s.blue += vec3(0.0, 0.0, 0.5);"
+			<< "}"
+			<< ""
+			<< "void main (void)"
+			<< "{"
+			<< "	S s;"
+			<< "	s.red = vec3(0.5, 0.0, 0.0);"
+			<< "	s.blue = vec3(0.0, 0.0, 0.5);"
+			<< "	modify(s);"
+			<< "	${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
+			<< "	if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))"
+			<< "		${DST} = vec4(1.0, 1.0, 1.0, 1.0);"
+			<< "	${ASSIGN_POS}"
+			<< "}";
+
+
+	std::map<std::string, std::string> precisionParams;
+
+	precisionParams["PRECISION"] = "lowp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_inout_lowp, "Struct with lowp members as an inout function parameter",
+		inoutSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "mediump";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_inout_mediump, "Struct with mediump members as an inout function parameter",
+		inoutSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "highp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_inout_highp, "Struct with highp members as an inout function parameter",
+		inoutSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
 	LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter",
 		LineStream()
 		<< "${HEADER}"
@@ -532,6 +594,58 @@
 			c.color.xyz() = c.coords.swizzle(0,1,2);
 		});
 
+	LineStream outSrc;
+	outSrc
+			<< "${HEADER}"
+			<< ""
+			<< "struct S {"
+			<< "	${PRECISION} vec3 red;"
+			<< "	${PRECISION} vec3 blue;"
+			<< "};"
+			<< ""
+			<< "void modify (out S s)"
+			<< "{"
+			<< "	s.red = vec3(1.0, 0.0, 0.0);"
+			<< "	s.blue = vec3(0.0, 0.0, 1.0);"
+			<< "}"
+			<< ""
+			<< "void main (void)"
+			<< "{"
+			<< "	S s;"
+			<< "	modify(s);"
+			<< "	${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
+			<< "	if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))"
+			<< "		${DST} = vec4(1.0, 1.0, 1.0, 1.0);"
+			<< "	${ASSIGN_POS}"
+			<< "}";
+
+	precisionParams["PRECISION"] = "lowp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_out_lowp, "Struct with lowp members as an out function parameter",
+		outSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "mediump";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_out_mediump, "Struct with mediump members as an out function parameter",
+		outSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
+	precisionParams["PRECISION"] = "highp";
+	LOCAL_STRUCT_CASE_PARAMETERIZED(
+		parameter_out_highp, "Struct with highp members as an out function parameter",
+		outSrc,
+		{
+			c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
+		},
+		&precisionParams);
+
 	LOCAL_STRUCT_CASE(return, "Struct as a return value",
 		LineStream()
 		<< "${HEADER}"
@@ -1228,8 +1342,8 @@
 				 static void setUniforms (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY /* NOLINT(SET_UNIFORMS_BODY) */ \
 			};																																							\
 			struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY };	/* NOLINT(EVAL_FUNC_BODY) */												\
-			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC));		\
-			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC));		\
+			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\
+			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, TEXTURES, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\
 		} while (deGetFalse())
 
 	UNIFORM_STRUCT_CASE(basic, "Basic struct usage", false,
diff --git a/modules/gles3/functional/es3fTextureSizeTests.cpp b/modules/gles3/functional/es3fTextureSizeTests.cpp
index fa0bbc5..79c960d 100644
--- a/modules/gles3/functional/es3fTextureSizeTests.cpp
+++ b/modules/gles3/functional/es3fTextureSizeTests.cpp
@@ -125,7 +125,7 @@
 	tcu::Surface			referenceFrame	(viewport.width, viewport.height);
 	const tcu::IVec4		texBits			= tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
 	const tcu::PixelFormat&	rtFmt			= m_renderCtx.getRenderTarget().getPixelFormat();
-	const tcu::PixelFormat	thresholdFormat(std::min(texBits[0], rtFmt.redBits), std::min(texBits[1], rtFmt.greenBits), std::min(texBits[2], rtFmt.blueBits), std::min(texBits[3], rtFmt.alphaBits));
+	const tcu::PixelFormat	thresholdFormat(de::min(texBits[0], rtFmt.redBits), de::min(texBits[1], rtFmt.greenBits), de::min(texBits[2], rtFmt.blueBits), de::min(texBits[3], rtFmt.alphaBits));
 	tcu::RGBA				threshold		= thresholdFormat.getColorThreshold() + tcu::RGBA(7,7,7,7);
 	deUint32				wrapS			= GL_CLAMP_TO_EDGE;
 	deUint32				wrapT			= GL_CLAMP_TO_EDGE;
@@ -273,7 +273,7 @@
 	tcu::Surface			referenceFrame	(viewport.width, viewport.height);
 	const tcu::IVec4		texBits			= tcu::getTextureFormatBitDepth(glu::mapGLTransferFormat(m_format, m_dataType));
 	const tcu::PixelFormat&	rtFmt			= m_renderCtx.getRenderTarget().getPixelFormat();
-	const tcu::PixelFormat	thresholdFormat(std::min(texBits[0], rtFmt.redBits), std::min(texBits[1], rtFmt.greenBits), std::min(texBits[2], rtFmt.blueBits), std::min(texBits[3], rtFmt.alphaBits));
+	const tcu::PixelFormat	thresholdFormat(de::min(texBits[0], rtFmt.redBits), de::min(texBits[1], rtFmt.greenBits), de::min(texBits[2], rtFmt.blueBits), de::min(texBits[3], rtFmt.alphaBits));
 	tcu::RGBA				threshold		= thresholdFormat.getColorThreshold() + tcu::RGBA(7,7,7,7);
 	deUint32				wrapS			= GL_CLAMP_TO_EDGE;
 	deUint32				wrapT			= GL_CLAMP_TO_EDGE;