Merge "Remove complex builtin function constant folding cases from mustpass"
diff --git a/android/cts/master/src/egl-failures.txt b/android/cts/master/src/egl-failures.txt
index 6f46bbb..1989fa5 100644
--- a/android/cts/master/src/egl-failures.txt
+++ b/android/cts/master/src/egl-failures.txt
@@ -303,97 +303,56 @@
 dEQP-EGL.functional.image.create.gles2_android_native_rgba8_read_pixels
 dEQP-EGL.functional.image.create.gles2_android_native_rgba8_depth_buffer
 dEQP-EGL.functional.image.modify.tex_rgb8_tex_subimage_rgb565
-dEQP-EGL.functional.image.modify.tex_rgb8_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.tex_rgb8_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.tex_rgb8_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.tex_rgb565_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.tex_rgb565_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.tex_rgb565_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.tex_rgba8_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.tex_rgba8_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.tex_rgba8_tex_subimage_rgba5_a1
 dEQP-EGL.functional.image.modify.tex_rgba8_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.tex_rgba5_a1_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.tex_rgba5_a1_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.tex_rgba5_a1_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.tex_rgba5_a1_tex_subimage_rgba5_a1
 dEQP-EGL.functional.image.modify.tex_rgba5_a1_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.tex_rgba5_a1_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.tex_rgba5_a1_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.tex_rgba5_a1_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgba5_a1
 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.tex_rgba4_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.tex_rgba4_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgba5_a1
 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_rgba4_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.renderbuffer_rgba4_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.renderbuffer_rgb5_a1_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.renderbuffer_rgb5_a1_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.renderbuffer_rgb5_a1_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.renderbuffer_rgb5_a1_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.renderbuffer_rgb565_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.renderbuffer_rgb565_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.renderbuffer_rgb565_tex_subimage_rgba4
-dEQP-EGL.functional.image.modify.renderbuffer_depth16_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.renderbuffer_depth16_tex_subimage_rgb565
-dEQP-EGL.functional.image.modify.renderbuffer_depth16_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.renderbuffer_depth16_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.renderbuffer_depth16_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.renderbuffer_depth16_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.renderbuffer_depth16_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.renderbuffer_depth16_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.renderbuffer_stencil_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.renderbuffer_stencil_tex_subimage_rgb565
-dEQP-EGL.functional.image.modify.renderbuffer_stencil_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.renderbuffer_stencil_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.renderbuffer_stencil_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.renderbuffer_stencil_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.renderbuffer_stencil_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.renderbuffer_stencil_renderbuffer_clear_stencil
 dEQP-EGL.functional.image.modify.android_native_rgb565_tex_subimage_rgb8
 dEQP-EGL.functional.image.modify.android_native_rgb565_tex_subimage_rgb565
-dEQP-EGL.functional.image.modify.android_native_rgb565_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.android_native_rgb565_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.android_native_rgb565_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.android_native_rgb565_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.android_native_rgb565_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.android_native_rgb565_renderbuffer_clear_stencil
 dEQP-EGL.functional.image.modify.android_native_rgb8_tex_subimage_rgb8
 dEQP-EGL.functional.image.modify.android_native_rgb8_tex_subimage_rgb565
-dEQP-EGL.functional.image.modify.android_native_rgb8_tex_subimage_rgba8
-dEQP-EGL.functional.image.modify.android_native_rgb8_tex_subimage_rgba5_a1
-dEQP-EGL.functional.image.modify.android_native_rgb8_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.android_native_rgb8_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.android_native_rgb8_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.android_native_rgb8_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.android_native_rgba4_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.android_native_rgba4_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.android_native_rgba4_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.android_native_rgba4_tex_subimage_rgba5_a1
 dEQP-EGL.functional.image.modify.android_native_rgba4_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.android_native_rgba4_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.android_native_rgba4_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.android_native_rgba4_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.android_native_rgb5_a1_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.android_native_rgb5_a1_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.android_native_rgb5_a1_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.android_native_rgb5_a1_tex_subimage_rgba5_a1
 dEQP-EGL.functional.image.modify.android_native_rgb5_a1_tex_subimage_rgba4
 dEQP-EGL.functional.image.modify.android_native_rgb5_a1_renderbuffer_clear_color
 dEQP-EGL.functional.image.modify.android_native_rgb5_a1_renderbuffer_clear_depth
 dEQP-EGL.functional.image.modify.android_native_rgb5_a1_renderbuffer_clear_stencil
