CP: Require 'master' config to be supported in Android CTS
am: 03d217bb53

Change-Id: I6ee82fc14e103e66fef989567c91e8af4b4d1300
diff --git a/android/cts/master/com.drawelements.deqp.egl.xml b/android/cts/master/com.drawelements.deqp.egl.xml
index 685a433..82622de 100644
--- a/android/cts/master/com.drawelements.deqp.egl.xml
+++ b/android/cts/master/com.drawelements.deqp.egl.xml
@@ -3116,18 +3116,12 @@
 					<Test name="tex_rgba4_tex_subimage_rgba4">
 						<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 					</Test>
-					<Test name="tex_rgba4_renderbuffer_clear_color">
-						<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-					</Test>
 					<Test name="renderbuffer_rgba4_tex_subimage_rgba8">
 						<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 					</Test>
 					<Test name="renderbuffer_rgba4_tex_subimage_rgba4">
 						<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 					</Test>
-					<Test name="renderbuffer_rgba4_renderbuffer_clear_color">
-						<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-					</Test>
 					<Test name="renderbuffer_rgb5_a1_tex_subimage_rgb5_a1">
 						<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 					</Test>
diff --git a/android/cts/master/egl-master.txt b/android/cts/master/egl-master.txt
index 9426a8f..a43d137 100644
--- a/android/cts/master/egl-master.txt
+++ b/android/cts/master/egl-master.txt
@@ -980,10 +980,8 @@
 dEQP-EGL.functional.image.modify.tex_rgb5_a1_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.tex_rgba4_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.renderbuffer_rgba4_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.renderbuffer_rgb5_a1_tex_subimage_rgb5_a1
 dEQP-EGL.functional.image.modify.renderbuffer_rgb5_a1_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.renderbuffer_rgb565_tex_subimage_rgb8
diff --git a/android/cts/master/src/egl-test-issues.txt b/android/cts/master/src/egl-test-issues.txt
index b3e70c3..7ce0644 100644
--- a/android/cts/master/src/egl-test-issues.txt
+++ b/android/cts/master/src/egl-test-issues.txt
@@ -23,3 +23,7 @@
 
 # Bug: 28676683
 dEQP-EGL.functional.color_clears.*.gles*.rgba5551_pbuffer
+
+# Bug: 30909609
+dEQP-EGL.functional.image.modify.tex_rgba4_renderbuffer_clear_color
+dEQP-EGL.functional.image.modify.renderbuffer_rgba4_renderbuffer_clear_color
diff --git a/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.cpp b/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.cpp
index 723706a..9569282 100644
--- a/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.cpp
+++ b/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.cpp
@@ -277,9 +277,10 @@
 
 // DeterministicFailAllocator
 
-DeterministicFailAllocator::DeterministicFailAllocator (const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs)
+DeterministicFailAllocator::DeterministicFailAllocator (const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs, Mode initialMode)
 	: ChainedAllocator	(allocator)
 	, m_numPassingAllocs(numPassingAllocs)
+	, m_mode			(initialMode)
 	, m_allocationNdx	(0)
 {
 }
@@ -288,9 +289,15 @@
 {
 }
 
+void DeterministicFailAllocator::setMode (Mode mode)
+{
+	m_mode = mode;
+}
+
 void* DeterministicFailAllocator::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
 {
-	if (deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs)
+	if ((m_mode == MODE_DO_NOT_COUNT) ||
+		(deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs))
 		return ChainedAllocator::allocate(size, alignment, allocationScope);
 	else
 		return DE_NULL;
@@ -298,7 +305,8 @@
 
 void* DeterministicFailAllocator::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
 {
-	if (deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs)
+	if ((m_mode == MODE_DO_NOT_COUNT) ||
+		(deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs))
 		return ChainedAllocator::reallocate(original, size, alignment, allocationScope);
 	else
 		return DE_NULL;
diff --git a/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.hpp b/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.hpp
index ecba532..63cabd8 100644
--- a/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.hpp
+++ b/external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.hpp
@@ -158,14 +158,26 @@
 class DeterministicFailAllocator : public ChainedAllocator
 {
 public:
-							DeterministicFailAllocator	(const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs);
+	enum Mode
+	{
+		MODE_DO_NOT_COUNT = 0,	//!< Do not count allocations, all allocs will succeed
+		MODE_COUNT_AND_FAIL,	//!< Count allocations, fail when reaching alloc N
+
+		MODE_LAST
+	};
+
+							DeterministicFailAllocator	(const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs, Mode initialMode);
 							~DeterministicFailAllocator	(void);
 
+	void					setMode						(Mode mode);
+
 	void*					allocate					(size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
 	void*					reallocate					(void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
 
 private:
 	const deUint32			m_numPassingAllocs;
+
+	Mode					m_mode;
 	volatile deUint32		m_allocationNdx;
 };
 
diff --git a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
index 399b894..e155d53 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
@@ -1840,7 +1840,9 @@
 				results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth >= 1), "Invalid dimensions for 3D image");
 				results.check(imageType != VK_IMAGE_TYPE_3D || properties.maxArrayLayers == 1, "Invalid maxArrayLayers for 3D image");
 
-				if (tiling == VK_IMAGE_TILING_OPTIMAL)
+				if (tiling == VK_IMAGE_TILING_OPTIMAL && imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
+					 ((supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) ||
+					 ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) && deviceFeatures.shaderStorageImageMultisample)))
 				{
 					const VkSampleCountFlags	requiredSampleCounts	= getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
 					results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
diff --git a/external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp
index 5336d44..771f996 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp
@@ -2124,18 +2124,12 @@
 	return tcu::TestStatus::pass("Ok");
 }
 
-template<typename Object>
-int getCreateCount (void)
-{
-	return 100;
-}
+// How many objects to create per thread
+template<typename Object>	int getCreateCount				(void) { return 100;	}
 
-template<>
-int getCreateCount<Device> (void)
-{
-	// Creating VkDevice can take significantly longer than other object types
-	return 20;
-}
+// Creating VkDevice and VkInstance can take significantly longer than other object types
+template<>					int getCreateCount<Instance>	(void) { return 20;		}
+template<>					int getCreateCount<Device>		(void) { return 20;		}
 
 template<typename Object>
 class CreateThread : public ThreadGroupThread
@@ -2305,28 +2299,34 @@
 	return tcu::TestStatus::pass("Ok");
 }
 
