Merge "Add basic WSI swapchain tests" into nyc-dev
diff --git a/Android.mk b/Android.mk
index ba443bc..99e7a2c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -713,6 +713,7 @@
 	external/vulkancts/modules/vulkan/dynamic_state/vktDynamicStateGeneralTests.cpp \
 	external/vulkancts/modules/vulkan/dynamic_state/vktDynamicStateImageObjectUtil.cpp \
 	external/vulkancts/modules/vulkan/vktTestPackage.cpp \
+	external/vulkancts/modules/vulkan/vktSynchronization.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderPackingFunctionTests.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderIntegerFunctionTests.cpp \
 	external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.cpp \
@@ -896,7 +897,7 @@
 	$(deqp_compile_flags)
 
 LOCAL_SDK_VERSION := 9
-LOCAL_CPPFLAGS += -Wno-non-virtual-dtor
+LOCAL_CPPFLAGS += -Wno-non-virtual-dtor -fwrapv
 LOCAL_NDK_STL_VARIANT := gnustl_static
 LOCAL_RTTI_FLAG := -frtti -fexceptions
 LOCAL_MULTILIB := both
diff --git a/android/cts/master/com.drawelements.deqp.gles31.xml b/android/cts/master/com.drawelements.deqp.gles31.xml
index 996aecd..2b03874 100644
--- a/android/cts/master/com.drawelements.deqp.gles31.xml
+++ b/android/cts/master/com.drawelements.deqp.gles31.xml
@@ -53492,18 +53492,6 @@
 							<Test name="precise_as_function_argument">
 								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 							</Test>
-							<Test name="precise_as_macro_name">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_variable">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_function">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_argument">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
 						</TestCase>
 						<TestCase name="advanced_blend">
 							<Test name="blend_qualifier_mismatch">
@@ -54811,18 +54799,6 @@
 							<Test name="precise_as_function_argument">
 								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 							</Test>
-							<Test name="precise_as_macro_name">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_variable">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_function">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_argument">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
 						</TestCase>
 						<TestCase name="advanced_blend">
 							<Test name="blend_qualifier_mismatch">
@@ -56127,18 +56103,6 @@
 							<Test name="precise_as_function_argument">
 								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
 							</Test>
-							<Test name="precise_as_macro_name">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_variable">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_function">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
-							<Test name="precise_as_macro_and_argument">
-								<TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
-							</Test>
 						</TestCase>
 						<TestCase name="advanced_blend">
 							<Test name="blend_qualifier_mismatch">
diff --git a/android/cts/master/com.drawelements.deqp.vk.xml b/android/cts/master/com.drawelements.deqp.vk.xml
index 834a20d..1d20ed4 100644
--- a/android/cts/master/com.drawelements.deqp.vk.xml
+++ b/android/cts/master/com.drawelements.deqp.vk.xml
@@ -258771,5 +258771,16 @@
 				</TestCase>
 			</TestSuite>
 		</TestSuite>
+		<TestCase name="synchronization">
+			<Test name="fences">
+				<TestInstance/>
+			</Test>
+			<Test name="semaphores">
+				<TestInstance/>
+			</Test>
+			<Test name="events">
+				<TestInstance/>
+			</Test>
+		</TestCase>
 	</TestSuite>
 </TestPackage>
diff --git a/android/cts/master/gles31-master.txt b/android/cts/master/gles31-master.txt
index a0d243b..3869bb6 100644
--- a/android/cts/master/gles31-master.txt
+++ b/android/cts/master/gles31-master.txt
@@ -16749,10 +16749,6 @@
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_variable_name
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_name
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_argument
-dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_macro_name
-dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_macro_and_variable
-dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_macro_and_function
-dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_macro_and_argument
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.attachment_advanced_equation
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.bind_buffer
@@ -17180,10 +17176,6 @@
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_variable_name
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_name
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_argument
-dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_macro_name
-dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_macro_and_variable
-dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_macro_and_function
-dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_macro_and_argument
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.attachment_advanced_equation
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.bind_buffer
@@ -17610,10 +17602,6 @@
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_variable_name
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_name
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_argument
-dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_macro_name
-dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_macro_and_variable
-dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_macro_and_function
-dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_macro_and_argument
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.attachment_advanced_equation
 dEQP-GLES31.functional.debug.externally_generated.application_messages
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index c711c8c..dddce41 100644
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
@@ -80294,3 +80294,6 @@
 dEQP-VK.wsi.android.surface.query_formats
 dEQP-VK.wsi.android.surface.query_present_modes
 dEQP-VK.wsi.android.surface.initial_size
+dEQP-VK.synchronization.fences
+dEQP-VK.synchronization.semaphores
+dEQP-VK.synchronization.events
diff --git a/external/vulkancts/modules/vulkan/CMakeLists.txt b/external/vulkancts/modules/vulkan/CMakeLists.txt
index a575e8f..4829419 100644
--- a/external/vulkancts/modules/vulkan/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/CMakeLists.txt
@@ -49,6 +49,8 @@
 	vktTestGroupUtil.hpp
 	vktInfoTests.cpp
 	vktInfoTests.hpp
+	vktSynchronization.cpp
+	vktSynchronization.hpp
 	)
 
 set(DEQP_VK_COMMON_LIBS
diff --git a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
index 0958bd1..4c66021 100755
--- a/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiFeatureInfo.cpp
@@ -808,6 +808,83 @@
 		}
 	}
 
