Merge aosp/upstream-vulkan-cts-1.0-dev into aosp/deqp-dev

Change-Id: Id72fd820e5ce49e72e0e14809eb92fcebb6fb1d7
diff --git a/android/cts/master/src/vk-waivers.txt b/android/cts/master/src/vk-waivers.txt
new file mode 100644
index 0000000..1b9e7d8
--- /dev/null
+++ b/android/cts/master/src/vk-waivers.txt
@@ -0,0 +1,50 @@
+#
+# VK-GL-CTS Issue #336
+#
+# This occurs on some versions of Imagination Technologies G6200, G6230, G6400, and G6430
+# Rogue Series 6 GPU's.
+#
+# The affected GPU's are unable to correctly filter CEM corners with F32 textures, this
+# includes the ability to gather texels for texel gather instructions.
+#
+# An application using gather on an F32 texture would obtain incorrect texel values around
+# the corners of the cubemap.
+#
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.sparse_clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.sparse_repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.sparse_mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.sparse_clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.sparse_repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.sparse_mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.sparse_clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.sparse_repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.sparse_mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.sparse_clamp_to_edge_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.sparse_repeat_mirrored_repeat
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.sparse_mirrored_repeat_clamp_to_edge
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_linear_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_linear_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_nearest_mipmap_nearest_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_nearest_mipmap_nearest_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_nearest_mipmap_linear_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_nearest_mipmap_linear_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_linear_mipmap_nearest_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_linear_mipmap_nearest_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_linear_mipmap_linear_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_linear_mipmap_linear_mag_linear
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.level_1
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.sparse_level_1
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.level_2
+dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.sparse_level_2
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index 974700c..b1c2a0d 100644
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
@@ -145739,30 +145739,6 @@
 dEQP-VK.glsl.texture_gather.basic.cube.rgba8i.base_level.sparse_level_1
 dEQP-VK.glsl.texture_gather.basic.cube.rgba8i.base_level.level_2
 dEQP-VK.glsl.texture_gather.basic.cube.rgba8i.base_level.sparse_level_2
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.sparse_clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.sparse_repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_less.sparse_mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.sparse_clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.sparse_repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_pot.compare_greater.sparse_mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.sparse_clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.sparse_repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_less.sparse_mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.sparse_clamp_to_edge_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.sparse_repeat_mirrored_repeat
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.size_npot.compare_greater.sparse_mirrored_repeat_clamp_to_edge
 dEQP-VK.glsl.texture_gather.basic.cube.depth32f.no_corners.size_pot.compare_less.clamp_to_edge_repeat
 dEQP-VK.glsl.texture_gather.basic.cube.depth32f.no_corners.size_pot.compare_less.sparse_clamp_to_edge_repeat
 dEQP-VK.glsl.texture_gather.basic.cube.depth32f.no_corners.size_pot.compare_less.repeat_mirrored_repeat
@@ -145787,20 +145763,6 @@
 dEQP-VK.glsl.texture_gather.basic.cube.depth32f.no_corners.size_npot.compare_greater.sparse_repeat_mirrored_repeat
 dEQP-VK.glsl.texture_gather.basic.cube.depth32f.no_corners.size_npot.compare_greater.mirrored_repeat_clamp_to_edge
 dEQP-VK.glsl.texture_gather.basic.cube.depth32f.no_corners.size_npot.compare_greater.sparse_mirrored_repeat_clamp_to_edge
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_linear_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_linear_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_nearest_mipmap_nearest_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_nearest_mipmap_nearest_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_nearest_mipmap_linear_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_nearest_mipmap_linear_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_linear_mipmap_nearest_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_linear_mipmap_nearest_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.min_linear_mipmap_linear_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.filter_mode.sparse_min_linear_mipmap_linear_mag_linear
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.level_1
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.sparse_level_1
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.level_2
-dEQP-VK.glsl.texture_gather.basic.cube.depth32f.base_level.sparse_level_2
 dEQP-VK.glsl.texture_gather.offset.min_required_offset.2d.rgba8.size_pot.clamp_to_edge_repeat
 dEQP-VK.glsl.texture_gather.offset.min_required_offset.2d.rgba8.size_pot.sparse_clamp_to_edge_repeat
 dEQP-VK.glsl.texture_gather.offset.min_required_offset.2d.rgba8.size_pot.repeat_mirrored_repeat