+template<typename Object>	deUint32	getOomIterLimit			(void) { return 1024;	}
+template<>					deUint32	getOomIterLimit<Device>	(void) { return 20;		}
+
 template<typename Object>
 tcu::TestStatus allocCallbackFailTest (Context& context, typename Object::Parameters params)
 {
-	AllocationCallbackRecorder			resCallbacks	(getSystemAllocator(), 128);
-	const Environment					rootEnv			(context.getPlatformInterface(),
-														 context.getDeviceInterface(),
-														 context.getDevice(),
-														 context.getUniversalQueueFamilyIndex(),
-														 context.getBinaryCollection(),
-														 resCallbacks.getCallbacks(),
-														 1u);
+	AllocationCallbackRecorder			resCallbacks		(getSystemAllocator(), 128);
+	const Environment					rootEnv				(context.getPlatformInterface(),
+															 context.getDeviceInterface(),
+															 context.getDevice(),
+															 context.getUniversalQueueFamilyIndex(),
+															 context.getBinaryCollection(),
+															 resCallbacks.getCallbacks(),
+															 1u);
+	deUint32							numPassingAllocs	= 0;
+	const deUint32						cmdLineIterCount	= (deUint32)context.getTestContext().getCommandLine().getTestIterationCount();
+	const deUint32						maxTries			= cmdLineIterCount != 0 ? cmdLineIterCount : getOomIterLimit<Object>();
 
 	{
-		const EnvClone						resEnv				(rootEnv, getDefaulDeviceParameters(context), 1u);
-		const typename Object::Resources	res					(resEnv.env, params);
-		deUint32							numPassingAllocs	= 0;
-		const deUint32						maxTries			= 1u<<10;
+		const EnvClone						resEnv	(rootEnv, getDefaulDeviceParameters(context), 1u);
+		const typename Object::Resources	res		(resEnv.env, params);
 
 		// Iterate over test until object allocation succeeds
 		for (; numPassingAllocs < maxTries; ++numPassingAllocs)
 		{
-			DeterministicFailAllocator			objAllocator(getSystemAllocator(), numPassingAllocs);
+			DeterministicFailAllocator			objAllocator(getSystemAllocator(),
+															 numPassingAllocs,
+															 DeterministicFailAllocator::MODE_COUNT_AND_FAIL);
 			AllocationCallbackRecorder			recorder	(objAllocator.getCallbacks(), 128);
 			const Environment					objEnv		(resEnv.env.vkp,
 															 resEnv.env.vkd,
@@ -2371,7 +2371,12 @@
 	if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u))
 		return tcu::TestStatus::fail("Invalid allocation callback");
 
-	return tcu::TestStatus::pass("Ok");
+	if (numPassingAllocs == 0)
+		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks not called");
+	else if (numPassingAllocs == maxTries)
+		return tcu::TestStatus(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Max iter count reached; OOM testing incomplete");
+	else
+		return tcu::TestStatus::pass("Ok");
 }
 
 // Utilities for creating groups
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp
index f7730a4..ef6b309 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp
@@ -31,6 +31,7 @@
 #include "vkQueryUtil.hpp"
 #include "vkRefUtil.hpp"
 #include "tcuImageCompare.hpp"
+#include "deSTLUtil.hpp"
 
 namespace vkt
 {
@@ -367,6 +368,12 @@
 		!isLinearFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat, VK_IMAGE_TILING_OPTIMAL))
 		throw tcu::NotSupportedError(std::string("Unsupported format for linear filtering: ") + getFormatName(imageFormat));
 
+	if ((samplerParams.addressModeU == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE ||
+		 samplerParams.addressModeV == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE ||
+		 samplerParams.addressModeW == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) &&
+		!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_sampler_mirror_clamp_to_edge"))
+		TCU_THROW(NotSupportedError, "VK_KHR_sampler_mirror_clamp_to_edge not supported");
+
 	if (isCompressedFormat(imageFormat) && imageViewType == VK_IMAGE_VIEW_TYPE_3D)
 	{
 		// \todo [2016-01-22 pyry] Mandate VK_ERROR_FORMAT_NOT_SUPPORTED
diff --git a/external/vulkancts/modules/vulkan/vktTestCase.cpp b/external/vulkancts/modules/vulkan/vktTestCase.cpp
index 42b066c..6971b11 100644
--- a/external/vulkancts/modules/vulkan/vktTestCase.cpp
+++ b/external/vulkancts/modules/vulkan/vktTestCase.cpp
@@ -123,12 +123,14 @@
 									VkPhysicalDevice				physicalDevice,
 									deUint32						queueIndex,
 									const VkPhysicalDeviceFeatures&	enabledFeatures,
+									const vector<string>&			enabledExtensions,
 									const tcu::CommandLine&			cmdLine)
 {
 	VkDeviceQueueCreateInfo		queueInfo;
 	VkDeviceCreateInfo			deviceInfo;
 	vector<string>				enabledLayers;
 	vector<const char*>			layerPtrs;
+	vector<const char*>			extensionPtrs;
 	const float					queuePriority	= 1.0f;
 
 	deMemset(&queueInfo,	0, sizeof(queueInfo));
@@ -146,6 +148,11 @@
 	for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
 		layerPtrs[ndx] = enabledLayers[ndx].c_str();
 
+	extensionPtrs.resize(enabledExtensions.size());
+
+	for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
+		extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
+
 	queueInfo.sType							= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
 	queueInfo.pNext							= DE_NULL;
 	queueInfo.flags							= (VkDeviceQueueCreateFlags)0u;
@@ -157,8 +164,8 @@
 	deviceInfo.pNext						= DE_NULL;
 	deviceInfo.queueCreateInfoCount			= 1u;
 	deviceInfo.pQueueCreateInfos			= &queueInfo;
-	deviceInfo.enabledExtensionCount		= 0u;
-	deviceInfo.ppEnabledExtensionNames		= DE_NULL;
+	deviceInfo.enabledExtensionCount		= (deUint32)extensionPtrs.size();
+	deviceInfo.ppEnabledExtensionNames		= (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
 	deviceInfo.enabledLayerCount			= (deUint32)layerPtrs.size();
 	deviceInfo.ppEnabledLayerNames			= (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
 	deviceInfo.pEnabledFeatures				= &enabledFeatures;
@@ -180,12 +187,14 @@
 	VkDevice							getDevice						(void) const	{ return *m_device;						}
 	const DeviceInterface&				getDeviceInterface				(void) const	{ return m_deviceInterface;				}
 	const VkPhysicalDeviceProperties&	getDeviceProperties				(void) const	{ return m_deviceProperties;			}
+	const vector<string>&				getDeviceExtensions				(void) const	{ return m_deviceExtensions;			}
 
 	deUint32							getUniversalQueueFamilyIndex	(void) const	{ return m_universalQueueFamilyIndex;	}
 	VkQueue								getUniversalQueue				(void) const;
 
 private:
 	static VkPhysicalDeviceFeatures		filterDefaultDeviceFeatures		(const VkPhysicalDeviceFeatures& deviceFeatures);
+	static vector<string>				filterDefaultDeviceExtensions	(const vector<VkExtensionProperties>& deviceExtensions);
 
 	const Unique<VkInstance>			m_instance;
 	const InstanceDriver				m_instanceInterface;
@@ -195,6 +204,7 @@
 	const deUint32						m_universalQueueFamilyIndex;
 	const VkPhysicalDeviceFeatures		m_deviceFeatures;
 	const VkPhysicalDeviceProperties	m_deviceProperties;
+	const vector<string>				m_deviceExtensions;
 
 	const Unique<VkDevice>				m_device;
 	const DeviceDriver					m_deviceInterface;
@@ -207,7 +217,8 @@
 	, m_universalQueueFamilyIndex	(findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
 	, m_deviceFeatures				(filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(m_instanceInterface, m_physicalDevice)))
 	, m_deviceProperties			(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
-	, m_device						(createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, cmdLine))
+	, m_deviceExtensions			(filterDefaultDeviceExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
+	, m_device						(createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, m_deviceExtensions, cmdLine))
 	, m_deviceInterface				(m_instanceInterface, *m_device)
 {
 }
@@ -233,6 +244,20 @@
 	return enabledDeviceFeatures;
 }
 
+vector<string> DefaultDevice::filterDefaultDeviceExtensions (const vector<VkExtensionProperties>& deviceExtensions)
+{
+	vector<string> enabledExtensions;
+
+	// The only extension we enable always (when supported) is
+	// VK_KHR_sampler_mirror_clamp_to_edge that is defined in
+	// the core spec and supported widely.
+	const char* const	mirrorClampToEdgeExt	= "VK_KHR_sampler_mirror_clamp_to_edge";
+	if (vk::isExtensionSupported(deviceExtensions, vk::RequiredExtension(mirrorClampToEdgeExt)))
+		enabledExtensions.push_back(mirrorClampToEdgeExt);
+
+	return enabledExtensions;
+}
+
 // Allocator utilities
 
 vk::Allocator* createAllocator (DefaultDevice* device)
@@ -265,6 +290,7 @@
 vk::VkPhysicalDevice					Context::getPhysicalDevice				(void) const { return m_device->getPhysicalDevice();			}
 const vk::VkPhysicalDeviceFeatures&		Context::getDeviceFeatures				(void) const { return m_device->getDeviceFeatures();			}
 const vk::VkPhysicalDeviceProperties&	Context::getDeviceProperties			(void) const { return m_device->getDeviceProperties();			}
+const vector<string>&					Context::getDeviceExtensions			(void) const { return m_device->getDeviceExtensions();			}
 vk::VkDevice							Context::getDevice						(void) const { return m_device->getDevice();					}
 const vk::DeviceInterface&				Context::getDeviceInterface				(void) const { return m_device->getDeviceInterface();			}
 deUint32								Context::getUniversalQueueFamilyIndex	(void) const { return m_device->getUniversalQueueFamilyIndex();	}
diff --git a/external/vulkancts/modules/vulkan/vktTestCase.hpp b/external/vulkancts/modules/vulkan/vktTestCase.hpp
index 89a6492..379d86c 100644
--- a/external/vulkancts/modules/vulkan/vktTestCase.hpp
+++ b/external/vulkancts/modules/vulkan/vktTestCase.hpp
@@ -65,6 +65,7 @@
 	vk::VkPhysicalDevice						getPhysicalDevice				(void) const;
 	const vk::VkPhysicalDeviceFeatures&			getDeviceFeatures				(void) const;
 	const vk::VkPhysicalDeviceProperties&		getDeviceProperties				(void) const;
+	const std::vector<std::string>&				getDeviceExtensions				(void) const;
 	vk::VkDevice								getDevice						(void) const;
 	const vk::DeviceInterface&					getDeviceInterface				(void) const;
 	deUint32									getUniversalQueueFamilyIndex	(void) const;
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
index 66db6e6..b74bda0 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp
@@ -230,7 +230,9 @@
 	for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 1024u; ++numPassingAllocs)
 	{
 		AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
-		DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(), numPassingAllocs);
+		DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(),
+														 numPassingAllocs,
+														 DeterministicFailAllocator::MODE_DO_NOT_COUNT);
 		bool						gotOOM				= false;
 
 		log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
@@ -238,6 +240,11 @@
 		try
 		{
 			const InstanceHelper		instHelper	(context, wsiType, failingAllocator.getCallbacks());
+
+			// OOM is not simulated for VkInstance as we don't want to spend time
+			// testing OOM paths inside instance creation.
+			failingAllocator.setMode(DeterministicFailAllocator::MODE_COUNT_AND_FAIL);
+
 			const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
 			const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki,
 																   *instHelper.instance,
diff --git a/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp b/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
index 4de0915..d18c88a 100644
--- a/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
+++ b/external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp
@@ -607,7 +607,9 @@
 	if (m_numPassingAllocs <= 16*1024u)
 	{
 		AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
-		DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(), m_numPassingAllocs);
+		DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(),
+														 m_numPassingAllocs,
+														 DeterministicFailAllocator::MODE_DO_NOT_COUNT);
 		bool						gotOOM				= false;
 
 		log << TestLog::Message << "Testing with " << m_numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
@@ -625,6 +627,10 @@
 			const DeviceHelper						devHelper	(m_context, instHelper.vki, *instHelper.instance, *surface, failingAllocator.getCallbacks());
 			const vector<VkSwapchainCreateInfoKHR>	cases		(generateSwapchainParameterCases(m_params.wsiType, m_params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
 
+			// We don't care testing OOM paths in VkInstance, VkSurface, or VkDevice
+			// creation as they are tested elsewhere.
+			failingAllocator.setMode(DeterministicFailAllocator::MODE_COUNT_AND_FAIL);
+
 			for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
 			{
 				VkSwapchainCreateInfoKHR	curParams	= cases[caseNdx];
diff --git a/framework/egl/egluConfigInfo.cpp b/framework/egl/egluConfigInfo.cpp
index b1eefc0..aed08f3 100644
--- a/framework/egl/egluConfigInfo.cpp
+++ b/framework/egl/egluConfigInfo.cpp
@@ -25,6 +25,8 @@
 #include "egluDefs.hpp"
 #include "eglwLibrary.hpp"
 #include "eglwEnums.hpp"
+#include "egluUtil.hpp"
+#include "deSTLUtil.hpp"
 
 namespace eglu
 {
@@ -66,11 +68,20 @@
 		case EGL_TRANSPARENT_RED_VALUE:		return transparentRedValue;
 		case EGL_TRANSPARENT_GREEN_VALUE:	return transparentGreenValue;
 		case EGL_TRANSPARENT_BLUE_VALUE:	return transparentBlueValue;
-		default:							TCU_FAIL("Unknown attribute");
+
+		// EGL_EXT_yuv_surface
+		case EGL_YUV_ORDER_EXT:				return yuvOrder;
+		case EGL_YUV_NUMBER_OF_PLANES_EXT:	return yuvNumberOfPlanes;
+		case EGL_YUV_SUBSAMPLE_EXT:			return yuvSubsample;
+		case EGL_YUV_DEPTH_RANGE_EXT:		return yuvDepthRange;
+		case EGL_YUV_CSC_STANDARD_EXT:		return yuvCscStandard;
+		case EGL_YUV_PLANE_BPP_EXT:			return yuvPlaneBpp;
+
+		default:							TCU_THROW(InternalError, "Unknown attribute");
 	}
 }
 
-void queryConfigInfo (const Library& egl, EGLDisplay display, EGLConfig config, ConfigInfo* dst)
+void queryCoreConfigInfo (const Library& egl, EGLDisplay display, EGLConfig config, ConfigInfo* dst)
 {
 	egl.getConfigAttrib(display, config, EGL_BUFFER_SIZE,				&dst->bufferSize);
 	egl.getConfigAttrib(display, config, EGL_RED_SIZE,					&dst->redSize);
@@ -106,4 +117,21 @@
 	EGLU_CHECK_MSG(egl, "Failed to query config info");
 }
 
+void queryExtConfigInfo (const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig config, ConfigInfo* dst)
+{
+	const std::vector<std::string>	extensions	= getDisplayExtensions(egl, display);
+
+	if (de::contains(extensions.begin(), extensions.end(), "EGL_EXT_yuv_surface"))
+	{
+		egl.getConfigAttrib(display, config, EGL_YUV_ORDER_EXT,				(EGLint*)&dst->yuvOrder);
+		egl.getConfigAttrib(display, config, EGL_YUV_NUMBER_OF_PLANES_EXT,	(EGLint*)&dst->yuvNumberOfPlanes);
+		egl.getConfigAttrib(display, config, EGL_YUV_SUBSAMPLE_EXT,			(EGLint*)&dst->yuvSubsample);
+		egl.getConfigAttrib(display, config, EGL_YUV_DEPTH_RANGE_EXT,		(EGLint*)&dst->yuvDepthRange);
+		egl.getConfigAttrib(display, config, EGL_YUV_CSC_STANDARD_EXT,		(EGLint*)&dst->yuvCscStandard);
+		egl.getConfigAttrib(display, config, EGL_YUV_PLANE_BPP_EXT,			(EGLint*)&dst->yuvPlaneBpp);
+
+		EGLU_CHECK_MSG(egl, "Failed to query EGL_EXT_yuv_surface config attribs");
+	}
+}
+
 } // eglu
diff --git a/framework/egl/egluConfigInfo.hpp b/framework/egl/egluConfigInfo.hpp
index 42fcaa3..356c50a 100644
--- a/framework/egl/egluConfigInfo.hpp
+++ b/framework/egl/egluConfigInfo.hpp
@@ -10,7 +10,7 @@
  * 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
+ *	  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,
@@ -25,6 +25,7 @@
 
 #include "tcuDefs.hpp"
 #include "eglwDefs.hpp"
+#include "eglwEnums.hpp"
 
 namespace eglw
 {
@@ -37,6 +38,7 @@
 class ConfigInfo
 {
 public:
+	// Core attributes
 	deInt32			bufferSize;
 	deInt32			redSize;
 	deInt32			greenSize;
@@ -69,45 +71,62 @@
 	deInt32			transparentGreenValue;
 	deInt32			transparentBlueValue;
 
+	// Extension attributes - set by queryExtConfigInfo()
+
+	// EGL_EXT_yuv_surface
+	deUint32		yuvOrder;
+	deInt32			yuvNumberOfPlanes;
+	deUint32		yuvSubsample;
+	deUint32		yuvDepthRange;
+	deUint32		yuvCscStandard;
+	deInt32			yuvPlaneBpp;
+
 	ConfigInfo (void)
-		: bufferSize            (0)
-		, redSize               (0)
-		, greenSize             (0)
-		, blueSize              (0)
-		, luminanceSize         (0)
-		, alphaSize             (0)
-		, alphaMaskSize         (0)
-		, bindToTextureRGB      (0)
-		, bindToTextureRGBA     (0)
-		, colorBufferType       (0)
-		, configCaveat          (0)
-		, configId              (0)
-		, conformant            (0)
-		, depthSize             (0)
-		, level                 (0)
-		, maxPbufferWidth       (0)
-		, maxPbufferHeight      (0)
-		, maxSwapInterval       (0)
-		, minSwapInterval       (0)
-		, nativeRenderable      (0)
-		, nativeVisualId        (0)
-		, nativeVisualType      (0)
-		, renderableType        (0)
-		, sampleBuffers         (0)
-		, samples               (0)
-		, stencilSize           (0)
-		, surfaceType           (0)
-		, transparentType       (0)
-		, transparentRedValue   (0)
-		, transparentGreenValue (0)
-		, transparentBlueValue  (0)
+		: bufferSize			(0)
+		, redSize				(0)
+		, greenSize				(0)
+		, blueSize				(0)
+		, luminanceSize			(0)
+		, alphaSize				(0)
+		, alphaMaskSize			(0)
+		, bindToTextureRGB		(0)
+		, bindToTextureRGBA		(0)
+		, colorBufferType		(0)
+		, configCaveat			(0)
+		, configId				(0)
+		, conformant			(0)
+		, depthSize				(0)
+		, level					(0)
+		, maxPbufferWidth		(0)
+		, maxPbufferHeight		(0)
+		, maxSwapInterval		(0)
+		, minSwapInterval		(0)
+		, nativeRenderable		(0)
+		, nativeVisualId		(0)
+		, nativeVisualType		(0)
+		, renderableType		(0)
+		, sampleBuffers			(0)
+		, samples				(0)
+		, stencilSize			(0)
+		, surfaceType			(0)
+		, transparentType		(0)
+		, transparentRedValue	(0)
+		, transparentGreenValue	(0)
+		, transparentBlueValue	(0)
+		, yuvOrder				(EGL_NONE)
+		, yuvNumberOfPlanes		(0)
+		, yuvSubsample			(EGL_NONE)
+		, yuvDepthRange			(EGL_NONE)
+		, yuvCscStandard		(EGL_NONE)
+		, yuvPlaneBpp			(EGL_YUV_PLANE_BPP_0_EXT)
 	{
 	}
 
 	deInt32 getAttribute (deUint32 attribute) const;
 };
 
-void	queryConfigInfo		(const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig config, ConfigInfo* dst);
+void	queryCoreConfigInfo	(const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig config, ConfigInfo* dst);
+void	queryExtConfigInfo	(const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig config, ConfigInfo* dst);
 
 } // eglu
 
diff --git a/framework/egl/egluStrUtil.inl b/framework/egl/egluStrUtil.inl
index 4000783..aab161d 100644
--- a/framework/egl/egluStrUtil.inl
+++ b/framework/egl/egluStrUtil.inl
@@ -132,6 +132,33 @@
 	}
 }
 
+const char* getYuvOrderName (int value)
+{
+	switch (value)
+	{
+		case EGL_NONE:					return "EGL_NONE";
+		case EGL_YUV_ORDER_YUV_EXT:		return "EGL_YUV_ORDER_YUV_EXT";
+		case EGL_YUV_ORDER_YVU_EXT:		return "EGL_YUV_ORDER_YVU_EXT";
+		case EGL_YUV_ORDER_YUYV_EXT:	return "EGL_YUV_ORDER_YUYV_EXT";
+		case EGL_YUV_ORDER_UYVY_EXT:	return "EGL_YUV_ORDER_UYVY_EXT";
+		case EGL_YUV_ORDER_YVYU_EXT:	return "EGL_YUV_ORDER_YVYU_EXT";
+		case EGL_YUV_ORDER_VYUY_EXT:	return "EGL_YUV_ORDER_VYUY_EXT";
+		case EGL_YUV_ORDER_AYUV_EXT:	return "EGL_YUV_ORDER_AYUV_EXT";
+		default:						return DE_NULL;
+	}
+}
+
+const char* getYuvPlaneBppName (int value)
+{
+	switch (value)
+	{
+		case EGL_YUV_PLANE_BPP_0_EXT:	return "EGL_YUV_PLANE_BPP_0_EXT";
+		case EGL_YUV_PLANE_BPP_8_EXT:	return "EGL_YUV_PLANE_BPP_8_EXT";
+		case EGL_YUV_PLANE_BPP_10_EXT:	return "EGL_YUV_PLANE_BPP_10_EXT";
+		default:						return DE_NULL;
+	}
+}
+
 const char* getSurfaceTargetName (int value)
 {
 	switch (value)
diff --git a/framework/egl/egluStrUtilPrototypes.inl b/framework/egl/egluStrUtilPrototypes.inl
index a5bda20..7ceac62 100644
--- a/framework/egl/egluStrUtilPrototypes.inl
+++ b/framework/egl/egluStrUtilPrototypes.inl
@@ -10,6 +10,8 @@
 const char*							getContextAttribName		(int value);
 const char*							getConfigAttribName			(int value);
 const char*							getSurfaceAttribName		(int value);
+const char*							getYuvOrderName				(int value);
+const char*							getYuvPlaneBppName			(int value);
 const char*							getSurfaceTargetName		(int value);
 const char*							getColorBufferTypeName		(int value);
 const char*							getConfigCaveatName			(int value);
@@ -30,6 +32,8 @@
 inline tcu::Format::Enum<int, 2>	getContextAttribStr			(int value)		{ return tcu::Format::Enum<int, 2>(getContextAttribName, value); }
 inline tcu::Format::Enum<int, 2>	getConfigAttribStr			(int value)		{ return tcu::Format::Enum<int, 2>(getConfigAttribName, value); }
 inline tcu::Format::Enum<int, 2>	getSurfaceAttribStr			(int value)		{ return tcu::Format::Enum<int, 2>(getSurfaceAttribName, value); }
+inline tcu::Format::Enum<int, 2>	getYuvOrderStr				(int value)		{ return tcu::Format::Enum<int, 2>(getYuvOrderName, value); }
+inline tcu::Format::Enum<int, 2>	getYuvPlaneBppStr			(int value)		{ return tcu::Format::Enum<int, 2>(getYuvPlaneBppName, value); }
 inline tcu::Format::Enum<int, 2>	getSurfaceTargetStr			(int value)		{ return tcu::Format::Enum<int, 2>(getSurfaceTargetName, value); }
 inline tcu::Format::Enum<int, 2>	getColorBufferTypeStr		(int value)		{ return tcu::Format::Enum<int, 2>(getColorBufferTypeName, value); }
 inline tcu::Format::Enum<int, 2>	getConfigCaveatStr			(int value)		{ return tcu::Format::Enum<int, 2>(getConfigCaveatName, value); }
diff --git a/modules/egl/teglChooseConfigReference.cpp b/modules/egl/teglChooseConfigReference.cpp
index 8dfbef5..50a2769 100644
--- a/modules/egl/teglChooseConfigReference.cpp
+++ b/modules/egl/teglChooseConfigReference.cpp
@@ -29,6 +29,8 @@
 #include "eglwLibrary.hpp"
 #include "eglwEnums.hpp"
 
+#include "deSTLUtil.hpp"
+
 #include <algorithm>
 #include <vector>
 #include <map>
@@ -111,6 +113,35 @@
 		}
 	}
 