+	if (memProps->memoryHeapCount >= VK_MAX_MEMORY_HEAPS)
+	{
+		log << TestLog::Message << "deviceMemoryProperties - HeapCount larger than " << (deUint32)VK_MAX_MEMORY_HEAPS << TestLog::EndMessage;
+		return tcu::TestStatus::fail("deviceMemoryProperties HeapCount too large");
+	}
+
+	if (memProps->memoryHeapCount == 1)
+	{
+		if ((memProps->memoryHeaps[0].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
+		{
+			log << TestLog::Message << "deviceMemoryProperties - Single heap is not marked DEVICE_LOCAL" << TestLog::EndMessage;
+			return tcu::TestStatus::fail("deviceMemoryProperties invalid HeapFlags");
+		}
+	}
+
+	const VkMemoryPropertyFlags validPropertyFlags[] =
+	{
+		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
+	};
+
+	const VkMemoryPropertyFlags requiredPropertyFlags[] =
+	{
+		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
+	};
+
+	bool requiredFlagsFound[DE_LENGTH_OF_ARRAY(requiredPropertyFlags)];
+	std::fill(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
+
+	for (deUint32 memoryNdx = 0; memoryNdx < memProps->memoryTypeCount; memoryNdx++)
+	{
+		bool validPropTypeFound = false;
+
+		if (memProps->memoryTypes[memoryNdx].heapIndex >= memProps->memoryHeapCount)
+		{
+			log << TestLog::Message << "deviceMemoryProperties - heapIndex " << memProps->memoryTypes[memoryNdx].heapIndex << " larger than heapCount" << TestLog::EndMessage;
+			return tcu::TestStatus::fail("deviceMemoryProperties - invalid heapIndex");
+		}
+
+		const VkMemoryPropertyFlags bitsToCheck = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
+		const VkMemoryPropertyFlags* requiredFlagsIterator = std::find(DE_ARRAY_BEGIN(requiredPropertyFlags),
+																		DE_ARRAY_END(requiredPropertyFlags),
+																		memProps->memoryTypes[memoryNdx].propertyFlags & bitsToCheck);
+
+		if (requiredFlagsIterator != DE_ARRAY_END(requiredPropertyFlags))
+		{
+			DE_ASSERT(requiredFlagsIterator - DE_ARRAY_BEGIN(requiredPropertyFlags) <= DE_LENGTH_OF_ARRAY(requiredFlagsFound));
+			requiredFlagsFound[requiredFlagsIterator - DE_ARRAY_BEGIN(requiredPropertyFlags)] = true;
+		}
+
+		if (de::contains(DE_ARRAY_BEGIN(validPropertyFlags), DE_ARRAY_END(validPropertyFlags), memProps->memoryTypes[memoryNdx].propertyFlags & bitsToCheck))
+			validPropTypeFound = true;
+
+		if (!validPropTypeFound)
+		{
+			log << TestLog::Message << "deviceMemoryProperties - propertyFlags "
+				<< memProps->memoryTypes[memoryNdx].propertyFlags << " not valid" << TestLog::EndMessage;
+			return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
+		}
+	}
+
+	bool* requiredFlagsFoundIterator = std::find(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
+	if (requiredFlagsFoundIterator != DE_ARRAY_END(requiredFlagsFound))
+	{
+		DE_ASSERT(requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound) <= DE_LENGTH_OF_ARRAY(requiredPropertyFlags));
+		log << TestLog::Message << "deviceMemoryProperties - required property flags "
+			<< requiredPropertyFlags[requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound)] << "not found" << TestLog::EndMessage;
+
+		return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
+	}
+
 	return tcu::TestStatus::pass("Querying memory properties succeeded");
 }
 
diff --git a/external/vulkancts/modules/vulkan/vktSynchronization.cpp b/external/vulkancts/modules/vulkan/vktSynchronization.cpp
new file mode 100644
index 0000000..e6cdbc2
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/vktSynchronization.cpp
@@ -0,0 +1,1408 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Platform Synchronization tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSynchronization.hpp"
+
+#include "vktTestCaseUtil.hpp"
+
+#include "vkPlatform.hpp"
+#include "vkStrUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkDeviceUtil.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuFormatUtil.hpp"
+
+#include "deUniquePtr.hpp"
+#include "deThread.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkTypeUtil.hpp"
+
+namespace vkt
+{
+
+using namespace vk;
+using namespace tcu;
+
+namespace
+{
+
+using std::vector;
+using std::string;
+using tcu::TestLog;
+using de::UniquePtr;
+using de::MovePtr;
+
+static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
+
+void buildShaders (SourceCollections& shaderCollection)
+{
+	shaderCollection.glslSources.add("glslvert") <<
+		glu::VertexSource(
+				"#version 310 es\n"
+				"precision mediump float;\n"
+				"layout (location = 0) in vec4 vertexPosition;\n"
+				"void main()\n"
+				"{\n"
+				"	gl_Position = vertexPosition;\n"
+				"}\n");
+
+	shaderCollection.glslSources.add("glslfrag") <<
+		glu::FragmentSource(
+				"#version 310 es\n"
+				"precision mediump float;\n"
+				"layout (location = 0) out vec4 outputColor;\n"
+				"void main()\n"
+				"{\n"
+				"	outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
+				"}\n");
+}
+
+Move<VkDevice> createTestDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
+{
+	VkDeviceQueueCreateInfo		queueInfo;
+	VkDeviceCreateInfo			deviceInfo;
+	size_t						queueNdx;
+	const float					queuePriority	= 1.0f;
+
+	const vector<VkQueueFamilyProperties>	queueProps				= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
+	const VkPhysicalDeviceFeatures			physicalDeviceFeatures	= getPhysicalDeviceFeatures(vki, physicalDevice);
+
+	for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
+	{
+		if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
+			break;
+	}
+
+	deMemset(&queueInfo,	0, sizeof(queueInfo));
+	deMemset(&deviceInfo,	0, sizeof(deviceInfo));
+
+	queueInfo.sType							= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+	queueInfo.pNext							= DE_NULL;
+	queueInfo.flags							= (VkDeviceQueueCreateFlags)0u;
+	queueInfo.queueFamilyIndex				= (deUint32)queueNdx;
+	queueInfo.queueCount					= 2u;
+	queueInfo.pQueuePriorities				= &queuePriority;
+
+	deviceInfo.sType						= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+	deviceInfo.pNext						= DE_NULL;
+	deviceInfo.queueCreateInfoCount			= 1u;
+	deviceInfo.pQueueCreateInfos			= &queueInfo;
+	deviceInfo.enabledExtensionCount		= 0u;
+	deviceInfo.ppEnabledExtensionNames		= DE_NULL;
+	deviceInfo.enabledLayerCount			= 0u;
+	deviceInfo.ppEnabledLayerNames			= DE_NULL;
+	deviceInfo.pEnabledFeatures				= &physicalDeviceFeatures;
+
+	return createDevice(vki, physicalDevice, &deviceInfo);
+};
+
+struct BufferParameters
+{
+	Context*						context;
+	VkDevice						device;
+	const void*						memory;
+	VkDeviceSize					size;
+	VkBufferUsageFlags				usage;
+	VkSharingMode					sharingMode;
+	deUint32						queueFamilyCount;
+	const deUint32*					queueFamilyIndex;
+	VkAccessFlags					inputBarrierFlags;
+};
+
+struct Buffer
+{
+	MovePtr<Allocation>				allocation;
+	vector<VkMemoryBarrier> 		memoryBarrier;
+	vk::Move<VkBuffer>				buffer;
+};
+
+void createVulkanBuffer (const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
+{
+	TestLog&							log					= bufferParameters.context->getTestContext().getLog();
+	const VkDevice						device				= bufferParameters.device;
+	const VkPhysicalDevice				physDevice			= bufferParameters.context->getPhysicalDevice();
+	const DeviceInterface&				deviceInterface		= bufferParameters.context->getDeviceInterface();
+	const InstanceInterface&			instanceInterface	= bufferParameters.context->getInstanceInterface();
+	VkResult							vkApiStatus;
+	VkPhysicalDeviceMemoryProperties	memProps;
+	VkMemoryRequirements				memReq;
+	VkBufferCreateInfo					bufferCreateParams;
+	VkBuffer							newBuffer;
+
+	bufferCreateParams.sType					= VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+	bufferCreateParams.pNext					= DE_NULL;
+	bufferCreateParams.flags					= 0;
+	bufferCreateParams.size						= bufferParameters.size;
+	bufferCreateParams.usage					= bufferParameters.usage;
+	bufferCreateParams.sharingMode				= bufferParameters.sharingMode;
+	bufferCreateParams.queueFamilyIndexCount	= bufferParameters.queueFamilyCount;
+	bufferCreateParams.pQueueFamilyIndices		= bufferParameters.queueFamilyIndex;
+
+	vkApiStatus = deviceInterface.createBuffer(device, &bufferCreateParams, DE_NULL, &newBuffer);
+	if (vkApiStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "Vulkan createBuffer  with (size,usage,sharingMode) = ("
+			<< bufferParameters.size << "," << bufferParameters.usage << "," << bufferParameters.sharingMode <<") failed with status "
+			<< vkApiStatus << TestLog::EndMessage;
+		VK_CHECK(vkApiStatus);
+	}
+
+	buffer.buffer = vk::Move<VkBuffer>(vk::check<VkBuffer>(newBuffer), Deleter<VkBuffer>(deviceInterface, device, DE_NULL));
+
+	instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
+	deviceInterface.getBufferMemoryRequirements(device, buffer.buffer.get(), &memReq);
+
+	{
+		Allocator&              allocator = bufferParameters.context->getDefaultAllocator();
+		MovePtr<Allocation>		newMemory	(allocator.allocate(memReq, visibility));
+
+		vkApiStatus = deviceInterface.bindBufferMemory(device, buffer.buffer.get(), newMemory->getMemory(), newMemory->getOffset());
+		if (vkApiStatus != VK_SUCCESS)
+		{
+			log << TestLog::Message << "bindBufferMemory on device " << device
+				<< "failed with status " << vkApiStatus << TestLog::EndMessage;
+			VK_CHECK(vkApiStatus);
+		}
+
+		// If caller provides a host memory buffer for the allocation, then go
+		// ahead and copy the provided data into the allocation and update the
+		// barrier list with the associated access
+		if (bufferParameters.memory != DE_NULL)
+		{
+			VkMemoryBarrier				barrier;
+			VkMappedMemoryRange			range;
+
+			range.sType		= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+			range.pNext		= DE_NULL;
+			range.memory	= newMemory->getMemory();
+			range.offset	= newMemory->getOffset();
+			range.size		= bufferParameters.size;
+
+			deMemcpy(newMemory->getHostPtr(), bufferParameters.memory, bufferParameters.size);
+			VK_CHECK(deviceInterface.flushMappedMemoryRanges(device, 1, &range));
+
+			barrier.sType			= VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+			barrier.pNext			= DE_NULL;
+			barrier.srcAccessMask	= VK_ACCESS_HOST_WRITE_BIT;
+			barrier.dstAccessMask	= bufferParameters.inputBarrierFlags;
+
+			buffer.memoryBarrier.push_back(barrier);
+		}
+		buffer.allocation = newMemory;
+	}
+}
+
+struct ImageParameters
+{
+	Context*							context;
+	VkDevice							device;
+	VkImageType							imageType;
+	VkFormat							format;
+	VkExtent3D							extent3D;
+	deUint32							mipLevels;
+	VkSampleCountFlagBits				samples;
+	VkImageTiling						tiling;
+	VkBufferUsageFlags					usage;
+	VkSharingMode						sharingMode;
+	deUint32							queueFamilyCount;
+	const deUint32*						queueFamilyNdxList;
+	VkImageLayout						initialLayout;
+	VkImageLayout						finalLayout;
+	VkAccessFlags						barrierInputMask;
+};
+
+struct Image
+{
+	vk::Move<VkImage>					image;
+	vk::Move<VkImageView>				imageView;
+	MovePtr<Allocation>					allocation;
+	vector<VkImageMemoryBarrier>		imageMemoryBarrier;
+};
+
+void createVulkanImage (const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
+{
+	TestLog&							log					= imageParameters.context->getTestContext().getLog();
+	const DeviceInterface&				deviceInterface		= imageParameters.context->getDeviceInterface();
+	const InstanceInterface&			instanceInterface	= imageParameters.context->getInstanceInterface();
+	const VkPhysicalDevice				physDevice			= imageParameters.context->getPhysicalDevice();
+	const VkDevice						device				= imageParameters.device;
+	VkResult							result;
+	VkPhysicalDeviceMemoryProperties	memProps;
+	VkMemoryRequirements				memReq;
+	VkComponentMapping					componentMap;
+	VkImageSubresourceRange				subresourceRange;
+	VkImageViewCreateInfo				imageViewCreateInfo;
+	VkImageCreateInfo					imageCreateParams;
+	VkImageMemoryBarrier				imageBarrier;
+	VkImage								newImage;
+	VkImageView							newImageView;
+
+	imageCreateParams.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+	imageCreateParams.pNext					= DE_NULL;
+	imageCreateParams.flags					= 0;
+	imageCreateParams.imageType				= imageParameters.imageType;
+	imageCreateParams.format				= imageParameters.format;
+	imageCreateParams.extent				= imageParameters.extent3D;
+	imageCreateParams.mipLevels				= imageParameters.mipLevels;
+	imageCreateParams.arrayLayers			= 1;
+	imageCreateParams.samples				= imageParameters.samples;
+	imageCreateParams.tiling				= imageParameters.tiling;
+	imageCreateParams.usage					= imageParameters.usage;
+	imageCreateParams.sharingMode			= imageParameters.sharingMode;
+	imageCreateParams.queueFamilyIndexCount	= imageParameters.queueFamilyCount;
+	imageCreateParams.pQueueFamilyIndices	= imageParameters.queueFamilyNdxList;
+	imageCreateParams.initialLayout			= imageParameters.initialLayout;
+
+	result = deviceInterface.createImage(device, &imageCreateParams, DE_NULL, &newImage);
+	if (result != VK_SUCCESS)
+	{
+		log << TestLog::Message << "createImage failed with status " << result << TestLog::EndMessage;
+		VK_CHECK(result);
+	}
+
+	image.image = vk::Move<VkImage>(vk::check<VkImage>(newImage), Deleter<VkImage>(deviceInterface, device, DE_NULL));
+
+	instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
+	deviceInterface.getImageMemoryRequirements(device, image.image.get(), &memReq);
+
+	{
+		Allocator&				allocator = imageParameters.context->getDefaultAllocator();
+		MovePtr<Allocation>		newMemory	(allocator.allocate(memReq, visibility));
+		result = deviceInterface.bindImageMemory(device, image.image.get(), newMemory->getMemory(), newMemory->getOffset());
+		if (result != VK_SUCCESS)
+		{
+			log << TestLog::Message << "bindImageMemory failed with status " << result << TestLog::EndMessage;
+			VK_CHECK(result);
+		}
+
+		componentMap.r							= VK_COMPONENT_SWIZZLE_R;
+		componentMap.g							= VK_COMPONENT_SWIZZLE_G;
+		componentMap.b							= VK_COMPONENT_SWIZZLE_B;
+		componentMap.a							= VK_COMPONENT_SWIZZLE_A;
+
+		subresourceRange.aspectMask				= VK_IMAGE_ASPECT_COLOR_BIT;
+		subresourceRange.baseMipLevel			= 0;
+		subresourceRange.levelCount				= imageParameters.mipLevels;
+		subresourceRange.baseArrayLayer			= 0;
+		subresourceRange.layerCount				= 1;
+
+		imageViewCreateInfo.sType				= VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+		imageViewCreateInfo.pNext				= DE_NULL;
+		imageViewCreateInfo.flags				= 0;
+		imageViewCreateInfo.image				= image.image.get();
+		imageViewCreateInfo.viewType			= VK_IMAGE_VIEW_TYPE_3D;
+		imageViewCreateInfo.format				= imageParameters.format;
+		imageViewCreateInfo.components			= componentMap;
+		imageViewCreateInfo.subresourceRange	= subresourceRange;
+
+		result = deviceInterface.createImageView(device, &imageViewCreateInfo, DE_NULL, &newImageView);
+		if (result != VK_SUCCESS)
+		{
+			log << TestLog::Message << "createImageView failed with status " << result << TestLog::EndMessage;
+			VK_CHECK(result);
+		}
+
+		image.imageView = vk::Move<VkImageView>(vk::check<VkImageView>(newImageView), Deleter<VkImageView>(deviceInterface, device, DE_NULL));
+		image.allocation = newMemory;
+
+		imageBarrier.sType					= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+		imageBarrier.pNext					= DE_NULL;
+		imageBarrier.srcAccessMask			= 0;
+		imageBarrier.dstAccessMask			= imageParameters.barrierInputMask;
+		imageBarrier.oldLayout				= imageParameters.initialLayout;
+		imageBarrier.newLayout				= imageParameters.finalLayout;
+		imageBarrier.srcQueueFamilyIndex	= imageParameters.queueFamilyNdxList[0];
+		imageBarrier.dstQueueFamilyIndex	= imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
+		imageBarrier.image					= image.image.get();
+		imageBarrier.subresourceRange		= subresourceRange;
+
+		image.imageMemoryBarrier.push_back(imageBarrier);
+	}
+}
+
+struct RenderPassParameters
+{
+	Context*				context;
+	VkDevice				device;
+	VkFormat				colorFormat;
+	VkSampleCountFlagBits	colorSamples;
+};
+
+void  createColorOnlyRenderPass (const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
+{
+	const DeviceInterface&				deviceInterface		= renderPassParameters.context->getDeviceInterface();
+	const VkDevice						device				= renderPassParameters.device;
+	VkAttachmentDescription				colorAttachmentDesc;
+	VkAttachmentReference				colorAttachmentRef;
+	VkAttachmentReference				stencilAttachmentRef;
+	VkSubpassDescription				subpassDesc;
+	VkRenderPassCreateInfo				renderPassParams;
+	VkRenderPass						newRenderPass;
+
+	colorAttachmentDesc.flags			= 0;
+	colorAttachmentDesc.format			= renderPassParameters.colorFormat;
+	colorAttachmentDesc.samples			= renderPassParameters.colorSamples;
+	colorAttachmentDesc.loadOp			= VK_ATTACHMENT_LOAD_OP_CLEAR;
+	colorAttachmentDesc.storeOp			= VK_ATTACHMENT_STORE_OP_STORE;
+	colorAttachmentDesc.stencilLoadOp	= VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+	colorAttachmentDesc.stencilStoreOp	= VK_ATTACHMENT_STORE_OP_DONT_CARE;
+	colorAttachmentDesc.initialLayout	= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+	colorAttachmentDesc.finalLayout		= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+	colorAttachmentRef.attachment		= 0;
+	colorAttachmentRef.layout			= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+	stencilAttachmentRef.attachment		= VK_NO_ATTACHMENT;
+	stencilAttachmentRef.layout			= VK_IMAGE_LAYOUT_UNDEFINED;
+
+	subpassDesc.flags					= 0;
+	subpassDesc.pipelineBindPoint		= VK_PIPELINE_BIND_POINT_GRAPHICS;
+	subpassDesc.inputAttachmentCount	= 0;
+	subpassDesc.pInputAttachments		= DE_NULL;
+	subpassDesc.colorAttachmentCount	= 1;
+	subpassDesc.pColorAttachments		= &colorAttachmentRef;
+	subpassDesc.pResolveAttachments		= DE_NULL;
+	subpassDesc.pDepthStencilAttachment	= &stencilAttachmentRef;
+	subpassDesc.preserveAttachmentCount	= 0;
+	subpassDesc.pPreserveAttachments	= DE_NULL;
+
+	renderPassParams.sType				= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+	renderPassParams.pNext				= DE_NULL;
+	renderPassParams.flags				= 0;
+	renderPassParams.attachmentCount	= 1;
+	renderPassParams.pAttachments		= &colorAttachmentDesc;
+	renderPassParams.subpassCount		= 1;
+	renderPassParams.pSubpasses			= &subpassDesc;
+	renderPassParams.dependencyCount	= 0;
+	renderPassParams.pDependencies		= DE_NULL;
+
+	VK_CHECK(deviceInterface.createRenderPass(device, &renderPassParams, DE_NULL, &newRenderPass));
+	renderPass = vk::Move<VkRenderPass>(vk::check<VkRenderPass>(newRenderPass), Deleter<VkRenderPass>(deviceInterface, device, DE_NULL));
+}
+
+struct ShaderDescParams
+{
+	const char*				name;
+	VkShaderStageFlagBits	stage;
+};
+
+void createGraphicsShaderStages (Context& context, const VkDevice device, vector<ShaderDescParams> shaderDesc, vector<VkPipelineShaderStageCreateInfo>& shaderCreateParams)
+{
+	const DeviceInterface&				deviceInterface		= context.getDeviceInterface();
+
+	for (vector<ShaderDescParams>::iterator shaderDescIter = shaderDesc.begin(); shaderDescIter != shaderDesc.end(); shaderDescIter++)
+	{
+		VkPipelineShaderStageCreateInfo		shaderStageInfo;
+		VkShaderModule						shaderModule;
+		VkShaderModuleCreateInfo			shaderModuleInfo;
+
+		shaderModuleInfo.sType				= VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+		shaderModuleInfo.pNext				= DE_NULL;
+		shaderModuleInfo.flags				= 0;
+		shaderModuleInfo.codeSize			= context.getBinaryCollection().get(shaderDescIter->name).getSize();
+		shaderModuleInfo.pCode				= (const deUint32*)context.getBinaryCollection().get(shaderDescIter->name).getBinary();
+		VK_CHECK(deviceInterface.createShaderModule(device, &shaderModuleInfo, DE_NULL, &shaderModule));
+
+		shaderStageInfo.sType				= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+		shaderStageInfo.pNext				= DE_NULL;
+		shaderStageInfo.flags				= 0;
+		shaderStageInfo.stage				= shaderDescIter->stage;
+		shaderStageInfo.module				= shaderModule;
+		shaderStageInfo.pName				= "main";
+		shaderStageInfo.pSpecializationInfo	= DE_NULL;
+		shaderCreateParams.push_back(shaderStageInfo);
+	}
+}
+
+struct VertexDesc
+{
+	deUint32	location;
+	VkFormat	format;
+	deUint32	stride;
+	deUint32	offset;
+};
+
+void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
+{
+	for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
+	{
+		deUint32							bindingId = 0;
+		VkVertexInputBindingDescription		bindingDesc;
+		VkVertexInputAttributeDescription	attrDesc;
+
+		bindingDesc.binding		= bindingId;
+		bindingDesc.stride		= vertDescIter->stride;
+		bindingDesc.inputRate	= VK_VERTEX_INPUT_RATE_VERTEX;
+		bindingList.push_back(bindingDesc);
+
+		attrDesc.location		= vertDescIter->location;
+		attrDesc.binding		= bindingId;
+		attrDesc.format			= vertDescIter->format;
+		attrDesc.offset			= vertDescIter->offset;
+		attrList.push_back(attrDesc);
+
+		bindingId++;
+	}
+
+	vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+	vertexInputState.pNext = DE_NULL,
+	vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
+	vertexInputState.pVertexBindingDescriptions = &bindingList[0];
+	vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
+	vertexInputState.pVertexAttributeDescriptions = &attrList[0];
+}
+
+void createCommandBuffer (Context& context, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef)
+{
+	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
+	VkCommandPool				commandPool;
+	VkCommandPoolCreateInfo		commandPoolInfo;
+	VkCommandBufferAllocateInfo	commandBufferInfo;
+	VkCommandBuffer				commandBuffer;
+
+	commandPoolInfo.sType				= VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+	commandPoolInfo.pNext				= DE_NULL;
+	commandPoolInfo.flags				= 0;
+	commandPoolInfo.queueFamilyIndex	= queueFamilyNdx;
+
+	VK_CHECK(deviceInterface.createCommandPool(device, &commandPoolInfo, DE_NULL, &commandPool));
+
+	commandBufferInfo.sType					= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+	commandBufferInfo.pNext					= DE_NULL;
+	commandBufferInfo.commandPool			= commandPool;
+	commandBufferInfo.level					= VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+	commandBufferInfo.commandBufferCount	= 1;
+
+	VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
+	*commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, DE_NULL));
+}
+
+void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
+{
+	VkFenceCreateInfo		fenceState;
+	VkFenceCreateFlags		signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
+
+	fenceState.sType		= VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+	fenceState.pNext		= DE_NULL;
+	fenceState.flags		= signalFlag;
+
+	for (deUint32 ndx = 0; ndx < numFences; ndx++)
+		VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
+}
+
+void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
+{
+	for (deUint32 ndx = 0; ndx < numFences; ndx++)
+		deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
+}
+
+struct RenderInfo
+{
+	Context*						context;
+	deInt32							width;
+	deInt32							height;
+	deUint32						vertexBufferSize;
+	VkBuffer						vertexBuffer;
+	VkImage							image;
+	VkCommandBuffer					commandBuffer;
+	VkRenderPass					renderPass;
+	VkFramebuffer					framebuffer;
+	VkPipeline						pipeline;
+	deUint32						mipLevels;
+	const deUint32*					queueFamilyNdxList;
+	deUint32						queueFamilyNdxCount;
+	bool							setEvent;
+	bool							waitEvent;
+	VkEvent							event;
+	vector<VkImageMemoryBarrier>*	barriers;
+};
+
+void  recordRenderPass (const RenderInfo& renderInfo)
+{
+	const DeviceInterface&				deviceInterface			= renderInfo.context->getDeviceInterface();
+	const VkDeviceSize					bindingOffset			= 0;
+	const VkClearValue					clearValue				= makeClearValueColorF32(0.0, 0.0, 1.0, 1.0);
+	VkRenderPassBeginInfo				renderPassBeginState;
+	VkImageMemoryBarrier				renderBarrier;
+
+	renderPassBeginState.sType						= VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+	renderPassBeginState.pNext						= DE_NULL;
+	renderPassBeginState.renderPass					= renderInfo.renderPass;
+	renderPassBeginState.framebuffer				= renderInfo.framebuffer;
+	renderPassBeginState.renderArea.offset.x		= 0;
+	renderPassBeginState.renderArea.offset.y		= 0;
+	renderPassBeginState.renderArea.extent.width	= renderInfo.width;
+	renderPassBeginState.renderArea.extent.height	= renderInfo.height;
+	renderPassBeginState.clearValueCount			= 1;
+	renderPassBeginState.pClearValues				= &clearValue;
+
+	deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE);
+	if (renderInfo.waitEvent)
+		deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
+	deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
+	deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
+	deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
+	if (renderInfo.setEvent)
+		deviceInterface.cmdSetEvent(renderInfo.commandBuffer, renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
+	deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer);
+
+	renderBarrier.sType								= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+	renderBarrier.pNext								= DE_NULL;
+	renderBarrier.srcAccessMask						= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+	renderBarrier.dstAccessMask						= VK_ACCESS_TRANSFER_READ_BIT;
+	renderBarrier.oldLayout							= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+	renderBarrier.newLayout							= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+	renderBarrier.srcQueueFamilyIndex				= renderInfo.queueFamilyNdxList[0];
+	renderBarrier.dstQueueFamilyIndex				= renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
+	renderBarrier.image								= renderInfo.image;
+	renderBarrier.subresourceRange.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
+	renderBarrier.subresourceRange.baseMipLevel		= 0;
+	renderBarrier.subresourceRange.levelCount		= renderInfo.mipLevels;
+	renderBarrier.subresourceRange.baseArrayLayer	= 0;
+	renderBarrier.subresourceRange.layerCount		= 1;
+	renderInfo.barriers->push_back(renderBarrier);
+}
+
+struct TransferInfo
+{
+	Context*						context;
+	VkCommandBuffer					commandBuffer;
+	deUint32						width;
+	deUint32						height;
+	VkImage							image;
+	VkBuffer						buffer;
+	VkDeviceSize					size;
+	deUint32						mipLevel;
+	VkOffset3D						imageOffset;
+	vector<VkBufferMemoryBarrier>*	barriers;
+};
+
+void copyToCPU (TransferInfo* transferInfo)
+{
+	const DeviceInterface&				deviceInterface			= transferInfo->context->getDeviceInterface();
+	VkBufferImageCopy					copyState;
+
+	copyState.bufferOffset						= 0;
+	copyState.bufferRowLength					= transferInfo->width;
+	copyState.bufferImageHeight					= transferInfo->height;
+	copyState.imageSubresource.aspectMask		= VK_IMAGE_ASPECT_COLOR_BIT;
+	copyState.imageSubresource.mipLevel			= transferInfo->mipLevel;
+	copyState.imageSubresource.baseArrayLayer	= 0;
+	copyState.imageSubresource.layerCount		= 1;
+	copyState.imageOffset						= transferInfo->imageOffset;
+	copyState.imageExtent.width					= (deInt32)(transferInfo->width);
+	copyState.imageExtent.height				= (deInt32)(transferInfo->height);
+	copyState.imageExtent.depth					= 1;
+
+	deviceInterface.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, &copyState);
+
+	{
+		VkBufferMemoryBarrier	bufferBarrier;
+		bufferBarrier.sType					= VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+		bufferBarrier.pNext					= DE_NULL;
+		bufferBarrier.srcAccessMask			= VK_ACCESS_TRANSFER_WRITE_BIT;
+		bufferBarrier.dstAccessMask			= VK_ACCESS_HOST_READ_BIT;
+		bufferBarrier.srcQueueFamilyIndex	= VK_QUEUE_FAMILY_IGNORED;
+		bufferBarrier.dstQueueFamilyIndex	= VK_QUEUE_FAMILY_IGNORED;
+		bufferBarrier.buffer				= transferInfo->buffer;
+		bufferBarrier.offset				= 0;
+		bufferBarrier.size					= transferInfo->size;
+		transferInfo->barriers->push_back(bufferBarrier);
+	}
+}
+
+struct TestContext
+{
+	Context&					context;
+	const VkDevice&				device;
+	const tcu::Vec4*			vertices;
+	deUint32					numVertices;
+	tcu::IVec2					renderDimension;
+	VkFence						fences[2];
+	VkDeviceSize				renderSize;
+	MovePtr<Allocation>			renderReadBuffer;
+	MovePtr<Allocation>			vertexBufferAllocation;
+	vk::Move<VkBuffer>			vertexBuffer;
+	vk::Move<VkBuffer>			renderBuffer;
+	bool						setEvent;
+	bool						waitEvent;
+	VkEvent						event;
+	vk::Move<VkImage>			image;
+	vk::Move<VkImageView>		imageView;
+	vk::Move<VkCommandBuffer>	cmdBuffer;
+	MovePtr<Allocation>			imageAllocation;
+
+	TestContext(Context& context_, const VkDevice& device_)
+		: context		(context_)
+		, device		(device_)
+		, numVertices	(0)
+		, setEvent		(DE_FALSE)
+		, waitEvent		(DE_FALSE)
+	{
+		createFences(context.getDeviceInterface(), device, DE_NULL, DE_LENGTH_OF_ARRAY(fences), fences);
+	}
+
+	~TestContext()
+	{
+		destroyFences(context.getDeviceInterface(), device, DE_LENGTH_OF_ARRAY(fences), fences);
+	}
+};
+
+void generateWork (TestContext& testContext)
+{
+	const DeviceInterface&						deviceInterface		= testContext.context.getDeviceInterface();
+	const deUint32								queueFamilyNdx		= testContext.context.getUniversalQueueFamilyIndex();
+	vk::Move<VkRenderPass>						renderPass;
+	VkPipelineCache								cache;
+	VkPipelineLayout							layout;
+	VkPipeline									pipeline;
+	VkFramebuffer								framebuffer;
+	vector<ShaderDescParams>					shaderDescParams;
+	vector<VkPipelineShaderStageCreateInfo>		shaderStageCreateParams;
+	VertexDesc									vertexDesc;
+	vector<VertexDesc>							vertexDescList;
+	vector<VkVertexInputAttributeDescription>	attrList;
+	vector<VkBufferMemoryBarrier>				bufferMemoryBarrier;
+	deUint32									memoryBarrierNdx;
+	deUint32									bufferMemoryBarrierNdx;
+	deUint32									imageMemoryBarrierNdx;
+	vector<VkVertexInputBindingDescription>		bindingList;
+	VkPipelineVertexInputStateCreateInfo		vertexInputState;
+	VkPipelineInputAssemblyStateCreateInfo		inputAssemblyState;
+	VkPipelineDepthStencilStateCreateInfo		depthStencilState;
+	VkPipelineColorBlendAttachmentState			blendAttachment;
+	VkPipelineColorBlendStateCreateInfo			blendState;
+	VkPipelineDynamicStateCreateInfo			dynamicState;
+	VkPipelineLayoutCreateInfo					pipelineLayoutState;
+	VkGraphicsPipelineCreateInfo				pipelineState;
+	VkPipelineCacheCreateInfo					cacheState;
+	VkViewport									viewport;
+	VkPipelineViewportStateCreateInfo			viewportInfo;
+	VkRect2D									scissor;
+	BufferParameters							bufferParameters;
+	Buffer										buffer;
+	RenderInfo									renderInfo;
+	ImageParameters								imageParameters;
+	Image										image;
+	VkPipelineRasterizationStateCreateInfo		rasterState;
+	VkPipelineMultisampleStateCreateInfo		multisampleState;
+	VkFramebufferCreateInfo						fbState;
+	VkCommandBufferBeginInfo					commandBufRecordState;
+	VkCommandBufferInheritanceInfo				inheritanceInfo;
+	RenderPassParameters						renderPassParameters;
+	TransferInfo								transferInfo;
+	vector<void*>								barrierList;
+	VkExtent3D									extent;
+	vector<VkMemoryBarrier>						memoryBarriers;
+	vector<VkBufferMemoryBarrier>				bufferBarriers;
+	vector<VkImageMemoryBarrier>				imageBarriers;
+
+	memoryBarrierNdx			= 0;
+	bufferMemoryBarrierNdx		= 0;
+	imageMemoryBarrierNdx		= 0;
+	buffer.memoryBarrier.resize(memoryBarrierNdx);
+	bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
+	image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
+
+	memoryBarriers.resize(0);
+	bufferBarriers.resize(0);
+	imageBarriers.resize(0);
+
+	bufferParameters.context				= &testContext.context;
+	bufferParameters.device					= testContext.device;
+	bufferParameters.memory					= testContext.vertices;
+	bufferParameters.size					= testContext.numVertices * sizeof(tcu::Vec4);
+	bufferParameters.usage					= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+	bufferParameters.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
+	bufferParameters.queueFamilyCount		= 1;
+	bufferParameters.queueFamilyIndex		= &queueFamilyNdx;
+	bufferParameters.inputBarrierFlags		= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+	createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
+	testContext.vertexBufferAllocation		= buffer.allocation;
+	testContext.vertexBuffer				= buffer.buffer;
+
+	bufferParameters.context				= &testContext.context;
+	bufferParameters.device					= testContext.device;
+	bufferParameters.memory					= DE_NULL;
+	bufferParameters.size					= testContext.renderSize;
+	bufferParameters.usage					= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+	bufferParameters.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
+	bufferParameters.queueFamilyCount		= 1;
+	bufferParameters.queueFamilyIndex		= &queueFamilyNdx;
+	bufferParameters.inputBarrierFlags		= 0;
+	createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
+	testContext.renderReadBuffer			= buffer.allocation;
+	testContext.renderBuffer				= buffer.buffer;
+
+	extent.width							= testContext.renderDimension.x();
+	extent.height							= testContext.renderDimension.y();
+	extent.depth							= 1;
+
+	imageParameters.context					= &testContext.context;
+	imageParameters.device					= testContext.device;
+	imageParameters.imageType 				= VK_IMAGE_TYPE_2D;
+	imageParameters.format					= VK_FORMAT_R8G8B8A8_UNORM;
+	imageParameters.extent3D				= extent;
+	imageParameters.mipLevels				= 1;
+	imageParameters.samples					= VK_SAMPLE_COUNT_1_BIT;
+	imageParameters.tiling					= VK_IMAGE_TILING_OPTIMAL;
+	imageParameters.usage					= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+	imageParameters.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;
+	imageParameters.queueFamilyCount		= 1;
+	imageParameters.queueFamilyNdxList		= &queueFamilyNdx;
+	imageParameters.initialLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
+	imageParameters.finalLayout				= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+	imageParameters.barrierInputMask		= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+	createVulkanImage(imageParameters, image, MemoryRequirement::Any);
+	testContext.imageAllocation				= image.allocation;
+	testContext.image						= image.image;
+
+	renderPassParameters.context			= &testContext.context;
+	renderPassParameters.device				= testContext.device;
+	renderPassParameters.colorFormat		= VK_FORMAT_R8G8B8A8_UNORM;
+	renderPassParameters.colorSamples		= VK_SAMPLE_COUNT_1_BIT;
+	createColorOnlyRenderPass(renderPassParameters, renderPass);
+
+	ShaderDescParams param;
+	param.name = "glslvert";
+	param.stage = VK_SHADER_STAGE_VERTEX_BIT;
+	shaderDescParams.push_back(param);
+
+	param.name = "glslfrag";
+	param.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+	shaderDescParams.push_back(param);
+	createGraphicsShaderStages(testContext.context, testContext.device, shaderDescParams, shaderStageCreateParams);
+
+	vertexDesc.location = 0;
+	vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
+	vertexDesc.stride = sizeof(tcu::Vec4);
+	vertexDesc.offset = 0;
+	vertexDescList.push_back(vertexDesc);
+
+	createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
+
+	inputAssemblyState.sType					= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+	inputAssemblyState.pNext					= DE_NULL;
+	inputAssemblyState.topology					= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+	inputAssemblyState.primitiveRestartEnable	= DE_FALSE;
+
+	viewport.x									= 0;
+	viewport.y									= 0;
+	viewport.width								= (float)testContext.renderDimension.x();
+	viewport.height								= (float)testContext.renderDimension.y();
+	viewport.minDepth							= 0;
+	viewport.maxDepth							= 1;
+
+	scissor.offset.x							= 0;
+	scissor.offset.y							= 0;
+	scissor.extent.width						= testContext.renderDimension.x();
+	scissor.extent.height						= testContext.renderDimension.y();
+
+	viewportInfo.sType							= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+	viewportInfo.pNext							= DE_NULL;
+	viewportInfo.flags							= 0;
+	viewportInfo.viewportCount					= 1;
+	viewportInfo.pViewports						= &viewport;
+	viewportInfo.scissorCount					= 1;
+	viewportInfo.pScissors						= &scissor;
+
+	rasterState.sType							= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+	rasterState.pNext							= DE_NULL;
+	rasterState.flags							= 0;
+	rasterState.depthClampEnable				= VK_TRUE;
+	rasterState.rasterizerDiscardEnable			= VK_FALSE;
+	rasterState.polygonMode						= VK_POLYGON_MODE_FILL;
+	rasterState.cullMode						= VK_CULL_MODE_NONE;
+	rasterState.frontFace						= VK_FRONT_FACE_COUNTER_CLOCKWISE;
+	rasterState.depthBiasEnable					= VK_FALSE;
+	rasterState.lineWidth						= 1;
+
+	multisampleState.sType						= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+	multisampleState.pNext						= DE_NULL;
+	multisampleState.flags						= 0;
+	multisampleState.rasterizationSamples		= VK_SAMPLE_COUNT_1_BIT;
+	multisampleState.sampleShadingEnable		= VK_FALSE;
+	multisampleState.pSampleMask				= DE_NULL;
+	multisampleState.alphaToCoverageEnable		= VK_FALSE;
+	multisampleState.alphaToOneEnable			= VK_FALSE;
+
+	depthStencilState.sType						= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+	depthStencilState.pNext						= DE_NULL;
+	depthStencilState.flags						= 0;
+	depthStencilState.depthTestEnable			= VK_FALSE;
+	depthStencilState.depthWriteEnable			= VK_FALSE;
+	depthStencilState.depthBoundsTestEnable		= VK_FALSE;
+	depthStencilState.stencilTestEnable			= VK_FALSE;
+
+	blendAttachment.blendEnable					= VK_FALSE;
+
+	blendState.sType							= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+	blendState.pNext							= DE_NULL;
+	blendState.flags							= 0;
+	blendState.logicOpEnable					= VK_FALSE;
+	blendState.attachmentCount					= 1;
+	blendState.pAttachments						= &blendAttachment;
+
+	dynamicState.sType							= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+	dynamicState.pNext							= DE_NULL;
+	dynamicState.flags							= 0;
+	dynamicState.dynamicStateCount				= 0;
+	dynamicState.pDynamicStates					= DE_NULL;
+
+	pipelineLayoutState.sType					= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+	pipelineLayoutState.pNext					= DE_NULL;
+	pipelineLayoutState.flags					= 0;
+	pipelineLayoutState.setLayoutCount			= 0;
+	pipelineLayoutState.pSetLayouts				= DE_NULL;
+	pipelineLayoutState.pushConstantRangeCount	= 0;
+	pipelineLayoutState.pPushConstantRanges		= DE_NULL;
+	VK_CHECK(deviceInterface.createPipelineLayout(testContext.device, &pipelineLayoutState, DE_NULL, &layout));
+
+	pipelineState.sType							= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+	pipelineState.pNext							= DE_NULL;
+	pipelineState.flags							= 0;
+	pipelineState.stageCount					= (deUint32)shaderStageCreateParams.size();
+	pipelineState.pStages						= &shaderStageCreateParams[0];
+	pipelineState.pVertexInputState				= &vertexInputState;
+	pipelineState.pInputAssemblyState			= &inputAssemblyState;
+	pipelineState.pTessellationState			= DE_NULL;
+	pipelineState.pViewportState				= &viewportInfo;
+	pipelineState.pRasterizationState			= &rasterState;
+	pipelineState.pMultisampleState				= &multisampleState;
+	pipelineState.pDepthStencilState			= &depthStencilState;
+	pipelineState.pColorBlendState				= &blendState;
+	pipelineState.pDynamicState					= &dynamicState;
+	pipelineState.layout						= layout;
+	pipelineState.renderPass					= renderPass.get();
+	pipelineState.subpass						= 0;
+	pipelineState.basePipelineHandle			= DE_NULL;
+	pipelineState.basePipelineIndex				= 0;
+
+	cacheState.sType							= VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+	cacheState.pNext							= DE_NULL;
+	cacheState.flags							= 0;
+	cacheState.initialDataSize					= 0;
+	cacheState.pInitialData						= DE_NULL;
+
+	VK_CHECK(deviceInterface.createPipelineCache(testContext.device, &cacheState, DE_NULL, &cache));
+	VK_CHECK(deviceInterface.createGraphicsPipelines(testContext.device, cache, 1, &pipelineState, DE_NULL, &pipeline));
+
+	fbState.sType								= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+	fbState.pNext								= DE_NULL;
+	fbState.flags								= 0;
+	fbState.renderPass							= renderPass.get();
+	fbState.attachmentCount						= 1;
+	fbState.pAttachments						= &image.imageView.get();
+	fbState.width								= (deUint32)testContext.renderDimension.x();
+	fbState.height								= (deUint32)testContext.renderDimension.y();
+	fbState.layers								= 1;
+	VK_CHECK(deviceInterface.createFramebuffer(testContext.device, &fbState, DE_NULL, &framebuffer));
+	testContext.imageView						= image.imageView;
+
+	inheritanceInfo.sType						= VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+	inheritanceInfo.pNext						= DE_NULL;
+	inheritanceInfo.renderPass					= renderPass.get();
+	inheritanceInfo.subpass						= 0;
+	inheritanceInfo.framebuffer					= framebuffer;
+	inheritanceInfo.occlusionQueryEnable		= VK_FALSE;
+
+	commandBufRecordState.sType					= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+	commandBufRecordState.pNext					= DE_NULL;
+	commandBufRecordState.flags					= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+	commandBufRecordState.pInheritanceInfo		= &inheritanceInfo;
+	VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
+
+	deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
+										VK_PIPELINE_STAGE_HOST_BIT,
+										VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+										DE_FALSE,
+										(deUint32)memoryBarriers.size(), &memoryBarriers[0],
+										(deUint32)bufferBarriers.size(), &bufferBarriers[0],
+										(deUint32)imageBarriers.size(), &imageBarriers[0]);
+
+	memoryBarriers.resize(0);
+	bufferBarriers.resize(0);
+	imageBarriers.resize(0);
+
+	renderInfo.context				= &testContext.context;
+	renderInfo.width				= testContext.renderDimension.x();
+	renderInfo.height				= testContext.renderDimension.y();
+	renderInfo.vertexBufferSize		= testContext.numVertices;
+	renderInfo.vertexBuffer			= testContext.vertexBuffer.get();
+	renderInfo.image				= testContext.image.get();
+	renderInfo.commandBuffer		= testContext.cmdBuffer.get();
+	renderInfo.renderPass			= renderPass.get();
+	renderInfo.framebuffer			= framebuffer;
+	renderInfo.pipeline				= pipeline;
+	renderInfo.mipLevels			= 1;
+	renderInfo.queueFamilyNdxList	= &queueFamilyNdx;
+	renderInfo.queueFamilyNdxCount	= 1;
+	renderInfo.setEvent				= testContext.setEvent;
+	renderInfo.waitEvent			= testContext.waitEvent;
+	renderInfo.event				= testContext.event;
+	renderInfo.barriers				= &imageBarriers;
+	recordRenderPass(renderInfo);
+
+	deviceInterface.cmdPipelineBarrier(	renderInfo.commandBuffer,
+										VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
+										VK_PIPELINE_STAGE_TRANSFER_BIT,
+										DE_FALSE,
+										(deUint32)memoryBarriers.size(), &memoryBarriers[0],
+										(deUint32)bufferBarriers.size(), &bufferBarriers[0],
+										(deUint32)imageBarriers.size(), &imageBarriers[0]);
+
+	memoryBarriers.resize(0);
+	bufferBarriers.resize(0);
+	imageBarriers.resize(0);
+
+	transferInfo.context = &testContext.context;
+	transferInfo.commandBuffer		= renderInfo.commandBuffer;
+	transferInfo.width				= testContext.renderDimension.x();
+	transferInfo.height				= testContext.renderDimension.y();
+	transferInfo.image				= renderInfo.image;
+	transferInfo.buffer				= testContext.renderBuffer.get();
+	transferInfo.size				= testContext.renderSize;
+	transferInfo.mipLevel			= 0;
+	transferInfo.imageOffset.x		= 0;
+	transferInfo.imageOffset.y		= 0;
+	transferInfo.imageOffset.z		= 0;
+	transferInfo.barriers			= &bufferBarriers;
+	copyToCPU(&transferInfo);
+
+	deviceInterface.cmdPipelineBarrier(	transferInfo.commandBuffer,
+										VK_PIPELINE_STAGE_TRANSFER_BIT,
+										VK_PIPELINE_STAGE_HOST_BIT,
+										DE_FALSE,
+										(deUint32)memoryBarriers.size(), &memoryBarriers[0],
+										(deUint32)bufferBarriers.size(), &bufferBarriers[0],
+										(deUint32)imageBarriers.size(), &imageBarriers[0]);
+
+	memoryBarriers.resize(0);
+	bufferBarriers.resize(0);
+	imageBarriers.resize(0);
+
+	VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer));
+}
+
+static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
+{
+	for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
+	{
+		submitInfo[ndx].sType					= VK_STRUCTURE_TYPE_SUBMIT_INFO;
+		submitInfo[ndx].pNext					= DE_NULL;
+		submitInfo[ndx].waitSemaphoreCount		= 0;
+		submitInfo[ndx].pWaitSemaphores			= DE_NULL;
+		submitInfo[ndx].pWaitDstStageMask		= DE_NULL;
+		submitInfo[ndx].commandBufferCount		= 1;
+		submitInfo[ndx].signalSemaphoreCount	= 0;
+		submitInfo[ndx].pSignalSemaphores		= DE_NULL;
+	}
+}
+
+tcu::TestStatus testFences (Context& context)
+{
+	TestLog&					log					= context.getTestContext().getLog();
+	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
+	const InstanceInterface&	instanceInterface	= context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
+	const VkQueue				queue				= context.getUniversalQueue();
+	const deUint32				queueFamilyIdx		= context.getUniversalQueueFamilyIndex();
+	vk::Move<VkDevice>			device				= createTestDevice(instanceInterface, physicalDevice);
+	VkResult					testStatus;
+	VkResult					fenceStatus;
+	TestContext					testContext(context, device.get());
+	VkSubmitInfo				submitInfo;
+	VkMappedMemoryRange			range;
+	void*						resultImage;
+
+	const tcu::Vec4				vertices[]			=
+	{
+		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
+		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
+		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
+	};
+
+	testContext.vertices = vertices;
+	testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
+	testContext.renderDimension = tcu::IVec2(256, 256);
+	testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
+
+	createCommandBuffer(testContext.context, device.get(), queueFamilyIdx, &testContext.cmdBuffer);
+	generateWork(testContext);
+
+	initSubmitInfo(&submitInfo, 1);
+	submitInfo.pCommandBuffers		= &testContext.cmdBuffer.get();
+
+	VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
+
+	fenceStatus = deviceInterface.getFenceStatus(device.get(), testContext.fences[0]);
+	if (fenceStatus != VK_NOT_READY)
+	{
+		log << TestLog::Message << "testSynchronizationPrimitives fence should be reset but status is " << fenceStatus << TestLog::EndMessage;
+		return tcu::TestStatus::fail("Fence in incorrect state");
+	}
+
+	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+	if (testStatus != VK_TIMEOUT)
+	{
+		log << TestLog::Message << "testSynchPrimitives failed to wait for all fences" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("Failed to wait for mulitple fences");
+	}
+
+	testStatus = deviceInterface.waitForFences(device.get(),
+												1,
+												&testContext.fences[1],
+												DE_TRUE,
+												DEFAULT_TIMEOUT);
+
+	if (testStatus != VK_TIMEOUT)
+	{
+		log << TestLog::Message << "testSyncPrimitives failed to wait for single fence" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("failed to wait for single fence");
+	}
+
+	testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+	if (testStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("failed to wait for a set fence");
+	}
+
+	fenceStatus = deviceInterface.getFenceStatus(device.get(), testContext.fences[0]);
+	if (fenceStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << fenceStatus << TestLog::EndMessage;
+		return tcu::TestStatus::fail("Fence in incorrect state");
+	}
+
+	range.sType			= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+	range.pNext			= DE_NULL;
+	range.memory		= testContext.renderReadBuffer->getMemory();
+	range.offset		= 0;
+	range.size			= testContext.renderSize;
+	VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+	resultImage = testContext.renderReadBuffer->getHostPtr();
+
+	log << TestLog::Image(	"result",
+							"result",
+							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+									testContext.renderDimension.x(),
+									testContext.renderDimension.y(),
+									1,
+									resultImage));
+
+	return TestStatus::pass("synchornization-fences passed");
+}
+
+vk::refdetails::Checked<VkSemaphore> createSemaphore (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
+{
+	VkSemaphoreCreateInfo		semaCreateInfo;
+	VkSemaphore					semaphore;
+
+	semaCreateInfo.sType		= VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+	semaCreateInfo.pNext		= DE_NULL;
+	semaCreateInfo.flags		= 0;
+	VK_CHECK(deviceInterface.createSemaphore(device, &semaCreateInfo, allocationCallbacks, &semaphore));
+
+	return vk::check<VkSemaphore>(semaphore);
+}
+
+tcu::TestStatus testSemaphores (Context& context)
+{
+	TestLog&					log					= context.getTestContext().getLog();
+	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
+	const InstanceInterface&	instanceInterface	= context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
+	vk::Move<VkDevice>			device				= createTestDevice(instanceInterface, physicalDevice);
+	VkQueue						queue[2];
+	const deUint32				queueFamilyIdx		= context.getUniversalQueueFamilyIndex();
+	VkResult					testStatus;
+	TestContext					testContext1(context, device.get());
+	TestContext					testContext2(context, device.get());
+	Unique<VkSemaphore>			semaphore(createSemaphore(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkSemaphore>(deviceInterface, device.get(), DE_NULL));
+	VkSubmitInfo				submitInfo[2];
+	VkMappedMemoryRange			range;
+	void*						resultImage;
+
+	deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
+	deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
+
+	const tcu::Vec4		vertices1[]			=
+	{
+		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
+		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
+		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
+	};
+
+	const tcu::Vec4		vertices2[]			=
+	{
+		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
+		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
+		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
+	};
+
+	testContext1.vertices = vertices1;
+	testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
+	testContext1.renderDimension = tcu::IVec2(256, 256);
+	testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
+
+	testContext2.vertices = vertices2;
+	testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
+	testContext2.renderDimension = tcu::IVec2(256, 256);
+	testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
+
+	createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
+	generateWork(testContext1);
+
+	createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
+	generateWork(testContext2);
+
+	initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
+
+	// The difference between the two submit infos is that each will use a unique cmd buffer,
+	// and one will signal a semaphore but not wait on a semaphore, the other will wait on the
+	// semaphore but not signal a semaphore
+	submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
+	submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
+
+	submitInfo[0].signalSemaphoreCount = 1;
+	submitInfo[0].pSignalSemaphores = &semaphore.get();
+	submitInfo[1].waitSemaphoreCount = 1;
+	submitInfo[1].pWaitSemaphores = &semaphore.get();
+
+	VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
+
+	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+	if (testStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("failed to wait for a set fence");
+	}
+
+	range.sType			= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+	range.pNext			= DE_NULL;
+	range.memory		= testContext1.renderReadBuffer->getMemory();
+	range.offset		= 0;
+	range.size			= testContext1.renderSize;
+	VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+	resultImage = testContext1.renderReadBuffer->getHostPtr();
+
+	log << TestLog::Image(	"result",
+							"result",
+							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+									testContext1.renderDimension.x(),
+									testContext1.renderDimension.y(),
+									1,
+									resultImage));
+
+	VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
+
+	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+	if (testStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("failed to wait for a set fence");
+	}
+
+	range.sType			= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+	range.pNext			= DE_NULL;
+	range.memory		= testContext2.renderReadBuffer->getMemory();
+	range.offset		= 0;
+	range.size			= testContext2.renderSize;
+	VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+	resultImage = testContext2.renderReadBuffer->getHostPtr();
+
+	log << TestLog::Image(	"result",
+							"result",
+							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+									testContext2.renderDimension.x(),
+									testContext2.renderDimension.y(),
+									1,
+									resultImage));
+
+	return tcu::TestStatus::pass("synchronization-semaphores passed");
+}
+
+vk::refdetails::Checked<VkEvent> createEvent (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
+{
+	VkEventCreateInfo		eventCreateInfo;
+	VkEvent					event;
+
+	eventCreateInfo.sType		= VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+	eventCreateInfo.pNext		= DE_NULL;
+	eventCreateInfo.flags		= 0;
+	VK_CHECK(deviceInterface.createEvent(device, &eventCreateInfo, allocationCallbacks, &event));
+
+	return vk::check<VkEvent>(event);
+}
+
+tcu::TestStatus testEvents (Context& context)
+{
+	TestLog&					log					= context.getTestContext().getLog();
+	const DeviceInterface&		deviceInterface		= context.getDeviceInterface();
+	const InstanceInterface&	instanceInterface	= context.getInstanceInterface();
+	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
+	vk::Move<VkDevice>			device				= createTestDevice(instanceInterface, physicalDevice);
+	VkQueue						queue[2];
+	const deUint32				queueFamilyIdx		= context.getUniversalQueueFamilyIndex();
+	VkResult					testStatus;
+	VkResult					eventStatus;
+	TestContext					testContext1(context, device.get());
+	TestContext					testContext2(context, device.get());
+	Unique<VkEvent>				event(createEvent(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkEvent>(deviceInterface, device.get(), DE_NULL));
+	VkSubmitInfo				submitInfo[2];
+	VkMappedMemoryRange			range;
+	void*						resultImage;
+
+	deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
+	deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
+
+	const tcu::Vec4		vertices1[]			=
+	{
+		tcu::Vec4( 0.5f,  0.5f, 0.0f, 1.0f),
+		tcu::Vec4(-0.5f,  0.5f, 0.0f, 1.0f),
+		tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
+	};
+
+	const tcu::Vec4		vertices2[]			=
+	{
+		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
+		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
+		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
+	};
+
+	testContext1.vertices = vertices1;
+	testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
+	testContext1.renderDimension = tcu::IVec2(256, 256);
+	testContext1.setEvent = DE_TRUE;
+	testContext1.event = event.get();
+	testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
+
+	testContext2.vertices = vertices2;
+	testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
+	testContext2.renderDimension = tcu::IVec2(256, 256);
+	testContext2.waitEvent = DE_TRUE;
+	testContext2.event = event.get();
+	testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
+
+	createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
+	generateWork(testContext1);
+
+	createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
+	generateWork(testContext2);
+
+	initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
+	submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
+	submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
+
+	eventStatus = deviceInterface.getEventStatus(device.get(), event.get());
+	if (eventStatus != VK_EVENT_RESET)
+	{
+		log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << eventStatus << TestLog::EndMessage;
+		return tcu::TestStatus::fail("Event in incorrect status");
+	}
+
+	// Now the two contexts are submitted normally, so, context1 and set the event and context2 can wait for the event
+	VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
+	VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
+
+	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+	if (testStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set fence" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("failed to wait for set fence");
+	}
+
+	range.sType			= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+	range.pNext			= DE_NULL;
+	range.memory		= testContext1.renderReadBuffer->getMemory();
+	range.offset		= 0;
+	range.size			= testContext1.renderSize;
+	VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+	resultImage = testContext1.renderReadBuffer->getHostPtr();
+
+	log << TestLog::Image(	"result",
+							"result",
+							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+									testContext1.renderDimension.x(),
+									testContext1.renderDimension.y(),
+									1,
+									resultImage));
+
+	testStatus  = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
+	if (testStatus != VK_SUCCESS)
+	{
+		log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
+		return tcu::TestStatus::fail("failed to wait for a set fence");
+	}
+
+	range.sType			= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+	range.pNext			= DE_NULL;
+	range.memory		= testContext2.renderReadBuffer->getMemory();
+	range.offset		= 0;
+	range.size			= testContext2.renderSize;
+	VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
+	resultImage = testContext2.renderReadBuffer->getHostPtr();
+
+	log << TestLog::Image(	"result",
+							"result",
+							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+									tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
+									testContext2.renderDimension.x(),
+									testContext2.renderDimension.y(),
+									1,
+									resultImage));
+
+	return tcu::TestStatus::pass("synchronization-events passed");
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createSynchronizationTests (tcu::TestContext& textCtx)
+{
+	de::MovePtr<tcu::TestCaseGroup> synchTests  (new tcu::TestCaseGroup(textCtx, "synchronization", "Vulkan Synchronization Tests"));
+
+	addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
+	addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores);
+	addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
+
+	return synchTests.release();
+}
+
+
+}; // vkt
diff --git a/external/vulkancts/modules/vulkan/vktSynchronization.hpp b/external/vulkancts/modules/vulkan/vktSynchronization.hpp
new file mode 100644
index 0000000..44c4585
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/vktSynchronization.hpp
@@ -0,0 +1,47 @@
+#ifndef _VKTSYNCHRONIZATION_HPP
+#define _VKTSYNCHRONIZATION_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be
+ * included in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by
+ * Khronos, at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Platform Synchronization tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+
+tcu::TestCaseGroup*		createSynchronizationTests		(tcu::TestContext& testCtx);
+
+} // vkt
+
+#endif // _VKTSYNCHRONIZATION_HPP
diff --git a/external/vulkancts/modules/vulkan/vktTestPackage.cpp b/external/vulkancts/modules/vulkan/vktTestPackage.cpp
index 3b50384..52aca99 100644
--- a/external/vulkancts/modules/vulkan/vktTestPackage.cpp
+++ b/external/vulkancts/modules/vulkan/vktTestPackage.cpp
@@ -68,6 +68,7 @@
 #include "vktImageTests.hpp"
 #include "vktInfoTests.hpp"
 #include "vktWsiTests.hpp"
