Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/master

Change-Id: I0a9fdded2cbfd25f1e2a1c73da97b2d8b8431962
diff --git a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
index 81db0e7..7ab9e51 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
@@ -3069,7 +3069,7 @@
 			DE_NULL,									// const void*				pNext;
 			0u,											// VkAccessFlags			srcAccessMask;
 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
-			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
+			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
diff --git a/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
index e0219c0..00fb35e 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
@@ -74,6 +74,27 @@
 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, maxMipLevels);
 }
 
+deUint32 greatestCommonDivisor (const deUint32 a, const deUint32 b)
+{
+	/* Find GCD */
+	deUint32 temp;
+	deUint32 x=a;
+	deUint32 y=b;
+
+	while (x%b != 0)
+	{
+		temp = y;
+		y = x%y;
+		x = temp;
+	}
+	return y;
+}
+
+deUint32 lowestCommonMultiple (const deUint32 a, const deUint32 b)
+{
+	return (a*b)/greatestCommonDivisor(a,b);
+}
+
 std::vector<deUint32> getImageMipLevelSizes (const deUint32 pixelSize, const VkExtent3D& baseExtent, const deUint32 numMipLevels, const deUint32 perLevelAlignment = 1u)
 {
 	std::vector<deUint32> results(numMipLevels);
@@ -81,7 +102,8 @@
 	for (deUint32 mipLevel = 0; mipLevel < numMipLevels; ++mipLevel)
 	{
 		const VkExtent3D extent = getMipLevelExtent(baseExtent, mipLevel);
-		results[mipLevel] = static_cast<deUint32>(deAlignSize(extent.width * extent.height * extent.depth * pixelSize, perLevelAlignment));
+		results[mipLevel] = static_cast<deUint32>(extent.width * extent.height * extent.depth * pixelSize);
+		results[mipLevel] = ((results[mipLevel] + perLevelAlignment-1) / perLevelAlignment) * perLevelAlignment;
 	}
 
 	return results;
@@ -748,7 +770,11 @@
 														  aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT ? getStencilCopyFormat(m_params.imageFormat) :
 														  TextureFormat();
 	const deUint32						pixelSize		= getPixelSize(tcuFormat);
-	const deUint32						alignment		= 4;	// subsequent mip levels aligned to 4 bytes
+	deUint32							alignment		= 4;	// subsequent mip levels aligned to 4 bytes
+
+	if (!getIsDepthFormat(m_params.imageFormat) && !getIsStencilFormat(m_params.imageFormat))
+		alignment = lowestCommonMultiple(pixelSize, alignment); // alignment must be multiple of pixel size, if not D/S.
+
 	const std::vector<deUint32>			mipLevelSizes	= getImageMipLevelSizes(pixelSize, m_params.imageExtent, m_imageMipLevels, alignment);
 	const VkDeviceSize					imageTotalSize	= std::accumulate(mipLevelSizes.begin(), mipLevelSizes.end(), 0u);
 
diff --git a/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp b/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
index 452d631..13b80e3 100644
--- a/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
+++ b/external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
@@ -441,11 +441,16 @@
 
 	const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
 	const CmdBufferBeginInfo beginInfo;
+	int firstInstanceIndicesCount = 1;
+
+	// Require 'drawIndirectFirstInstance' feature to run non-zero firstInstance indirect draw tests.
+	if (m_context.getDeviceFeatures().drawIndirectFirstInstance)
+		firstInstanceIndicesCount = DE_LENGTH_OF_ARRAY(firstInstanceIndices);
 
 	for (int instanceCountNdx = 0; instanceCountNdx < DE_LENGTH_OF_ARRAY(instanceCounts); instanceCountNdx++)
 	{
 		const deUint32 instanceCount = instanceCounts[instanceCountNdx];
-		for (int firstInstanceIndexNdx = 0; firstInstanceIndexNdx < DE_LENGTH_OF_ARRAY(firstInstanceIndices); firstInstanceIndexNdx++)
+		for (int firstInstanceIndexNdx = 0; firstInstanceIndexNdx < firstInstanceIndicesCount; firstInstanceIndexNdx++)
 		{
 			const deUint32 firstInstance = firstInstanceIndices[firstInstanceIndexNdx];
 
diff --git a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
index 935c0b8..087a7b3 100644
--- a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
+++ b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
@@ -1164,7 +1164,7 @@
 			scene.lines.swap(lines);
 			scene.lineWidth = lineWidth;
 
-			if (!verifyClippedTriangulatedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
+			if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
 				m_allIterationsPassed = false;
 		}
 	}
diff --git a/framework/common/tcuRasterizationVerifier.cpp b/framework/common/tcuRasterizationVerifier.cpp
index e341398..dd8ff86 100644
--- a/framework/common/tcuRasterizationVerifier.cpp
+++ b/framework/common/tcuRasterizationVerifier.cpp
@@ -907,7 +907,7 @@
 	CLIPMODE_LAST
 };
 
-bool verifyMultisampleLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, ClipMode clipMode)
+bool verifyMultisampleLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, ClipMode clipMode, VerifyTriangleGroupRasterizationLogStash* logStash = DE_NULL)
 {
 	// Multisampled line == 2 triangles
 
@@ -963,7 +963,7 @@
 		triangleScene.triangles[lineNdx*2 + 1].positions[2] = tcu::Vec4(lineQuadNormalizedDeviceSpace[3].x(), lineQuadNormalizedDeviceSpace[3].y(), 0.0f, 1.0f);	triangleScene.triangles[lineNdx*2 + 1].sharedEdge[2] = false;
 	}
 