+	static int getYuvOrderRank (EGLenum order)
+	{
+		switch (order)
+		{
+			case EGL_NONE:					return 0;
+			case EGL_YUV_ORDER_YUV_EXT:		return 1;
+			case EGL_YUV_ORDER_YVU_EXT:		return 2;
+			case EGL_YUV_ORDER_YUYV_EXT:	return 3;
+			case EGL_YUV_ORDER_YVYU_EXT:	return 4;
+			case EGL_YUV_ORDER_UYVY_EXT:	return 5;
+			case EGL_YUV_ORDER_VYUY_EXT:	return 6;
+			case EGL_YUV_ORDER_AYUV_EXT:	return 7;
+			default:
+				TCU_THROW(TestError, (std::string("Unknown YUV order: ") + eglu::getYuvOrderStr(order).toString()).c_str());
+		}
+	}
+
+	static int getYuvPlaneBppValue (EGLenum bpp)
+	{
+		switch (bpp)
+		{
+			case EGL_YUV_PLANE_BPP_0_EXT:	return 0;
+			case EGL_YUV_PLANE_BPP_8_EXT:	return 8;
+			case EGL_YUV_PLANE_BPP_10_EXT:	return 10;
+			default:
+				TCU_THROW(TestError, (std::string("Unknown YUV plane BPP: ") + eglu::getYuvPlaneBppStr(bpp).toString()).c_str());
+		}
+	}
+
 	typedef bool (*CompareFunc) (const SurfaceConfig& a, const SurfaceConfig& b);
 
 	static bool compareCaveat (const SurfaceConfig& a, const SurfaceConfig& b)