-dEQP-EGL.functional.image.modify.android_native_rgba8_tex_subimage_rgb8
-dEQP-EGL.functional.image.modify.android_native_rgba8_tex_subimage_rgb565
 dEQP-EGL.functional.image.modify.android_native_rgba8_tex_subimage_rgba8
 dEQP-EGL.functional.image.modify.android_native_rgba8_tex_subimage_rgba5_a1
 dEQP-EGL.functional.image.modify.android_native_rgba8_tex_subimage_rgba4
diff --git a/framework/platform/android/tcuAndroidInternals.cpp b/framework/platform/android/tcuAndroidInternals.cpp
index d825b85..368f3e0 100644
--- a/framework/platform/android/tcuAndroidInternals.cpp
+++ b/framework/platform/android/tcuAndroidInternals.cpp
@@ -22,6 +22,8 @@
  *//*--------------------------------------------------------------------*/
 
 #include "tcuAndroidInternals.hpp"
+#include "deMemory.h"
+#include "deStringUtil.hpp"
 
 namespace tcu
 {
@@ -51,20 +53,200 @@
 	setFuncPtr(gb.getNativeBuffer,	m_library,	"_ZNK7android13GraphicBuffer15getNativeBufferEv");
 	setFuncPtr(gb.lock,				m_library,	"_ZN7android13GraphicBuffer4lockEjPPv");
 	setFuncPtr(gb.unlock,			m_library,	"_ZN7android13GraphicBuffer6unlockEv");
+	setFuncPtr(gb.initCheck,		m_library,	"_ZNK7android13GraphicBuffer9initCheckEv");
 }
 
 #define GRAPHICBUFFER_SIZE 1024 // Hopefully enough
 