-	return verifyTriangleGroupRasterization(surface, triangleScene, args, log);
+	return verifyTriangleGroupRasterization(surface, triangleScene, args, log, VERIFICATIONMODE_STRICT, logStash);
 }
 
 bool verifyMultisampleLineGroupInterpolation (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
@@ -2242,7 +2242,33 @@
 	}
 }
 
-bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const TriangleSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, VerificationMode mode)
+static void verifyTriangleGroupRasterizationLog (const tcu::Surface& surface, tcu::TestLog& log, VerifyTriangleGroupRasterizationLogStash& logStash)
+{
+	// Output results
+	log << tcu::TestLog::Message << "Verifying rasterization result." << tcu::TestLog::EndMessage;
+
+	if (!logStash.result)
+	{
+		log << tcu::TestLog::Message << "Invalid pixels found:\n\t"
+			<< logStash.missingPixels << " missing pixels. (Marked with purple)\n\t"
+			<< logStash.unexpectedPixels << " incorrectly filled pixels. (Marked with red)\n\t"
+			<< "Unknown (subpixel on edge) pixels are marked with yellow."
+			<< tcu::TestLog::EndMessage;
+		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
+			<< tcu::TestLog::Image("Result",	"Result",		surface)
+			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	logStash.errorMask)
+			<< tcu::TestLog::EndImageSet;
+	}
+	else
+	{
+		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
+		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
+			<< tcu::TestLog::Image("Result", "Result", surface)
+			<< tcu::TestLog::EndImageSet;
+	}
+}
+
+bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const TriangleSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, VerificationMode mode, VerifyTriangleGroupRasterizationLogStash* logStash)
 {
 	DE_ASSERT(mode < VERIFICATIONMODE_LAST);
 
@@ -2260,6 +2286,7 @@
 	int					subPixelBits				= args.subpixelBits;
 	tcu::TextureLevel	coverageMap					(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT8), surface.getWidth(), surface.getHeight());
 	tcu::Surface		errorMask					(surface.getWidth(), surface.getHeight());
+	bool				result						= false;
 
 	// subpixel bits in in a valid range?
 
@@ -2376,33 +2403,33 @@
 		};
 	}
 
-	// Output results
-	log << tcu::TestLog::Message << "Verifying rasterization result." << tcu::TestLog::EndMessage;
-
 	if (((mode == VERIFICATIONMODE_STRICT) && (missingPixels + unexpectedPixels > 0)) ||
 		((mode == VERIFICATIONMODE_WEAK)   && (missingPixels + unexpectedPixels > weakVerificationThreshold)))
 	{
-		log << tcu::TestLog::Message << "Invalid pixels found:\n\t"
-			<< missingPixels << " missing pixels. (Marked with purple)\n\t"
-			<< unexpectedPixels << " incorrectly filled pixels. (Marked with red)\n\t"
-			<< "Unknown (subpixel on edge) pixels are marked with yellow."
-			<< tcu::TestLog::EndMessage;
-		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
-			<< tcu::TestLog::Image("Result",	"Result",		surface)
-			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
-			<< tcu::TestLog::EndImageSet;
-
-		return false;
+		result = false;
 	}
 	else
 	{
-		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
-		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
-			<< tcu::TestLog::Image("Result", "Result", surface)
-			<< tcu::TestLog::EndImageSet;
-
-		return true;
+		result = true;
 	}
+
+	// Output or stash results
+	{
+		VerifyTriangleGroupRasterizationLogStash* tempLogStash = (logStash == DE_NULL) ? new VerifyTriangleGroupRasterizationLogStash : logStash;
+
+		tempLogStash->result			= result;
+		tempLogStash->missingPixels		= missingPixels;
+		tempLogStash->unexpectedPixels	= unexpectedPixels;
+		tempLogStash->errorMask			= errorMask;
+
+		if (logStash == DE_NULL)
+		{
+			verifyTriangleGroupRasterizationLog(surface, log, *tempLogStash);
+			delete tempLogStash;
+		}
+	}
+
+	return result;
 }
 
 bool verifyLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