@@ -123,7 +154,12 @@
 		return getColorBufferTypeRank((EGLenum)a.m_info.colorBufferType) < getColorBufferTypeRank((EGLenum)b.m_info.colorBufferType);
 	}
 
-	static bool compareColorBufferBits (const SurfaceConfig& a, const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors)
+	static bool compareYuvOrder (const SurfaceConfig& a, const SurfaceConfig& b)
+	{
+		return getYuvOrderRank((EGLenum)a.m_info.yuvOrder) < getYuvOrderRank((EGLenum)b.m_info.yuvOrder);
+	}
+
+	static bool compareColorBufferBits (const SurfaceConfig& a, const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified)
 	{
 		DE_ASSERT(a.m_info.colorBufferType == b.m_info.colorBufferType);
 		switch (a.m_info.colorBufferType)
@@ -144,8 +180,7 @@
 			}
 
 			case EGL_YUV_BUFFER_EXT:
-				// \todo [mika 2015-05-05] Sort YUV configs correctly. Currently all YUV configs are non-conformant and ordering can be relaxed.
-				return true;
+				return yuvPlaneBppSpecified ? (a.m_info.yuvPlaneBpp > b.m_info.yuvPlaneBpp) : false;
 
 			default:
 				DE_ASSERT(DE_FALSE);