+#include "vktSynchronization.hpp"
 
 #include <vector>
 #include <sstream>
@@ -323,6 +324,7 @@
 	addChild(compute::createTests		(m_testCtx));
 	addChild(image::createTests			(m_testCtx));
 	addChild(wsi::createTests			(m_testCtx));
+	addChild(createSynchronizationTests	(m_testCtx));
 }
 
 } // vkt
diff --git a/framework/delibs/cmake/CFlags.cmake b/framework/delibs/cmake/CFlags.cmake
index ff25740..98f0252 100644
--- a/framework/delibs/cmake/CFlags.cmake
+++ b/framework/delibs/cmake/CFlags.cmake
@@ -49,6 +49,10 @@
 	set(CMAKE_C_FLAGS			"${CMAKE_C_FLAGS} ${TARGET_FLAGS} ${WARNING_FLAGS} -ansi -pedantic ")
 	set(CMAKE_CXX_FLAGS			"${CMAKE_CXX_FLAGS} ${TARGET_FLAGS} ${WARNING_FLAGS}")
 
+	# Force compiler to generate code where integers have well defined overflow
+	# Turn on -Wstrict-overflow=5 and check all warnings before removing
+	set(CMAKE_C_FLAGS			"${CMAKE_C_FLAGS} -fwrapv")
+	set(CMAKE_CXX_FLAGS			"${CMAKE_CXX_FLAGS} -fwrapv")
 elseif (DE_COMPILER_IS_MSC)
 	# Compiler flags for msc
 
