Merge branch 'jbolz_compareFRem' into 'master'

Add 'compareFRem' function verifyIO function

Use an approximate comparison for FRem.

See merge request !316
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
index c364191..db4fed3 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
@@ -450,6 +450,28 @@
 	return group.release();
 }
 
+bool compareFRem(const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs)
+{
+	if (outputAllocs.size() != 1)
+		return false;
+
+	const BufferSp& expectedOutput = expectedOutputs[0];
+	const float *expectedOutputAsFloat = static_cast<const float*>(expectedOutput->data());
+	const float* outputAsFloat = static_cast<const float*>(outputAllocs[0]->getHostPtr());;
+
+	for (size_t idx = 0; idx < expectedOutput->getNumBytes() / sizeof(float); ++idx)
+	{
+		const float f0 = expectedOutputAsFloat[idx];
+		const float f1 = outputAsFloat[idx];
+		// \todo relative error needs to be fairly high because FRem may be implemented as
+		// (roughly) frac(a/b)*b, so LSB errors can be magnified. But this should be fine for now.
+		if (deFloatAbs((f1 - f0) / f0) > 0.02)
+			return false;
+	}
+
+	return true;
+}
+
 tcu::TestCaseGroup* createOpFRemGroup (tcu::TestContext& testCtx)
 {
 	de::MovePtr<tcu::TestCaseGroup>	group			(new tcu::TestCaseGroup(testCtx, "opfrem", "Test the OpFRem instruction"));
@@ -528,6 +550,7 @@
 	spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats2)));
 	spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
 	spec.numWorkGroups = IVec3(numElements, 1, 1);
+	spec.verifyIO = &compareFRem;
 
 	group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "", spec));