@@ -177,7 +212,9 @@
 
 	friend bool operator== (const SurfaceConfig& a, const SurfaceConfig& b)
 	{
-		for (std::map<EGLenum, AttribRule>::const_iterator iter = SurfaceConfig::defaultRules.begin(); iter != SurfaceConfig::defaultRules.end(); iter++)
+		const std::map<EGLenum, AttribRule> defaultRules = getDefaultRules();
+
+		for (std::map<EGLenum, AttribRule>::const_iterator iter = defaultRules.begin(); iter != defaultRules.end(); iter++)
 		{
 			const EGLenum attribute = iter->first;
 
@@ -186,7 +223,7 @@
 		return true;
 	}
 
-	bool compareTo (const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors) const
+	bool compareTo (const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified) const
 	{
 		static const SurfaceConfig::CompareFunc compareFuncs[] =
 		{
@@ -199,6 +236,7 @@
 			SurfaceConfig::compareAttributeSmaller<EGL_DEPTH_SIZE>,
 			SurfaceConfig::compareAttributeSmaller<EGL_STENCIL_SIZE>,
 			SurfaceConfig::compareAttributeSmaller<EGL_ALPHA_MASK_SIZE>,
+			SurfaceConfig::compareYuvOrder,
 			SurfaceConfig::compareAttributeSmaller<EGL_CONFIG_ID>
 		};
 
@@ -209,9 +247,9 @@
 		{
 			if (!compareFuncs[ndx])
 			{
-				if (compareColorBufferBits(*this, b, specifiedRGBColors, specifiedLuminanceColors))
+				if (compareColorBufferBits(*this, b, specifiedRGBColors, specifiedLuminanceColors, yuvPlaneBppSpecified))
 					return true;
-				else if (compareColorBufferBits(b, *this, specifiedRGBColors, specifiedLuminanceColors))
+				else if (compareColorBufferBits(b, *this, specifiedRGBColors, specifiedLuminanceColors, yuvPlaneBppSpecified))
 					return false;
 
 				continue;
@@ -226,9 +264,7 @@
 		TCU_FAIL("Unable to compare configs - duplicate ID?");
 	}
 
-	static const std::map<EGLenum, AttribRule> defaultRules;
-
-	static std::map<EGLenum, AttribRule> initAttribRules (void)
+	static std::map<EGLenum, AttribRule> getDefaultRules (void)
 	{
 		// \todo [2011-03-24 pyry] From EGL 1.4 spec - check that this is valid for other versions as well
 		std::map<EGLenum, AttribRule> rules;
@@ -263,6 +299,14 @@
 		rules[EGL_TRANSPARENT_GREEN_VALUE]	= AttribRule(EGL_TRANSPARENT_GREEN_VALUE,	EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_NONE);
 		rules[EGL_TRANSPARENT_BLUE_VALUE]	= AttribRule(EGL_TRANSPARENT_BLUE_VALUE,	EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_NONE);
 
+		// EGL_EXT_yuv_surface
+		rules[EGL_YUV_ORDER_EXT]			= AttribRule(EGL_YUV_ORDER_EXT,				EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_SPECIAL);
+		rules[EGL_YUV_NUMBER_OF_PLANES_EXT]	= AttribRule(EGL_YUV_NUMBER_OF_PLANES_EXT,	EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_NONE);
+		rules[EGL_YUV_SUBSAMPLE_EXT]		= AttribRule(EGL_YUV_SUBSAMPLE_EXT,			EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_NONE);
+		rules[EGL_YUV_DEPTH_RANGE_EXT]		= AttribRule(EGL_YUV_DEPTH_RANGE_EXT,		EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_NONE);
+		rules[EGL_YUV_CSC_STANDARD_EXT]		= AttribRule(EGL_YUV_CSC_STANDARD_EXT,		EGL_DONT_CARE,		CRITERIA_EXACT,		SORTORDER_NONE);
+		rules[EGL_YUV_PLANE_BPP_EXT]		= AttribRule(EGL_YUV_PLANE_BPP_EXT,			EGL_DONT_CARE,		CRITERIA_AT_LEAST,	SORTORDER_SPECIAL);	//	3
+
 		return rules;
 	}
 private:
@@ -270,25 +314,25 @@
 	ConfigInfo m_info;
 };
 
-const std::map<EGLenum, AttribRule> SurfaceConfig::defaultRules = SurfaceConfig::initAttribRules();
-
 class CompareConfigs
 {
 public:
-	CompareConfigs (const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors)
+	CompareConfigs (const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified)
 		: m_specifiedRGBColors			(specifiedRGBColors)
 		, m_specifiedLuminanceColors	(specifiedLuminanceColors)
+		, m_yuvPlaneBppSpecified		(yuvPlaneBppSpecified)
 	{
 	}
 
 	bool operator() (const SurfaceConfig& a, const SurfaceConfig& b)
 	{
-		return a.compareTo(b, m_specifiedRGBColors, m_specifiedLuminanceColors);
+		return a.compareTo(b, m_specifiedRGBColors, m_specifiedLuminanceColors, m_yuvPlaneBppSpecified);
 	}
 
 private:
 	const tcu::BVec4	m_specifiedRGBColors;
 	const tcu::BVec2	m_specifiedLuminanceColors;
+	const bool			m_yuvPlaneBppSpecified;
 };
 
 class ConfigFilter
@@ -297,13 +341,13 @@
 	std::map<EGLenum, AttribRule> m_rules;
 public:
 	ConfigFilter ()
-		: m_rules(SurfaceConfig::defaultRules)
+		: m_rules(SurfaceConfig::getDefaultRules())
 	{
 	}
 
 	void setValue (EGLenum name, EGLint value)
 	{
-		DE_ASSERT(SurfaceConfig::defaultRules.find(name) != SurfaceConfig::defaultRules.end());
+		DE_ASSERT(de::contains(m_rules, name));
 		m_rules[name].value = value;
 	}
 
@@ -318,13 +362,13 @@
 		}
 	}
 