diff --git a/framework/common/tcuApp.cpp b/framework/common/tcuApp.cpp
index 075d505..d99617f 100644
--- a/framework/common/tcuApp.cpp
+++ b/framework/common/tcuApp.cpp
@@ -209,10 +209,10 @@
 	return m_testExecutor->getStatus();
 }
 
-void App::onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr)
+void App::onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr, qpTimeoutReason reason)
 {
 	DE_UNREF(watchDog);
-	static_cast<App*>(userPtr)->onWatchdogTimeout();
+	static_cast<App*>(userPtr)->onWatchdogTimeout(reason);
 }
 
 void App::onCrash (qpCrashHandler* crashHandler, void* userPtr)
@@ -221,7 +221,7 @@
 	static_cast<App*>(userPtr)->onCrash();
 }
 
-void App::onWatchdogTimeout (void)
+void App::onWatchdogTimeout (qpTimeoutReason reason)
 {
 	if (!m_crashLock.tryLock() || m_crashed)
 		return; // In crash handler already.
@@ -229,7 +229,7 @@
 	m_crashed = true;
 
 	m_testCtx->getLog().terminateCase(QP_TEST_RESULT_TIMEOUT);
-	die("Watchdog timer timeout");
+	die("Watchdog timer timeout for %s", (reason == QP_TIMEOUT_REASON_INTERVAL_LIMIT ? "touch interval" : "total time"));
 }
 
 static void writeCrashToLog (void* userPtr, const char* infoString)
diff --git a/framework/common/tcuApp.hpp b/framework/common/tcuApp.hpp
index b6e0db1..7ee007d 100644
--- a/framework/common/tcuApp.hpp
+++ b/framework/common/tcuApp.hpp
@@ -71,10 +71,10 @@
 protected:
 	void					cleanup				(void);
 
-	void					onWatchdogTimeout	(void);
+	void					onWatchdogTimeout	(qpTimeoutReason reason);
 	void					onCrash				(void);
 
-	static void				onWatchdogTimeout	(qpWatchDog* watchDog, void* userPtr);
+	static void				onWatchdogTimeout	(qpWatchDog* watchDog, void* userPtr, qpTimeoutReason reason);
 	static void				onCrash				(qpCrashHandler* crashHandler, void* userPtr);
 
 	Platform&				m_platform;
diff --git a/framework/qphelper/qpTestLog.c b/framework/qphelper/qpTestLog.c
index 5e60797..00603c1 100644
--- a/framework/qphelper/qpTestLog.c
+++ b/framework/qphelper/qpTestLog.c
@@ -551,31 +551,6 @@
 }
 
 /*--------------------------------------------------------------------*//*!
- * \brief Write a message to output log
- * \param log		qpTestLog instance
- * \param format	Format string of message
- * \param ...		Parameters for message
- * \return true if ok, false otherwise
- *//*--------------------------------------------------------------------*/
-deBool qpTestLog_writeMessage (qpTestLog* log, const char* format, ...)
-{
-	char	buffer[1024];
-	va_list	args;
-
-	/* \todo [petri] Handle buffer overflows! */
-
-	va_start(args, format);
-	buffer[DE_LENGTH_OF_ARRAY(buffer) - 1] = 0;
-	vsnprintf(buffer, sizeof(buffer), format, args);
-	va_end(args);
-
-	printf("%s\n", buffer);
-
-	/* <Text>text</Text> */
-	return qpTestLog_writeKeyValuePair(log, "Text", DE_NULL, DE_NULL, DE_NULL, QP_KEY_TAG_LAST, buffer);
-}
-
-/*--------------------------------------------------------------------*//*!
  * \brief Write key-value-pair into log
  * \param log			qpTestLog instance
  * \param name			Unique identifier for entry
@@ -604,8 +579,6 @@
 	char tmpString[64];
 	int64ToString(value, tmpString);
 
-	printf("%s = %lld %s\n", description, (signed long long)value, unit ? unit : "");
-
 	/* <Number Name="name" Description="description" Tag="Performance">15</Number> */
 	return qpTestLog_writeKeyValuePair(log, "Number", name, description, unit, tag, tmpString);
 }
@@ -624,8 +597,6 @@
 	char tmpString[64];
 	floatToString(value, tmpString, sizeof(tmpString));
 
-	printf("%s = %f %s\n", description, value, unit ? unit : "");
-
 	/* <Number Name="name" Description="description" Tag="Performance">15</Number> */
 	return qpTestLog_writeKeyValuePair(log, "Number", name, description, unit, tag, tmpString);
 }