+typedef void (*GenericFptr)();
+
+//! call constructor with 4 arguments
+template <typename RT, typename T1, typename T2, typename T3, typename T4>
+RT* callConstructor4 (GenericFptr fptr, void* memory, size_t memorySize, T1 param1, T2 param2, T3 param3, T4 param4)
+{
+	DE_UNREF(memorySize);
+
+#if (DE_CPU == DE_CPU_ARM)
+	// C1 constructors return pointer
+	typedef RT* (*ABIFptr)(void*, T1, T2, T3, T4);
+	(void)((ABIFptr)fptr)(memory, param1, param2, param3, param4);
+	return reinterpret_cast<RT*>(memory);
+#elif (DE_CPU == DE_CPU_ARM_64)
+	// C1 constructors return void
+	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
+	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
+	return reinterpret_cast<RT*>(memory);
+#elif (DE_CPU == DE_CPU_X86)
+	// ctor returns void
+	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
+	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
+	return reinterpret_cast<RT*>(memory);
+#elif (DE_CPU == DE_CPU_X86_64)
+	// ctor returns void
+	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
+	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
+	return reinterpret_cast<RT*>(memory);
+#else
+	TCU_THROW(NotSupportedError, "ABI not supported");
+	return DE_NULL;
+#endif
+}
+
+template <typename T>
+void callDestructor (GenericFptr fptr, T* obj)
+{
+#if (DE_CPU == DE_CPU_ARM)
+	// D1 destructor returns ptr
+	typedef void* (*ABIFptr)(T* obj);
+	(void)((ABIFptr)fptr)(obj);
+#elif (DE_CPU == DE_CPU_ARM_64)
+	// D1 destructor returns void
+	typedef void (*ABIFptr)(T* obj);
+	((ABIFptr)fptr)(obj);
+#elif (DE_CPU == DE_CPU_X86)
+	// dtor returns void
+	typedef void (*ABIFptr)(T* obj);
+	((ABIFptr)fptr)(obj);
+#elif (DE_CPU == DE_CPU_X86_64)
+	// dtor returns void
+	typedef void (*ABIFptr)(T* obj);
+	((ABIFptr)fptr)(obj);
+#else
+	TCU_THROW(NotSupportedError, "ABI not supported");
+#endif
+}
+
+template<typename T1, typename T2>
+T1* pointerToOffset (T2* ptr, size_t bytes)
+{
+	return reinterpret_cast<T1*>((deUint8*)ptr + bytes);
+}
+
+static android::android_native_base_t* getAndroidNativeBase (android::GraphicBuffer* gb)
+{
+	// \note: assuming Itanium ABI
+	return pointerToOffset<android::android_native_base_t>(gb, 2 * DE_PTR_SIZE);
+}
+
+//! android_native_base_t::magic for ANativeWindowBuffer
+static deInt32 getExpectedNativeBufferVersion (void)
+{
+#if (DE_PTR_SIZE == 4)
+	return 96;
+#elif (DE_PTR_SIZE == 8)
+	return 168;
+#else
+#	error Invalid DE_PTR_SIZE
+#endif
+}
+
+//! access android_native_base_t::magic
+static deUint32 getNativeBaseMagic (android::android_native_base_t* base)
+{
+	return *pointerToOffset<deUint32>(base, 0);
+}
+
+//! access android_native_base_t::version
+static deUint32 getNativeBaseVersion (android::android_native_base_t* base)
+{
+	return *pointerToOffset<deInt32>(base, 4);
+}
+
+//! access android_native_base_t::incRef
+static NativeBaseFunctions::incRefFunc getNativeBaseIncRefFunc (android::android_native_base_t* base)
+{
+	return *pointerToOffset<NativeBaseFunctions::incRefFunc>(base, 8 + DE_PTR_SIZE*4);
+}
+
+//! access android_native_base_t::decRef
+static NativeBaseFunctions::decRefFunc getNativeBaseDecRefFunc (android::android_native_base_t* base)
+{
+	return *pointerToOffset<NativeBaseFunctions::decRefFunc>(base, 8 + DE_PTR_SIZE*5);
+}
+
+static android::GraphicBuffer* createGraphicBuffer (const GraphicBufferFunctions& functions, NativeBaseFunctions& baseFunctions, deUint32 w, deUint32 h, PixelFormat format, deUint32 usage)
+{
+	// \note: Hopefully uses the same allocator as libui
+	void* const memory = deMalloc(GRAPHICBUFFER_SIZE);
+	if (memory == DE_NULL)
+		TCU_THROW(ResourceError, "Could not alloc for GraphicBuffer");
+	else
+	{
+		try
+		{
+			android::GraphicBuffer* const			gb			= callConstructor4<android::GraphicBuffer, deUint32, deUint32, PixelFormat, deUint32>(functions.constructor,
+																																					  memory,
+																																					  GRAPHICBUFFER_SIZE,
+																																					  w,
+																																					  h,
+																																					  format,
+																																					  usage);
+			android::android_native_base_t* const	base		= getAndroidNativeBase(gb);
+			status_t								ctorStatus	= functions.initCheck(gb);
+
+			if (ctorStatus)
+			{
+				// ctor failed
+				callDestructor<android::GraphicBuffer>(functions.destructor, gb);
+				TCU_THROW(NotSupportedError, ("GraphicBuffer ctor failed, initCheck returned " + de::toString(ctorStatus)).c_str());
+			}
+
+			// check object layout
+			{
+				const deUint32 magic		= getNativeBaseMagic(base);
+				const deUint32 bufferMagic	= 0x5f626672u; // "_bfr"
+
+				if (magic != bufferMagic)
+					TCU_THROW(NotSupportedError, "GraphicBuffer layout unexpected");
+			}
+
+			// check object version
+			{
+				const deInt32 version			= getNativeBaseVersion(base);
+				const deInt32 expectedVersion	= getExpectedNativeBufferVersion();
+
+				if (version != expectedVersion)
+					TCU_THROW(NotSupportedError, "GraphicBuffer version unexpected");
+			}
+
+			// locate refcounting functions
+
+			if (!baseFunctions.incRef || !baseFunctions.decRef)
+			{
+				baseFunctions.incRef = getNativeBaseIncRefFunc(base);
+				baseFunctions.decRef = getNativeBaseDecRefFunc(base);
+			}
+
+			// take the initial reference and return
+			baseFunctions.incRef(base);
+			return gb;
+		}
+		catch (...)
+		{
+			deFree(memory);
+			throw;
+		}
+	}
+}
+
 GraphicBuffer::GraphicBuffer (const LibUI& lib, deUint32 width, deUint32 height, PixelFormat format, deUint32 usage)
 	: m_functions	(lib.getFunctions().graphicBuffer)