-	AttribRule getAttribute (EGLenum name)
+	AttribRule getAttribute (EGLenum name) const
 	{
-		DE_ASSERT(SurfaceConfig::defaultRules.find(name) != SurfaceConfig::defaultRules.end());
-		return m_rules[name];
+		DE_ASSERT(de::contains(m_rules, name));
+		return m_rules.find(name)->second;
 	}
 
-	bool isMatch (const SurfaceConfig& config)
+	bool isMatch (const SurfaceConfig& config) const
 	{
 		for (std::map<EGLenum, AttribRule>::const_iterator iter = m_rules.begin(); iter != m_rules.end(); iter++)
 		{
@@ -366,7 +410,7 @@
 		return true;
 	}
 
-	tcu::BVec4 getSpecifiedRGBColors (void)
+	tcu::BVec4 getSpecifiedRGBColors (void) const
 	{
 		const EGLenum bitAttribs[] =
 		{
@@ -392,7 +436,7 @@
 		return result;
 	}
 
-	tcu::BVec2 getSpecifiedLuminanceColors (void)
+	tcu::BVec2 getSpecifiedLuminanceColors (void) const
 	{
 		const EGLenum bitAttribs[] =
 		{
@@ -416,7 +460,15 @@
 		return result;
 	}
 
-	std::vector<SurfaceConfig> filter (const std::vector<SurfaceConfig>& configs)
+	bool isYuvPlaneBppSpecified (void) const
+	{
+		const EGLenum	attrib	= EGL_YUV_PLANE_BPP_EXT;
+		const EGLint	value	= getAttribute(attrib).value;
+
+		return (value != 0) && (value != EGL_DONT_CARE);
+	}
+
+	std::vector<SurfaceConfig> filter (const std::vector<SurfaceConfig>& configs) const
 	{
 		std::vector<SurfaceConfig> out;
 
@@ -434,11 +486,15 @@
 	// Get all configs
 	std::vector<EGLConfig> eglConfigs = eglu::getConfigs(egl, display);
 
-	// Config infos
+	// Config infos - including extension attributes
 	std::vector<ConfigInfo> configInfos;
 	configInfos.resize(eglConfigs.size());
+
 	for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
-		eglu::queryConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
+	{
+		eglu::queryCoreConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
+		eglu::queryExtConfigInfo(egl, display, eglConfigs[ndx], &configInfos[ndx]);
+	}
 
 	// Pair configs with info
 	std::vector<SurfaceConfig> configs;
@@ -452,7 +508,7 @@
 	std::vector<SurfaceConfig> filteredConfigs = configFilter.filter(configs);
 
 	// Sort configs
-	std::sort(filteredConfigs.begin(), filteredConfigs.end(), CompareConfigs(configFilter.getSpecifiedRGBColors(), configFilter.getSpecifiedLuminanceColors()));
+	std::sort(filteredConfigs.begin(), filteredConfigs.end(), CompareConfigs(configFilter.getSpecifiedRGBColors(), configFilter.getSpecifiedLuminanceColors(), configFilter.isYuvPlaneBppSpecified()));
 
 	// Write to dst list
 	dst.resize(filteredConfigs.size());
diff --git a/modules/egl/teglQuerySurfaceTests.cpp b/modules/egl/teglQuerySurfaceTests.cpp
index be44395..3815818 100644
--- a/modules/egl/teglQuerySurfaceTests.cpp
+++ b/modules/egl/teglQuerySurfaceTests.cpp
@@ -309,7 +309,7 @@
 		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
 		ConfigInfo							info;
 
-		eglu::queryConfigInfo(egl, display, config, &info);
+		eglu::queryCoreConfigInfo(egl, display, config, &info);
 
 		log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage;
 		EGLU_CHECK_MSG(egl, "before queries");
@@ -340,7 +340,7 @@
 		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
 		ConfigInfo							info;
 
-		eglu::queryConfigInfo(egl, display, config, &info);
+		eglu::queryCoreConfigInfo(egl, display, config, &info);
 
 		log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage;
 		EGLU_CHECK_MSG(egl, "before queries");
@@ -370,7 +370,7 @@
 		int				height	= 64;
 		ConfigInfo		info;
 
-		eglu::queryConfigInfo(egl, display, config, &info);
+		eglu::queryCoreConfigInfo(egl, display, config, &info);
 
 		log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage;
 		EGLU_CHECK_MSG(egl, "before queries");
@@ -582,7 +582,7 @@
 		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
 		ConfigInfo							info;
 
-		eglu::queryConfigInfo(egl, display, config, &info);
+		eglu::queryCoreConfigInfo(egl, display, config, &info);
 
 		log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage;
 		EGLU_CHECK_MSG(egl, "before queries");
@@ -611,7 +611,7 @@
 		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
 		ConfigInfo							info;
 
-		eglu::queryConfigInfo(egl, display, config, &info);
+		eglu::queryCoreConfigInfo(egl, display, config, &info);
 
 		log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage;
 		EGLU_CHECK_MSG(egl, "before queries");
@@ -639,7 +639,7 @@
 		int				height	= 64;
 		ConfigInfo		info;
 
-		eglu::queryConfigInfo(egl, display, config, &info);
+		eglu::queryCoreConfigInfo(egl, display, config, &info);
 
 		log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage;
 		EGLU_CHECK_MSG(egl, "before queries");
diff --git a/modules/gles31/functional/es31fGeometryShaderTests.cpp b/modules/gles31/functional/es31fGeometryShaderTests.cpp
index 3926a8e..715c3ee 100644
--- a/modules/gles31/functional/es31fGeometryShaderTests.cpp
+++ b/modules/gles31/functional/es31fGeometryShaderTests.cpp
@@ -3947,7 +3947,7 @@
 
 void GeometryProgramQueryCase::init (void)
 {
-	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") && glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+	if (!(m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") || glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2))))
 		TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
 }
 