diff --git a/modules/gles31/functional/es31fGeometryShaderTests.cpp b/modules/gles31/functional/es31fGeometryShaderTests.cpp
index a1b2503..3926a8e 100644
--- a/modules/gles31/functional/es31fGeometryShaderTests.cpp
+++ b/modules/gles31/functional/es31fGeometryShaderTests.cpp
@@ -2600,8 +2600,8 @@
 
 		tcu::Vec2 range = tcu::Vec2(1.0f, 1.0f);
 
-		if (m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_point_size"))
-			TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension.");
+		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_point_size"))
+			TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_point_size extension.");
 
 		m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, range.getPtr());
 		if (range.y() < requiredPointSize)
diff --git a/modules/gles31/functional/es31fNegativePreciseTests.cpp b/modules/gles31/functional/es31fNegativePreciseTests.cpp
index 934b78b..c21cb7b 100644
--- a/modules/gles31/functional/es31fNegativePreciseTests.cpp
+++ b/modules/gles31/functional/es31fNegativePreciseTests.cpp
@@ -192,54 +192,6 @@
 	ctx.endSection();
 }
 
-void precise_as_macro_name (NegativeTestContext& ctx)
-{
-	TCU_CHECK_AND_THROW(NotSupportedError,
-		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
-		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
-
-	ctx.beginSection("Test precise keyword as macro name.");
-	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
-		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_MACRO_NAME);
-	ctx.endSection();
-}
-
-void precise_as_macro_and_variable (NegativeTestContext& ctx)
-{
-	TCU_CHECK_AND_THROW(NotSupportedError,
-		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
-		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
-
-	ctx.beginSection("Test precise keyword as macro and variable name.");
-	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
-		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_MACRO_AND_VARIABLE);
-	ctx.endSection();
-}
-
-void precise_as_macro_and_function (NegativeTestContext& ctx)
-{
-	TCU_CHECK_AND_THROW(NotSupportedError,
-		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
-		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
-
-	ctx.beginSection("Test precise keyword as macro and function name.");
-	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
-		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_MACRO_AND_FUNCTION);
-	ctx.endSection();
-}
-
-void precise_as_macro_and_argument (NegativeTestContext& ctx)
-{
-	TCU_CHECK_AND_THROW(NotSupportedError,
-		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
-		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
-
-	ctx.beginSection("Test precise keyword as macro and argument name.");
-	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
-		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_MACRO_AND_ARGUMENT);
-	ctx.endSection();
-}
-
 } // anonymous
 
 std::vector<FunctionContainer> getNegativePreciseTestFunctions (void)