-	, m_memory		(GRAPHICBUFFER_SIZE) // vector<char> (new char[]) is max-aligned
-	, m_impl		(m_functions.constructor(&m_memory.front(), width, height, format, usage))
+	, m_impl		(DE_NULL)
 {
+	m_baseFunctions.incRef = DE_NULL;
+	m_baseFunctions.decRef = DE_NULL;
+
+	// \note createGraphicBuffer updates m_baseFunctions
+	m_impl = createGraphicBuffer(m_functions, m_baseFunctions, width, height, format, usage);
 }
 
 GraphicBuffer::~GraphicBuffer (void)
 {
-	m_functions.destructor(m_impl);
+	if (m_impl && m_baseFunctions.decRef)
+	{
+		m_baseFunctions.decRef(getAndroidNativeBase(m_impl));
+		m_impl = DE_NULL;
+	}
 }
 
 status_t GraphicBuffer::lock (deUint32 usage, void** vaddr)
diff --git a/framework/platform/android/tcuAndroidInternals.hpp b/framework/platform/android/tcuAndroidInternals.hpp
index e6754c6..1d7d231 100644
--- a/framework/platform/android/tcuAndroidInternals.hpp
+++ b/framework/platform/android/tcuAndroidInternals.hpp
@@ -35,6 +35,7 @@
 namespace android
 {
 class GraphicBuffer;
+class android_native_base_t;
 }
 
 namespace tcu
@@ -96,17 +97,28 @@
 // ui/GraphicBuffer.h
 struct GraphicBufferFunctions
 {
-	typedef android::GraphicBuffer*	(*constructorFunc)		(void* memory, deUint32 w, deUint32 h, PixelFormat format, deUint32 usage);
-	typedef void*					(*destructorFunc)		(android::GraphicBuffer* buffer);
+	typedef void					(*genericFunc)			();
+	typedef status_t				(*initCheckFunc)		(android::GraphicBuffer* buffer);
 	typedef status_t				(*lockFunc)				(android::GraphicBuffer* buffer, deUint32 usage, void** vaddr);
 	typedef status_t				(*unlockFunc)			(android::GraphicBuffer* buffer);
 	typedef ANativeWindowBuffer*	(*getNativeBufferFunc)	(const android::GraphicBuffer* buffer);
 
-	constructorFunc					constructor;
-	destructorFunc					destructor;
+	genericFunc						constructor;
+	genericFunc						destructor;
 	lockFunc						lock;
 	unlockFunc						unlock;
 	getNativeBufferFunc				getNativeBuffer;
+	initCheckFunc					initCheck;
+};
+
+// system/window.h
+struct NativeBaseFunctions
+{
+	typedef void	(*incRefFunc)			(android::android_native_base_t* base);
+	typedef void	(*decRefFunc)			(android::android_native_base_t* base);
+
+	incRefFunc		incRef;
+	decRefFunc		decRef;
 };
 
 struct LibUIFunctions
@@ -166,7 +178,7 @@
 
 private:
 	const GraphicBufferFunctions&	m_functions;
-	std::vector<deUint8>			m_memory;
+	NativeBaseFunctions				m_baseFunctions;
 	android::GraphicBuffer*			m_impl;
 };
 
diff --git a/modules/egl/teglAndroidUtil.cpp b/modules/egl/teglAndroidUtil.cpp
index e79b58e..64cbe9b 100644
--- a/modules/egl/teglAndroidUtil.cpp
+++ b/modules/egl/teglAndroidUtil.cpp
@@ -51,9 +51,9 @@
 
 #if (DE_OS != DE_OS_ANDROID)
 
-MovePtr<ImageSource> createAndroidNativeImageSource	(GLenum)
+MovePtr<ImageSource> createAndroidNativeImageSource	(GLenum format)
 {
-	return createUnsupportedImageSource("Not Android platform");
+	return createUnsupportedImageSource("Not Android platform", format);
 }
 
 #else // DE_OS == DE_OS_ANDROID