diff --git a/modules/gles31/functional/es31fNegativeFragmentApiTests.cpp b/modules/gles31/functional/es31fNegativeFragmentApiTests.cpp
index 0a5ad9e..1410aea 100644
--- a/modules/gles31/functional/es31fNegativeFragmentApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeFragmentApiTests.cpp
@@ -161,8 +161,8 @@
 {
 	glw::GLint maxDrawBuffers = -1;
 
-	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
-		throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
 
 	ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
 	ctx.beginSection("GL_INVALID_ENUM is generated if mode is not GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MAX or GL_MIN.");
@@ -181,8 +181,8 @@
 {
 	glw::GLint maxDrawBuffers = -1;
 
-	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
-		throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
 
 	ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
 	ctx.beginSection("GL_INVALID_ENUM is generated if modeRGB is not GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MAX or GL_MIN.");
@@ -229,8 +229,8 @@
 {
 	glw::GLint maxDrawBuffers = -1;
 
-	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
-		throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+	if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
 
 	ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
 	ctx.beginSection("GL_INVALID_ENUM is generated if either sfactor or dfactor is not an accepted value.");
@@ -251,8 +251,8 @@
 {
 	glw::GLint maxDrawBuffers = -1;
 
-	if (!glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
-		throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+	if (!glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
 
 	ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
 	ctx.beginSection("GL_INVALID_ENUM is generated if srcRGB, dstRGB, srcAlpha, or dstAlpha is not an accepted value.");
diff --git a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
index e33ecbf..64b3504 100644
--- a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
@@ -517,20 +517,24 @@
 	ctx.glGetProgramiv		(srcProgram.getProgram(), GL_LINK_STATUS,			&linkStatus);
 	ctx.getLog() << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
 	ctx.getLog() << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
-	TCU_CHECK(bufSize > 0);
-	binaryBuf.resize(bufSize);
-	ctx.glGetProgramBinary	(srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
-	ctx.expectError		(GL_NO_ERROR);
 
-	ctx.beginSection("GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
-	ctx.glProgramBinary		(dummyShader, binaryFormat, &binaryBuf[0], binaryLength);
-	ctx.expectError		(GL_INVALID_OPERATION);
-	ctx.endSection();
+	TCU_CHECK(bufSize >= 0);
+	if (bufSize > 0)
+	{
+		binaryBuf.resize(bufSize);
+		ctx.glGetProgramBinary	(srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
+		ctx.expectError			(GL_NO_ERROR);
 
-	ctx.beginSection("GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
-	ctx.glProgramBinary		(dstProgram, -1, &binaryBuf[0], binaryLength);
-	ctx.expectError		(GL_INVALID_ENUM);
-	ctx.endSection();
+		ctx.beginSection("GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
+		ctx.glProgramBinary		(dummyShader, binaryFormat, &binaryBuf[0], binaryLength);
+		ctx.expectError			(GL_INVALID_OPERATION);
+		ctx.endSection();
+
+		ctx.beginSection("GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
+		ctx.glProgramBinary		(dstProgram, -1, &binaryBuf[0], binaryLength);
+		ctx.expectError			(GL_INVALID_ENUM);
+		ctx.endSection();
+	}
 
 	ctx.glDeleteShader(dummyShader);
 	ctx.glDeleteProgram(dstProgram);
diff --git a/scripts/egl/str_util.py b/scripts/egl/str_util.py
index d00fe45..4372932 100644
--- a/scripts/egl/str_util.py
+++ b/scripts/egl/str_util.py
@@ -126,6 +126,21 @@
 		"ALPHA_FORMAT",
 		"COLORSPACE"
 		]),
+	("YuvOrder", [
+		"NONE",
+		"YUV_ORDER_YUV_EXT",
+		"YUV_ORDER_YVU_EXT",
+		"YUV_ORDER_YUYV_EXT",
+		"YUV_ORDER_UYVY_EXT",
+		"YUV_ORDER_YVYU_EXT",
+		"YUV_ORDER_VYUY_EXT",
+		"YUV_ORDER_AYUV_EXT",
+		]),
+	("YuvPlaneBpp", [
+		"YUV_PLANE_BPP_0_EXT",
+		"YUV_PLANE_BPP_8_EXT",
+		"YUV_PLANE_BPP_10_EXT",
+		]),
 	("SurfaceTarget",		["READ", "DRAW"]),
 
 	# ConfigAttrib values