diff --git a/framework/qphelper/qpTestLog.h b/framework/qphelper/qpTestLog.h
index 807716e..d57f3c1 100644
--- a/framework/qphelper/qpTestLog.h
+++ b/framework/qphelper/qpTestLog.h
@@ -195,7 +195,6 @@
 deBool			qpTestLog_endCase				(qpTestLog* log, qpTestResult result, const char* description);
 deBool			qpTestLog_terminateCase			(qpTestLog* log, qpTestResult result);
 
-deBool			qpTestLog_writeMessage			(qpTestLog* log, const char* format, ...) DE_PRINTF_FUNC_ATTR(2,3);
 deBool			qpTestLog_startSection			(qpTestLog* log, const char* name, const char* description);
 deBool			qpTestLog_endSection			(qpTestLog* log);
 deBool			qpTestLog_writeText				(qpTestLog* log, const char* name, const char* description, qpKeyValueTag tag, const char* value);
diff --git a/framework/qphelper/qpWatchDog.c b/framework/qphelper/qpWatchDog.c
index 84957b8..c691aa2 100644
--- a/framework/qphelper/qpWatchDog.c
+++ b/framework/qphelper/qpWatchDog.c
@@ -69,11 +69,14 @@
 		deUint64	curTime					= deGetMicroseconds();
 		int			totalSecondsPassed		= (int)((curTime - dog->resetTime) / 1000000ull);
 		int			secondsSinceLastTouch	= (int)((curTime - dog->lastTouchTime) / 1000000ull);
+		deBool		overIntervalLimit		= secondsSinceLastTouch > dog->intervalTimeLimit;
+		deBool		overTotalLimit			= totalSecondsPassed > dog->totalTimeLimit;
 
-		if ((secondsSinceLastTouch > dog->intervalTimeLimit) || (totalSecondsPassed > dog->totalTimeLimit))
+		if (overIntervalLimit || overTotalLimit)
 		{
+		    qpTimeoutReason reason = overTotalLimit ? QP_TIMEOUT_REASON_TOTAL_LIMIT : QP_TIMEOUT_REASON_INTERVAL_LIMIT;
 			DBGPRINT(("watchDogThreadFunc(): call timeout func\n"));
-			dog->timeOutFunc(dog, dog->timeOutUserPtr);
+			dog->timeOutFunc(dog, dog->timeOutUserPtr, reason);
 			break;
 		}
 
diff --git a/framework/qphelper/qpWatchDog.h b/framework/qphelper/qpWatchDog.h
index 6ac8f6a..6247e66 100644
--- a/framework/qphelper/qpWatchDog.h
+++ b/framework/qphelper/qpWatchDog.h
@@ -27,7 +27,15 @@
 
 typedef struct qpWatchDog_s	qpWatchDog;
 
-typedef void		(*qpWatchDogFunc)		(qpWatchDog* dog, void* userPtr);
+typedef enum qpTimeoutReason_e
+{
+	QP_TIMEOUT_REASON_INTERVAL_LIMIT = 0,
+	QP_TIMEOUT_REASON_TOTAL_LIMIT,
+
+	QP_TIMEOUT_REASON_LAST
+} qpTimeoutReason;
+
+typedef void		(*qpWatchDogFunc)		(qpWatchDog* dog, void* userPtr, qpTimeoutReason reason);
 
 DE_BEGIN_EXTERN_C
 