@@ -2410,14 +2437,46 @@
 	const bool multisampled = args.numSamples != 0;
 
 	if (multisampled)
-		return verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_NO_CLIPPING);
+		return verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_NO_CLIPPING, DE_NULL);
 	else
 		return verifySinglesampleLineGroupRasterization(surface, scene, args, log);
 }
 
 bool verifyClippedTriangulatedLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
 {
-	return verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_USE_CLIPPING_BOX);
+	return verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_USE_CLIPPING_BOX, DE_NULL);
+}
+
+bool verifyRelaxedLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
+{
+	VerifyTriangleGroupRasterizationLogStash noClippingLogStash;
+	VerifyTriangleGroupRasterizationLogStash useClippingLogStash;
+
+	if (verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_USE_CLIPPING_BOX, &useClippingLogStash))
+	{
+		log << tcu::TestLog::Message << "Relaxed rasterization succeeded with CLIPMODE_USE_CLIPPING_BOX, details follow." << tcu::TestLog::EndMessage;
+
+		verifyTriangleGroupRasterizationLog(surface, log, useClippingLogStash);
+
+		return true;
+	}
+	else if (verifyMultisampleLineGroupRasterization(surface, scene, args, log, CLIPMODE_NO_CLIPPING, &noClippingLogStash))
+	{
+		log << tcu::TestLog::Message << "Relaxed rasterization succeeded with CLIPMODE_NO_CLIPPING, details follow." << tcu::TestLog::EndMessage;
+
+		verifyTriangleGroupRasterizationLog(surface, log, noClippingLogStash);
+
+		return true;
+	}
+	else
+	{
+		log << tcu::TestLog::Message << "Relaxed rasterization failed, details follow." << tcu::TestLog::EndMessage;
+
+		verifyTriangleGroupRasterizationLog(surface, log, useClippingLogStash);
+		verifyTriangleGroupRasterizationLog(surface, log, noClippingLogStash);
+
+		return false;
+	}
 }
 
 bool verifyPointGroupRasterization (const tcu::Surface& surface, const PointSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log)
diff --git a/framework/common/tcuRasterizationVerifier.hpp b/framework/common/tcuRasterizationVerifier.hpp
index 31f88f8..0815116 100644
--- a/framework/common/tcuRasterizationVerifier.hpp
+++ b/framework/common/tcuRasterizationVerifier.hpp
@@ -25,6 +25,7 @@
 
 #include "tcuDefs.hpp"
 #include "tcuTestLog.hpp"
+#include "tcuSurface.hpp"
 #include "deMath.h"
 
 #include <vector>
@@ -101,6 +102,14 @@
 	int blueBits;
 };
 
+struct VerifyTriangleGroupRasterizationLogStash
+{
+	int				missingPixels;
+	int				unexpectedPixels;
+	tcu::Surface	errorMask;
+	bool			result;
+};
+
 /*--------------------------------------------------------------------*//*!
  * \brief Calculates triangle coverage at given pixel
  * Calculates the coverage of a triangle given by three vertices. The
@@ -116,10 +125,11 @@
  * by RasterizationArguments. Triangles should not be z-clipped.
  *
  * Triangle colors are not used. The triangle is expected to be white.
+ * If logStash is not NULL the results are not logged, but copied to stash.
  *
  * Returns false if invalid rasterization is found.
  *//*--------------------------------------------------------------------*/
-bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const TriangleSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, VerificationMode mode = VERIFICATIONMODE_STRICT);
+bool verifyTriangleGroupRasterization (const tcu::Surface& surface, const TriangleSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log, VerificationMode mode = VERIFICATIONMODE_STRICT, VerifyTriangleGroupRasterizationLogStash* logStash = DE_NULL);
 
 /*--------------------------------------------------------------------*//*!
  * \brief Verify line rasterization result
@@ -146,6 +156,16 @@
 bool verifyClippedTriangulatedLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log);
 
 /*--------------------------------------------------------------------*//*!
+ * \brief Verify line rasterization result both clipped and non-clipped
+ *
+ * For details please see verifyLineGroupRasterization and
+ * verifyClippedTriangulatedLineGroupRasterization
+ *
+ * Returns false if both rasterizations are invalid.
+ *//*--------------------------------------------------------------------*/
+bool verifyRelaxedLineGroupRasterization (const tcu::Surface& surface, const LineSceneSpec& scene, const RasterizationArguments& args, tcu::TestLog& log);
+
+/*--------------------------------------------------------------------*//*!
  * \brief Verify point rasterization result
  * Verifies points in the surface are rasterized within the bounds given
  * by RasterizationArguments. Points should not be z-clipped.