@@ -105,6 +105,7 @@
 	MovePtr<ClientBuffer>	createBuffer 				(const glw::Functions&, Texture2D*) const;
 	string					getRequiredExtension		(void) const { return "EGL_ANDROID_image_native_buffer"; }
 	EGLImageKHR				createImage					(const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
+	GLenum					getFormat					(void) const { return m_format; }
 
 protected:
 	GLenum					m_format;
@@ -158,7 +159,7 @@
 	}
 	catch (std::runtime_error& exc)
 	{
-		return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what());
+		return createUnsupportedImageSource(string("Android native buffers unsupported: ") + exc.what(), format);
 	}
 }
 
diff --git a/modules/egl/teglImageFormatTests.cpp b/modules/egl/teglImageFormatTests.cpp
index 1e06500..8cfc2da 100644
--- a/modules/egl/teglImageFormatTests.cpp
+++ b/modules/egl/teglImageFormatTests.cpp
@@ -181,6 +181,7 @@
 								Create					(MovePtr<ImageSource> imgSource) : m_imgSource(imgSource) {}
 		string					getRequiredExtension	(void) const { return m_imgSource->getRequiredExtension(); }
 		bool					invokeGLES2				(GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
+		glw::GLenum				getFormat				(void) const { return m_imgSource->getFormat(); }
 
 	private:
 		UniquePtr<ImageSource>	m_imgSource;
@@ -209,6 +210,7 @@
 	public:
 							ModifyTexSubImage		(GLenum format, GLenum type) : m_format(format), m_type(type) {}
 		bool				invokeGLES2				(GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
+		GLenum				getFormat				(void) const { return m_format; }
 
 	private:
 		GLenum				m_format;
@@ -1117,6 +1119,63 @@
 	m_modifyActions.add("renderbuffer_clear_stencil",	MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(78)));
 }
 