@@ -249,10 +201,6 @@
         {precise_as_variable_name,			"precise_as_variable_name",			"Test precise keyword as variable name."			},
         {precise_as_function_name,			"precise_as_function_name",			"Test precise keyword as function name."			},
         {precise_as_function_argument,		"precise_as_function_argument",		"Test precise keyword as argument name."			},
-        {precise_as_macro_name,				"precise_as_macro_name",			"Test precise keyword as macro name."				},
-        {precise_as_macro_and_variable,		"precise_as_macro_and_variable",	"Test precise keyword as macro and variable name."	},
-        {precise_as_macro_and_function,		"precise_as_macro_and_function",	"Test precise keyword as macro and function name."	},
-        {precise_as_macro_and_argument,		"precise_as_macro_and_argument",	"Test precise keyword as macro and argument name."	},
 	};
 
 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
diff --git a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
index 9f36f47..e33ecbf 100644
--- a/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
+++ b/modules/gles31/functional/es31fNegativeShaderApiTests.cpp
@@ -125,10 +125,11 @@
 
 void compile_shader (NegativeTestContext& ctx)
 {
-	// \note Shader compilation must be supported.
+	const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+	ctx.glDeleteShader(notAShader);
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
-	ctx.glCompileShader(9);
+	ctx.glCompileShader(notAShader);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -143,8 +144,11 @@
 
 void delete_shader (NegativeTestContext& ctx)
 {
+	const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+	ctx.glDeleteShader(notAShader);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
-	ctx.glDeleteShader(9);
+	ctx.glDeleteShader(notAShader);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 }
@@ -231,6 +235,12 @@
 	GLuint shader2 = ctx.glCreateShader(GL_VERTEX_SHADER);
 	GLuint program = ctx.glCreateProgram();
 
+	const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+	const GLuint notAProgram = ctx.glCreateProgram();
+
+	ctx.glDeleteShader(notAShader);
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
 	ctx.glAttachShader(shader1, shader1);
 	ctx.expectError(GL_INVALID_OPERATION);
@@ -244,11 +254,11 @@
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
-	ctx.glAttachShader(program, -1);
+	ctx.glAttachShader(program, notAShader);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glAttachShader(-1, shader1);
+	ctx.glAttachShader(notAProgram, shader1);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glAttachShader(-1, -1);
+	ctx.glAttachShader(notAProgram, notAShader);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -274,12 +284,18 @@
 	GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 	GLuint program = ctx.glCreateProgram();
 
+	const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
+	const GLuint notAProgram = ctx.glCreateProgram();
+
+	ctx.glDeleteShader(notAShader);
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
-	ctx.glDetachShader(-1, shader);
+	ctx.glDetachShader(notAProgram, shader);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glDetachShader(program, -1);
+	ctx.glDetachShader(program, notAShader);
 	ctx.expectError(GL_INVALID_VALUE);
-	ctx.glDetachShader(-1, -1);
+	ctx.glDetachShader(notAProgram, notAShader);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -308,8 +324,11 @@
 {
 	GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
-	ctx.glLinkProgram(-1);
+	ctx.glLinkProgram(notAProgram);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -353,8 +372,11 @@
 {
 	GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is neither 0 nor a value generated by OpenGL.");
-	ctx.glUseProgram(-1);
+	ctx.glUseProgram(notAProgram);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -404,8 +426,11 @@
 {
 	GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
-	ctx.glDeleteProgram(-1);
+	ctx.glDeleteProgram(notAProgram);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -421,8 +446,11 @@
 {
 	GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
-	ctx.glValidateProgram(-1);
+	ctx.glValidateProgram(notAProgram);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -513,8 +541,11 @@
 	GLuint program	= ctx.glCreateProgram();
 	GLuint shader	= ctx.glCreateShader(GL_VERTEX_SHADER);
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of an existing program object.");
-	ctx.glProgramParameteri(0, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
+	ctx.glProgramParameteri(notAProgram, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -809,6 +840,9 @@
 
 	glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_OPERATION is generated if program has not been successfully linked.");
 	ctx.glBindAttribLocation		(programEmpty, 0, "test");
 	ctx.glGetAttribLocation			(programEmpty, "test");
@@ -821,7 +855,7 @@
 	ctx.expectError				(GL_NO_ERROR);
 	ctx.glGetAttribLocation			(program.getProgram(), "test");
 	ctx.expectError				(GL_NO_ERROR);
-	ctx.glGetAttribLocation			(-2, "test");
+	ctx.glGetAttribLocation			(notAProgram, "test");
 	ctx.expectError				(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -842,6 +876,9 @@
 
 	glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.beginSection("GL_INVALID_OPERATION is generated if program has not been successfully linked.");
 	ctx.glGetUniformLocation(programEmpty, "test");
 	ctx.expectError(GL_INVALID_OPERATION);
@@ -849,7 +886,7 @@
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
 	ctx.glUseProgram(program.getProgram());
-	ctx.glGetUniformLocation(-2, "test");
+	ctx.glGetUniformLocation(notAProgram, "test");
 	ctx.expectError(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -2142,6 +2179,9 @@
 	GLenum					type;
 	char					name[32];
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.glGenTransformFeedbacks				(1, &tfID);
 
 	ctx.glTransformFeedbackVaryings			(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
@@ -2153,7 +2193,7 @@
 	ctx.expectError						(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object.");
-	ctx.glGetTransformFeedbackVarying		(-1, 0, 32, &length, &size, &type, &name[0]);
+	ctx.glGetTransformFeedbackVarying		(notAProgram, 0, 32, &length, &size, &type, &name[0]);
 	ctx.expectError						(GL_INVALID_VALUE);
 	ctx.endSection();
 
@@ -2175,21 +2215,23 @@
 void transform_feedback_varyings (NegativeTestContext& ctx)
 {
 	GLuint										tfID = 0;
-	GLuint shader								= -1;
+	GLuint shader								= ctx.glCreateShader(GL_VERTEX_SHADER);
 	glu::ShaderProgram program					(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
 	const char* tfVarying						= "gl_Position";
 	GLint maxTransformFeedbackSeparateAttribs	= 0;
 
+	const GLuint notAProgram = ctx.glCreateProgram();
+	ctx.glDeleteProgram(notAProgram);
+
 	ctx.glGenTransformFeedbacks				(1, &tfID);
 	ctx.expectError						(GL_NO_ERROR);
 
 	ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object.");
-	ctx.glTransformFeedbackVaryings			(0, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
+	ctx.glTransformFeedbackVaryings			(notAProgram, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
 	ctx.expectError						(GL_INVALID_VALUE);
 	ctx.endSection();
 
 	ctx.beginSection("GL_INVALID_OPERATION is generated if program is the name of a shader object.");
-	shader = ctx.glCreateShader(GL_VERTEX_SHADER);
 	ctx.glTransformFeedbackVaryings(shader, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
 	ctx.expectError(GL_INVALID_OPERATION);
 	ctx.glDeleteShader(shader);
diff --git a/modules/gles31/functional/es31fShaderCommonFunctionTests.cpp b/modules/gles31/functional/es31fShaderCommonFunctionTests.cpp
index aafd861..40cd452 100644
--- a/modules/gles31/functional/es31fShaderCommonFunctionTests.cpp
+++ b/modules/gles31/functional/es31fShaderCommonFunctionTests.cpp
@@ -1795,8 +1795,7 @@
 		const glu::DataType		type						= m_spec.inputs[0].varType.getBasicType();
 		const glu::Precision	precision					= m_spec.inputs[0].varType.getPrecision();
 		const int				scalarSize					= glu::getDataTypeScalarSize(type);
-		const bool				transitSupportsSignedZero	= (m_shaderType != glu::SHADERTYPE_FRAGMENT); // executor cannot reliably transit negative zero to fragment stage
-		const bool				signedZero					= supportsSignedZero(precision) && transitSupportsSignedZero;
+		const bool				signedZero					= false;
 
 		const int				mantissaBits				= getMinMantissaBits(precision);
 		const deUint32			maxUlpDiff					= getMaxUlpDiffFromBits(mantissaBits);