diff --git a/modules/gles2/functional/es2fDitheringTests.cpp b/modules/gles2/functional/es2fDitheringTests.cpp
index faf9cb0..96d7baa 100644
--- a/modules/gles2/functional/es2fDitheringTests.cpp
+++ b/modules/gles2/functional/es2fDitheringTests.cpp
@@ -317,11 +317,12 @@
 	{
 		const int	increasingDirectionSize	= isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth();
 		const int	constantDirectionSize	= isVerticallyIncreasing ? renderedImg.getWidth() : renderedImg.getHeight();
-		bool		colorHasChanged			= false;
 
 		for (int incrPos = 0; incrPos < increasingDirectionSize; incrPos++)
 		{
-			tcu::RGBA prevConstantDirectionPix;
+			bool		colorHasChanged			= false;
+			tcu::RGBA	prevConstantDirectionPix;
+
 			for (int constPos = 0; constPos < constantDirectionSize; constPos++)
 			{
 				const int			x		= isVerticallyIncreasing ? constPos : incrPos;
diff --git a/modules/gles3/functional/es3fDitheringTests.cpp b/modules/gles3/functional/es3fDitheringTests.cpp
index ad02947..5e52d9e 100644
--- a/modules/gles3/functional/es3fDitheringTests.cpp
+++ b/modules/gles3/functional/es3fDitheringTests.cpp
@@ -317,11 +317,12 @@
 	{
 		const int	increasingDirectionSize	= isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth();
 		const int	constantDirectionSize	= isVerticallyIncreasing ? renderedImg.getWidth() : renderedImg.getHeight();
-		bool		colorHasChanged			= false;
 
 		for (int incrPos = 0; incrPos < increasingDirectionSize; incrPos++)
 		{
-			tcu::RGBA prevConstantDirectionPix;
+			bool		colorHasChanged			= false;
+			tcu::RGBA	prevConstantDirectionPix;
+
 			for (int constPos = 0; constPos < constantDirectionSize; constPos++)
 			{
 				const int			x		= isVerticallyIncreasing ? constPos : incrPos;
diff --git a/modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp b/modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp
index 478246f..de99dd7 100644
--- a/modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp
+++ b/modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp
@@ -2222,13 +2222,16 @@
 		++totalPixels;
 	}
 
-	if (missedPixels > 0 && --messageLimitCounter >= 0)
+	if (missedPixels > 0)
 	{
-		m_testCtx.getLog()
-			<< tcu::TestLog::Message
-			<< "Found non-continuous " << ((advance.x() == 1)  ? ("horizontal") : ("vertical")) << " line near " << begin << ". "
-			<< "Missed pixels: " << missedPixels
-			<< tcu::TestLog::EndMessage;
+		if (--messageLimitCounter >= 0)
+		{
+			m_testCtx.getLog()
+				<< tcu::TestLog::Message
+				<< "Found non-continuous " << ((advance.x() == 1)  ? ("horizontal") : ("vertical")) << " line near " << begin << ". "
+				<< "Missed pixels: " << missedPixels
+				<< tcu::TestLog::EndMessage;
+		}
 		// allow 10% missing pixels for warning
 		if (missedPixels <= deRoundFloatToInt32((float)totalPixels * 0.1f))
 			errorMask = SCANRESULT_LINE_CONT_WARN_BIT;
diff --git a/modules/glshared/glsLifetimeTests.cpp b/modules/glshared/glsLifetimeTests.cpp
index f00b4b2..fb34551 100644
--- a/modules/glshared/glsLifetimeTests.cpp
+++ b/modules/glshared/glsLifetimeTests.cpp
@@ -37,6 +37,8 @@
 #include "gluPixelTransfer.hpp"
 #include "gluShaderProgram.hpp"
 #include "gluDefs.hpp"
+#include "gluTextureUtil.hpp"
+#include "gluStrUtil.hpp"
 #include "glwFunctions.hpp"
 
 #include <vector>
@@ -358,18 +360,178 @@
 	return getFboAttachment(gl(), fbo, GL_TEXTURE);
 }
 
+static bool isTextureFormatColorRenderable (const glu::RenderContext& renderCtx, const glu::TransferFormat& format)
+{
+	const glw::Functions&	gl			= renderCtx.getFunctions();
+	deUint32				curFbo		= ~0u;
+	deUint32				curTex		= ~0u;
+	deUint32				testFbo		= 0u;
+	deUint32				testTex		= 0u;
+	GLenum					status		= GL_NONE;
+
+	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (deInt32*)&curFbo));
+	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_TEXTURE_BINDING_2D, (deInt32*)&curTex));
+
+	try
+	{
+		GLU_CHECK_GLW_CALL(gl, genTextures(1, &testTex));
+		GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, testTex));
+		GLU_CHECK_GLW_CALL(gl, texImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
+										  format.format, format.dataType, DE_NULL));
+
+		GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
+		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
+		GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, testTex, 0));
+
+		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
+		GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");
+
+		GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, curTex));
+		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));
+
+		GLU_CHECK_GLW_CALL(gl, deleteTextures(1, &testTex));
+		GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
+	}
+	catch (...)
+	{
+		if (testTex != 0)
+			gl.deleteTextures(1, &testTex);
+
+		if (testFbo != 0)
+			gl.deleteFramebuffers(1, &testFbo);
+
+		throw;
+	}
+
+	if (status == GL_FRAMEBUFFER_COMPLETE)
+		return true;
+	else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
+		return false;
+	else
+		TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ")
+							  + de::toString(glu::getFramebufferStatusStr(status))).c_str());
+}
+
+static glu::TransferFormat getRenderableColorTextureFormat (const glu::RenderContext& renderCtx)
+{
+	if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3,0)))
+		return glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
+
+	{
+		const glu::TransferFormat	candidates[]	=
+		{
+			glu::TransferFormat(GL_RGBA,	GL_UNSIGNED_SHORT_4_4_4_4),
+			glu::TransferFormat(GL_RGBA,	GL_UNSIGNED_SHORT_5_5_5_1),
+			glu::TransferFormat(GL_RGB,		GL_UNSIGNED_SHORT_5_6_5),
+			glu::TransferFormat(GL_RGBA,	GL_UNSIGNED_BYTE),
+		};
+
+		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
+		{
+			if (isTextureFormatColorRenderable(renderCtx, candidates[ndx]))
+				return candidates[ndx];
+		}
+	}
+
+	return glu::TransferFormat(GL_NONE, GL_NONE);
+}
+
 void TextureFboAttacher::initStorage (void)
 {
+	const glu::TransferFormat	format	= getRenderableColorTextureFormat(getRenderContext());
+
+	if (format.format == GL_NONE)
+		TCU_THROW(NotSupportedError, "No renderable texture format found");
+
 	GLU_CHECK_CALL_ERROR(
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
-					 GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, DE_NULL),
+		glTexImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
+					 format.format, format.dataType, DE_NULL),
 		gl().getError());
 }
 