+bool isCompatibleFormats (GLenum createFormat, GLenum modifyFormat)
+{
+	switch (createFormat)
+	{
+		case GL_RGB:
+		case GL_RGB8:
+		case GL_RGB565:
+			if (modifyFormat == GL_RGB
+				|| modifyFormat == GL_RGB8
+				|| modifyFormat == GL_RGB565)
+				return true;
+			else
+				return false;
+
+		case GL_RGBA:
+		case GL_RGBA4:
+		case GL_RGBA8:
+		case GL_RGB5_A1:
+			if (modifyFormat == GL_RGBA
+				|| modifyFormat == GL_RGBA8
+				|| modifyFormat == GL_RGBA4
+				|| modifyFormat == GL_RGB5_A1)
+				return true;
+			else
+				return false;
+
+		case GL_DEPTH_COMPONENT16:
+		case GL_STENCIL_INDEX8:
+			return false;
+
+		default:
+			DE_ASSERT(false);
+			return false;
+	}
+}
+
+bool isCompatibleCreateAndModifyActions (const Action& create, const Action& modify)
+{
+	if (const GLES2ImageApi::Create* gles2Create = dynamic_cast<const GLES2ImageApi::Create*>(&create))
+	{
+		const GLenum createFormat = gles2Create->getFormat();
+
+		if (const GLES2ImageApi::ModifyTexSubImage* gles2TexSubImageModify = dynamic_cast<const GLES2ImageApi::ModifyTexSubImage*>(&modify))
+		{
+			const GLenum modifyFormat  = gles2TexSubImageModify->getFormat();
+
+			return isCompatibleFormats(createFormat, modifyFormat);
+		}
+
+		return true;
+	}
+	else
+		DE_ASSERT(false);
+
+	return false;
+}
+
 void ModifyTests::init (void)
 {
 	addCreateTexture2DActions("tex_");
@@ -1131,6 +1190,10 @@
 		for (int modifyNdx = 0; modifyNdx < m_modifyActions.size(); modifyNdx++)
 		{
 			LabeledAction& modifyAction = m_modifyActions[modifyNdx];
+
+			if (!isCompatibleCreateAndModifyActions(*createAction.action, *modifyAction.action))
+				continue;
+
 			TestSpec spec;
 			spec.name = createAction.label + "_" + modifyAction.label;
 			spec.desc = "gles2_tex_sub_image";
diff --git a/modules/egl/teglImageUtil.cpp b/modules/egl/teglImageUtil.cpp
index f4b5dbf..badb9ab 100644
--- a/modules/egl/teglImageUtil.cpp
+++ b/modules/egl/teglImageUtil.cpp
@@ -180,6 +180,7 @@
 public:
 							TextureImageSource	(GLenum format, GLenum type, bool useTexLevel0) : m_format(format), m_type(type), m_useTexLevel0(useTexLevel0) {}
 	MovePtr<ClientBuffer>	createBuffer		(const glw::Functions& gl, Texture2D* reference) const;
+	GLenum					getFormat			(void) const { return m_format; }
 
 protected:
 	AttribMap				getCreateAttribs	(void) const;
@@ -304,6 +305,7 @@
 
 	string					getRequiredExtension	(void) const 	{ return "EGL_KHR_gl_renderbuffer_image"; }
 	MovePtr<ClientBuffer>	createBuffer			(const glw::Functions& gl, Texture2D* reference) const;
+	GLenum					getFormat				(void) const { return m_format; }
 
 protected:
 	EGLenum					getSource				(void) const	{ return EGL_GL_RENDERBUFFER_KHR; }
@@ -397,13 +399,15 @@
 class UnsupportedImageSource : public ImageSource
 {
 public:
-							UnsupportedImageSource	(const string& message) : m_message(message) {}
+							UnsupportedImageSource	(const string& message, GLenum format) : m_message(message), m_format(format) {}
 	string					getRequiredExtension	(void) const { fail(); return ""; }
 	MovePtr<ClientBuffer>	createBuffer			(const glw::Functions&, tcu::Texture2D*) const { fail(); return de::MovePtr<ClientBuffer>(); }
 	EGLImageKHR				createImage				(const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
+	GLenum					getFormat				(void) const { return m_format; }
 
 private:
 	const string			m_message;
+	GLenum					m_format;
 
 	void					fail					(void) const { TCU_THROW(NotSupportedError, m_message.c_str()); }
 };
@@ -427,9 +431,9 @@
 	return MovePtr<ImageSource>(new RenderbufferImageSource(format));
 }
 
-MovePtr<ImageSource> createUnsupportedImageSource (const string& message)
+MovePtr<ImageSource> createUnsupportedImageSource (const string& message, GLenum format)
 {
-	return MovePtr<ImageSource>(new UnsupportedImageSource(message));
+	return MovePtr<ImageSource>(new UnsupportedImageSource(message, format));
 }
 
 } // Image
diff --git a/modules/egl/teglImageUtil.hpp b/modules/egl/teglImageUtil.hpp
index 7a2723c..aeb6669 100644
--- a/modules/egl/teglImageUtil.hpp
+++ b/modules/egl/teglImageUtil.hpp
@@ -74,11 +74,12 @@
 	virtual std::string					getRequiredExtension(void) const = 0;
 	virtual de::MovePtr<ClientBuffer>	createBuffer		(const glw::Functions& gl, tcu::Texture2D* reference = DE_NULL) const = 0;
 	virtual eglw::EGLImageKHR			createImage			(const eglw::Library& egl, eglw::EGLDisplay dpy, eglw::EGLContext ctx, eglw::EGLClientBuffer clientBuffer) const = 0;
+	virtual glw::GLenum					getFormat			(void) const = 0;
 };
 
 de::MovePtr<ImageSource> createTextureImageSource			(eglw::EGLenum source, glw::GLenum format, glw::GLenum type, bool useTexLevel0 = false);
 de::MovePtr<ImageSource> createRenderbufferImageSource		(glw::GLenum format);
-de::MovePtr<ImageSource> createUnsupportedImageSource		(const std::string& message);
+de::MovePtr<ImageSource> createUnsupportedImageSource		(const std::string& message, glw::GLenum format);
 
 } // Image
 } // egl
diff --git a/modules/egl/teglNegativeApiTests.cpp b/modules/egl/teglNegativeApiTests.cpp
index 3503c86..98e3f94 100644
--- a/modules/egl/teglNegativeApiTests.cpp
+++ b/modules/egl/teglNegativeApiTests.cpp
@@ -681,18 +681,6 @@
 			expectError(EGL_BAD_CONFIG);
 
 			log << TestLog::EndSection;
-
-			log << TestLog::Section("Test3", "EGL_BAD_NATIVE_WINDOW may be generated if native_window is not a valid native window");
-
-			// Any window-capable config.
-			EGLConfig windowConfig;
-			if (getConfig(&windowConfig, FilterList() << surfaceBits<EGL_WINDOW_BIT>))
-			{
-				expectNoSurface(eglCreateWindowSurface(display, windowConfig, DE_NULL, s_emptyAttribList));
-				expectError(EGL_BAD_NATIVE_WINDOW);
-			}
-
-			log << TestLog::EndSection;
 		});
 
 	TEGL_ADD_API_CASE(destroy_context, "eglDestroyContext() negative tests",
diff --git a/modules/egl/teglRenderTests.cpp b/modules/egl/teglRenderTests.cpp
index 19a970b..81a32d7 100644
--- a/modules/egl/teglRenderTests.cpp
+++ b/modules/egl/teglRenderTests.cpp
@@ -125,6 +125,22 @@
 	int				stencilRef;
 };
 
+static bool isANarrowScreenSpaceTriangle (const tcu::Vec4& p0, const tcu::Vec4& p1, const tcu::Vec4& p2)
+{
+	// to clip space
+	const tcu::Vec2	csp0 				= p0.swizzle(0, 1) / p0.w();
+	const tcu::Vec2	csp1 				= p1.swizzle(0, 1) / p1.w();
+	const tcu::Vec2	csp2 				= p2.swizzle(0, 1) / p2.w();
+
+	const tcu::Vec2	e01					= (csp1 - csp0);
+	const tcu::Vec2	e02					= (csp2 - csp0);
+
+	const float		minimumVisibleArea	= 0.4f; // must cover at least 10% of the surface
+	const float		visibleArea			= de::abs(e01.x() * e02.y() - e02.x() * e01.y()) * 0.5f;
+
+	return visibleArea < minimumVisibleArea;
+}
+
 void randomizeDrawOp (de::Random& rnd, DrawPrimitiveOp& drawOp)
 {
 	const int	minStencilRef	= 0;
@@ -173,6 +189,34 @@
 				color.z()		= rnd.getFloat(minRGB, maxRGB);
 				color.w()		= rnd.getFloat(minAlpha, maxAlpha);
 			}
+
+			// avoid generating narrow triangles
+			{
+				const int	maxAttempts	= 40;
+				int			numAttempts	= 0;
+				tcu::Vec4&	p0			= drawOp.positions[triNdx*3 + 0];
+				tcu::Vec4&	p1			= drawOp.positions[triNdx*3 + 1];
+				tcu::Vec4&	p2			= drawOp.positions[triNdx*3 + 2];
+
+				while (isANarrowScreenSpaceTriangle(p0, p1, p2))
+				{
+					p1.x()	= cx + rnd.getFloat(-maxTriOffset, maxTriOffset);
+					p1.y()	= cy + rnd.getFloat(-maxTriOffset, maxTriOffset);
+					p1.z()	= rnd.getFloat(minDepth, maxDepth);
+					p1.w()	= 1.0f;
+
+					p2.x()	= cx + rnd.getFloat(-maxTriOffset, maxTriOffset);
+					p2.y()	= cy + rnd.getFloat(-maxTriOffset, maxTriOffset);
+					p2.z()	= rnd.getFloat(minDepth, maxDepth);
+					p2.w()	= 1.0f;
+
+					if (++numAttempts > maxAttempts)
+					{
+						DE_ASSERT(false);
+						break;
+					}
+				}
+			}
 		}
 	}
 	else
@@ -535,6 +579,8 @@
 			DE_ASSERT(false);
 	}
 
+	gl.disable(GL_DITHER);
+
 	gl.vertexAttribPointer(gles2Program.getPositionLoc(), 4, GL_FLOAT, GL_FALSE, 0, &drawOp.positions[0]);
 	gl.vertexAttribPointer(gles2Program.getColorLoc(), 4, GL_FLOAT, GL_FALSE, 0, &drawOp.colors[0]);