+static bool isRenderbufferFormatColorRenderable (const glu::RenderContext& renderCtx, const deUint32 format)
+{
+	const glw::Functions&	gl			= renderCtx.getFunctions();
+	deUint32				curFbo		= ~0u;
+	deUint32				curRbo		= ~0u;
+	deUint32				testFbo		= 0u;
+	deUint32				testRbo		= 0u;
+	GLenum					status		= GL_NONE;
+
+	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (deInt32*)&curFbo));
+	GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_RENDERBUFFER_BINDING, (deInt32*)&curRbo));
+
+	try
+	{
+		GLU_CHECK_GLW_CALL(gl, genRenderbuffers(1, &testRbo));
+		GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, testRbo));
+		GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE));
+
+		GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
+		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
+		GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, testRbo));
+
+		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
+		GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");
+
+		GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, curRbo));
+		GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));
+
+		GLU_CHECK_GLW_CALL(gl, deleteRenderbuffers(1, &testRbo));
+		GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
+	}
+	catch (...)
+	{
+		if (testRbo != 0)
+			gl.deleteRenderbuffers(1, &testRbo);
+
+		if (testFbo != 0)
+			gl.deleteFramebuffers(1, &testFbo);
+
+		throw;
+	}
+
+	if (status == GL_FRAMEBUFFER_COMPLETE)
+		return true;
+	else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
+		return false;
+	else
+		TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ")
+							  + de::toString(glu::getFramebufferStatusStr(status))).c_str());
+}
+
+static deUint32 getRenderableColorRenderbufferFormat (const glu::RenderContext& renderCtx)
+{
+	if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3,0)))
+		return GL_RGBA4;
+
+	{
+		const deUint32	candidates[]	=
+		{
+			GL_RGBA4,
+			GL_RGB5_A1,
+			GL_RGB565,
+		};
+
+		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
+		{
+			if (isRenderbufferFormatColorRenderable(renderCtx, candidates[ndx]))
+				return candidates[ndx];
+		}
+	}
+
+	return GL_NONE;
+}
+
 void RboFboAttacher::initStorage (void)
 {
+	const deUint32	format	= getRenderableColorRenderbufferFormat(getRenderContext());
+
+	if (format == GL_NONE)
+		TCU_THROW(TestError, "No color-renderable renderbuffer format found");
+
 	GLU_CHECK_CALL_ERROR(
-		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
+		glRenderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
 		gl().getError());
 }
 
diff --git a/scripts/build_android_mustpass.py b/scripts/build_android_mustpass.py
index e2e8815..1fa117b 100644
--- a/scripts/build_android_mustpass.py
+++ b/scripts/build_android_mustpass.py
@@ -500,6 +500,7 @@
 		exclude("vk-not-applicable.txt"),
 		exclude("vk-excluded-tests.txt"),
 		exclude("vk-test-issues.txt"),
+		exclude("vk-waivers.txt"),
 	]
 MASTER_VULKAN_PKG				= Package(module = VULKAN_MODULE, configurations = [
 		Configuration(name			= "master",