Add Vulkan DrawContext utility class

This is the first in a series of changes to move the DrawContext class
for more general use.

Test: run clipping tests on Vulkan
Affects: dEQP-VK.clipping.*

Change-Id: Ia9b8953d25c10ec2a6c227bf300637dcd62ea898
(cherry picked from commit 9a928cdc2014c830eb8cb43043746f8f2ea6969a)
diff --git a/Android.mk b/Android.mk
index f61d22e..97e217e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -697,6 +697,7 @@
 	external/vulkancts/framework/vulkan/vkAllocationCallbackUtil.cpp \
 	external/vulkancts/framework/vulkan/vkApiVersion.cpp \
 	external/vulkancts/framework/vulkan/vkBinaryRegistry.cpp \
+	external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp \
 	external/vulkancts/framework/vulkan/vkBuilderUtil.cpp \
 	external/vulkancts/framework/vulkan/vkDebugReportUtil.cpp \
 	external/vulkancts/framework/vulkan/vkDefs.cpp \
@@ -704,6 +705,7 @@
 	external/vulkancts/framework/vulkan/vkGlslProgram.cpp \
 	external/vulkancts/framework/vulkan/vkGlslToSpirV.cpp \
 	external/vulkancts/framework/vulkan/vkImageUtil.cpp \
+	external/vulkancts/framework/vulkan/vkImageWithMemory.cpp \
 	external/vulkancts/framework/vulkan/vkMemUtil.cpp \
 	external/vulkancts/framework/vulkan/vkNullDriver.cpp \
 	external/vulkancts/framework/vulkan/vkPlatform.cpp \
@@ -738,7 +740,6 @@
 	external/vulkancts/modules/vulkan/binding_model/vktBindingModelTests.cpp \
 	external/vulkancts/modules/vulkan/binding_model/vktBindingShaderAccessTests.cpp \
 	external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp \
-	external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp \
 	external/vulkancts/modules/vulkan/compute/vktComputeBasicComputeShaderTests.cpp \
 	external/vulkancts/modules/vulkan/compute/vktComputeIndirectComputeDispatchTests.cpp \
 	external/vulkancts/modules/vulkan/compute/vktComputeShaderBuiltinVarTests.cpp \
@@ -911,6 +912,7 @@
 	external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp \
 	external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp \
 	external/vulkancts/modules/vulkan/vktExternalMemoryUtil.cpp \
+	external/vulkancts/modules/vulkan/vktDrawUtil.cpp \
 	external/vulkancts/modules/vulkan/vktInfoTests.cpp \
 	external/vulkancts/modules/vulkan/vktShaderLibrary.cpp \
 	external/vulkancts/modules/vulkan/vktTestCase.cpp \
diff --git a/external/vulkancts/framework/vulkan/CMakeLists.txt b/external/vulkancts/framework/vulkan/CMakeLists.txt
index baef5d7..fa8e8f4 100644
--- a/external/vulkancts/framework/vulkan/CMakeLists.txt
+++ b/external/vulkancts/framework/vulkan/CMakeLists.txt
@@ -47,6 +47,10 @@
 	vkDebugReportUtil.hpp
 	vkGlslProgram.cpp
 	vkGlslProgram.hpp
+	vkBufferWithMemory.cpp
+	vkBufferWithMemory.hpp
+	vkImageWithMemory.cpp
+	vkImageWithMemory.hpp
 	)
 
 set(VKUTIL_LIBS
diff --git a/external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp b/external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp
new file mode 100644
index 0000000..64ef9ea
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkBufferWithMemory.cpp
@@ -0,0 +1,27 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Buffer backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkBufferWithMemory.hpp"
+
+DE_EMPTY_CPP_FILE
diff --git a/external/vulkancts/framework/vulkan/vkBufferWithMemory.hpp b/external/vulkancts/framework/vulkan/vkBufferWithMemory.hpp
new file mode 100644
index 0000000..1fcd299
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkBufferWithMemory.hpp
@@ -0,0 +1,65 @@
+#ifndef _VKBUFFERWITHMEMORY_HPP
+#define _VKBUFFERWITHMEMORY_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Buffer backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+
+namespace vk
+{
+class BufferWithMemory
+{
+public:
+										BufferWithMemory	(const vk::DeviceInterface&		vk,
+															 const vk::VkDevice				device,
+															 vk::Allocator&					allocator,
+															 const vk::VkBufferCreateInfo&	bufferCreateInfo,
+															 const vk::MemoryRequirement	memoryRequirement)
+
+											: m_buffer		(createBuffer(vk, device, &bufferCreateInfo))
+											, m_allocation	(allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
+										{
+											VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
+										}
+
+	const vk::VkBuffer&					get				(void) const { return *m_buffer; }
+	const vk::VkBuffer&					operator*		(void) const { return get(); }
+	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }
+
+private:
+	const vk::Unique<vk::VkBuffer>		m_buffer;
+	const de::UniquePtr<vk::Allocation>	m_allocation;
+
+	// "deleted"
+										BufferWithMemory	(const BufferWithMemory&);
+	BufferWithMemory					operator=			(const BufferWithMemory&);
+};
+} // vk
+
+#endif // _VKBUFFERWITHMEMORY_HPP
diff --git a/external/vulkancts/framework/vulkan/vkImageWithMemory.cpp b/external/vulkancts/framework/vulkan/vkImageWithMemory.cpp
new file mode 100644
index 0000000..b8f680f
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkImageWithMemory.cpp
@@ -0,0 +1,27 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Image backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkImageWithMemory.hpp"
+
+DE_EMPTY_CPP_FILE
diff --git a/external/vulkancts/framework/vulkan/vkImageWithMemory.hpp b/external/vulkancts/framework/vulkan/vkImageWithMemory.hpp
new file mode 100644
index 0000000..23f0859
--- /dev/null
+++ b/external/vulkancts/framework/vulkan/vkImageWithMemory.hpp
@@ -0,0 +1,64 @@
+#ifndef _VKIMAGEWITHMEMORY_HPP
+#define _VKIMAGEWITHMEMORY_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Image backed with memory
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkMemUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+
+namespace vk
+{
+class ImageWithMemory
+{
+public:
+										ImageWithMemory	(const vk::DeviceInterface&		vk,
+														 const vk::VkDevice				device,
+														 vk::Allocator&					allocator,
+														 const vk::VkImageCreateInfo&	imageCreateInfo,
+														 const vk::MemoryRequirement	memoryRequirement)
+
+											: m_image		(createImage(vk, device, &imageCreateInfo))
+											, m_allocation	(allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
+										{
+											VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
+										}
+
+	const vk::VkImage&					get				(void) const { return *m_image; }
+	const vk::VkImage&					operator*		(void) const { return get(); }
+	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }
+
+private:
+	const vk::Unique<vk::VkImage>		m_image;
+	const de::UniquePtr<vk::Allocation>	m_allocation;
+
+	// "deleted"
+										ImageWithMemory	(const ImageWithMemory&);
+	ImageWithMemory&					operator=		(const ImageWithMemory&);
+};
+} // vk
+
+#endif // _VKIMAGEWITHMEMORY_HPP
diff --git a/external/vulkancts/modules/vulkan/CMakeLists.txt b/external/vulkancts/modules/vulkan/CMakeLists.txt
index 24f2291..c6cec98 100644
--- a/external/vulkancts/modules/vulkan/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/CMakeLists.txt
@@ -67,6 +67,8 @@
 	vktInfoTests.hpp
 	vktExternalMemoryUtil.cpp
 	vktExternalMemoryUtil.hpp
+	vktDrawUtil.cpp
+	vktDrawUtil.hpp
 	)
 
 set(DEQP_VK_COMMON_LIBS
diff --git a/external/vulkancts/modules/vulkan/clipping/CMakeLists.txt b/external/vulkancts/modules/vulkan/clipping/CMakeLists.txt
index 2fb6331..fc2e61f 100644
--- a/external/vulkancts/modules/vulkan/clipping/CMakeLists.txt
+++ b/external/vulkancts/modules/vulkan/clipping/CMakeLists.txt
@@ -3,8 +3,6 @@
 set(DEQP_VK_CLIPPING_SRCS
 	vktClippingTests.cpp
 	vktClippingTests.hpp
-	vktClippingUtil.cpp
-	vktClippingUtil.hpp
 	)
 
 set(DEQP_VK_CLIPPING_LIBS
diff --git a/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp b/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
index 15d1443..627e06d 100644
--- a/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
+++ b/external/vulkancts/modules/vulkan/clipping/vktClippingTests.cpp
@@ -25,7 +25,7 @@
 #include "vktTestCase.hpp"
 #include "vktTestGroupUtil.hpp"
 #include "vktTestCaseUtil.hpp"
-#include "vktClippingUtil.hpp"
+#include "vktDrawUtil.hpp"
 #include "vkRefUtil.hpp"
 #include "vkTypeUtil.hpp"
 #include "vkImageUtil.hpp"
@@ -45,524 +45,60 @@
 using tcu::UVec2;
 using tcu::Vec4;
 using tcu::IVec2;
+using namespace drawutil;
 
-enum Constants
+enum FeatureFlagBits
 {
-	RENDER_SIZE								= 16,
-	RENDER_SIZE_LARGE						= 128,
-	NUM_RENDER_PIXELS						= RENDER_SIZE * RENDER_SIZE,
-	NUM_PATCH_CONTROL_POINTS				= 3,
-	MAX_NUM_SHADER_MODULES					= 5,
-	MAX_CLIP_DISTANCES						= 8,
-	MAX_CULL_DISTANCES						= 8,
-	MAX_COMBINED_CLIP_AND_CULL_DISTANCES	= 8,
+	FEATURE_TESSELLATION_SHADER							= 1u << 0,
+	FEATURE_GEOMETRY_SHADER								= 1u << 1,
+	FEATURE_SHADER_FLOAT_64								= 1u << 2,
+	FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			= 1u << 3,
+	FEATURE_FRAGMENT_STORES_AND_ATOMICS					= 1u << 4,
+	FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	= 1u << 5,
+	FEATURE_DEPTH_CLAMP									= 1u << 6,
+	FEATURE_LARGE_POINTS								= 1u << 7,
+	FEATURE_WIDE_LINES									= 1u << 8,
+	FEATURE_SHADER_CLIP_DISTANCE						= 1u << 9,
+	FEATURE_SHADER_CULL_DISTANCE						= 1u << 10,
 };
+typedef deUint32 FeatureFlags;
 
-struct Shader
+void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
 {
-	VkShaderStageFlagBits	stage;
-	const ProgramBinary*	binary;
+	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
 
-	Shader (const VkShaderStageFlagBits stage_, const ProgramBinary& binary_)
-		: stage		(stage_)
-		, binary	(&binary_)
-	{
-	}
-};
+	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
+		throw tcu::NotSupportedError("Tessellation shader not supported");
 
-//! Sets up a graphics pipeline and enables simple draw calls to predefined attachments.
-//! Clip volume uses wc = 1.0, which gives clip coord ranges: x = [-1, 1], y = [-1, 1], z = [0, 1]
-//! Clip coords (-1,-1) map to viewport coords (0, 0).
-class DrawContext
-{
-public:
-									DrawContext		(Context&						context,
-													 const std::vector<Shader>&		shaders,
-													 const std::vector<Vec4>&		vertices,
-													 const VkPrimitiveTopology		primitiveTopology,
-													 const deUint32					renderSize			= static_cast<deUint32>(RENDER_SIZE),
-													 const bool						depthClampEnable	= false,
-													 const bool						blendEnable			= false,
-													 const float					lineWidth			= 1.0f);
+	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
+		throw tcu::NotSupportedError("Geometry shader not supported");
 
-	void							draw			(void);
-	tcu::ConstPixelBufferAccess		getColorPixels	(void) const;
+	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
+		throw tcu::NotSupportedError("Double-precision floats not supported");
 
-private:
-	Context&						m_context;
-	const VkFormat					m_colorFormat;
-	const VkImageSubresourceRange	m_colorSubresourceRange;
-	const UVec2						m_renderSize;
-	const VkExtent3D				m_imageExtent;
-	const VkPrimitiveTopology		m_primitiveTopology;
-	const bool						m_depthClampEnable;
-	const bool						m_blendEnable;
-	const deUint32					m_numVertices;
-	const float						m_lineWidth;
-	const deUint32					m_numPatchControlPoints;
-	MovePtr<Buffer>					m_vertexBuffer;
-	MovePtr<Image>					m_colorImage;
-	MovePtr<Buffer>					m_colorAttachmentBuffer;
-	Move<VkImageView>				m_colorImageView;
-	Move<VkRenderPass>				m_renderPass;
-	Move<VkFramebuffer>				m_framebuffer;
-	Move<VkPipelineLayout>			m_pipelineLayout;
-	Move<VkPipeline>				m_pipeline;
-	Move<VkCommandPool>				m_cmdPool;
-	Move<VkCommandBuffer>			m_cmdBuffer;
-	Move<VkShaderModule>			m_shaderModules[MAX_NUM_SHADER_MODULES];
+	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
+		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
 
-									DrawContext		(const DrawContext&);	// "deleted"
-	DrawContext&					operator=		(const DrawContext&);	// "deleted"
-};
+	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
+		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
 
-DrawContext::DrawContext (Context&						context,
-						  const std::vector<Shader>&	shaders,
-						  const std::vector<Vec4>&		vertices,
-						  const VkPrimitiveTopology		primitiveTopology,
-						  const deUint32				renderSize,
-						  const bool					depthClampEnable,
-						  const bool					blendEnable,
-						  const float					lineWidth)
-	: m_context					(context)
-	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
-	, m_colorSubresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
-	, m_renderSize				(renderSize, renderSize)
-	, m_imageExtent				(makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
-	, m_primitiveTopology		(primitiveTopology)
-	, m_depthClampEnable		(depthClampEnable)
-	, m_blendEnable				(blendEnable)
-	, m_numVertices				(static_cast<deUint32>(vertices.size()))
-	, m_lineWidth				(lineWidth)
-	, m_numPatchControlPoints	(NUM_PATCH_CONTROL_POINTS)		// we're treating patches as triangles
-{
-	const DeviceInterface&	vk			= m_context.getDeviceInterface();
-	const VkDevice			device		= m_context.getDevice();
-	Allocator&				allocator	= m_context.getDefaultAllocator();
+	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
+		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
 
-	// Command buffer
-	{
-		m_cmdPool	= makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
-		m_cmdBuffer	= makeCommandBuffer(vk, device, *m_cmdPool);
-	}
+	if (((flags & FEATURE_DEPTH_CLAMP) != 0) && !features.depthClamp)
+		throw tcu::NotSupportedError("Depth clamp not supported");
 
-	// Color attachment image
-	{
-		const VkImageUsageFlags usage			= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
-		const VkImageCreateInfo	imageCreateInfo	=
-		{
-			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
-			DE_NULL,									// const void*              pNext;
-			(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
-			VK_IMAGE_TYPE_2D,							// VkImageType              imageType;
-			m_colorFormat,								// VkFormat                 format;
-			m_imageExtent,								// VkExtent3D               extent;
-			1u,											// uint32_t                 mipLevels;
-			1u,											// uint32_t                 arrayLayers;
-			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
-			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
-			usage,										// VkImageUsageFlags        usage;
-			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
-			VK_QUEUE_FAMILY_IGNORED,					// uint32_t                 queueFamilyIndexCount;
-			DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
-			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
-		};
+	if (((flags & FEATURE_LARGE_POINTS) != 0) && !features.largePoints)
+		throw tcu::NotSupportedError("Large points not supported");
 
-		m_colorImage = MovePtr<Image>(new Image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
-		m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
+	if (((flags & FEATURE_WIDE_LINES) != 0) && !features.wideLines)
+		throw tcu::NotSupportedError("Wide lines not supported");
 
-		// Buffer to copy attachment data after rendering
+	if (((flags & FEATURE_SHADER_CLIP_DISTANCE) != 0) && !features.shaderClipDistance)
+		throw tcu::NotSupportedError("Shader ClipDistance not supported");
 
-		const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_colorFormat)) * m_renderSize.x() * m_renderSize.y();
-		m_colorAttachmentBuffer = MovePtr<Buffer>(new Buffer(
-			vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
-
-		{
-			const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
-			deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
-			flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
-		}
-	}
-
-	// Vertex buffer
-	{
-		const VkDeviceSize bufferSize = vertices.size() * sizeof(vertices[0]);
-		m_vertexBuffer = MovePtr<Buffer>(new Buffer(
-			vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
-
-		const Allocation& alloc = m_vertexBuffer->getAllocation();
-		deMemcpy(alloc.getHostPtr(), &vertices[0], (size_t)bufferSize);
-		flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
-	}
-
-	// Pipeline layout
-	{
-		m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
-	}
-
-	// Renderpass
-	{
-		const VkAttachmentDescription colorAttachmentDescription =
-		{
-			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
-			m_colorFormat,										// VkFormat							format;
-			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
-			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
-			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
-			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
-			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
-			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
-			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
-		};
-
-		const VkAttachmentReference colorAttachmentReference =
-		{
-			0u,													// deUint32			attachment;
-			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
-		};
-
-		const VkAttachmentReference depthAttachmentReference =
-		{
-			VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
-			VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
-		};
-
-		const VkSubpassDescription subpassDescription =
-		{
-			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
-			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
-			0u,													// deUint32							inputAttachmentCount;
-			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
-			1u,													// deUint32							colorAttachmentCount;
-			&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
-			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
-			&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
-			0u,													// deUint32							preserveAttachmentCount;
-			DE_NULL												// const deUint32*					pPreserveAttachments;
-		};
-
-		const VkRenderPassCreateInfo renderPassInfo =
-		{
-			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
-			DE_NULL,											// const void*						pNext;
-			(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
-			1u,													// deUint32							attachmentCount;
-			&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
-			1u,													// deUint32							subpassCount;
-			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
-			0u,													// deUint32							dependencyCount;
-			DE_NULL												// const VkSubpassDependency*		pDependencies;
-		};
-
-		m_renderPass = createRenderPass(vk, device, &renderPassInfo);
-	}
-
-	// Framebuffer
-	{
-		const VkFramebufferCreateInfo framebufferInfo = {
-			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
-			DE_NULL,										// const void*                                 pNext;
-			(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
-			*m_renderPass,									// VkRenderPass                                renderPass;
-			1u,												// uint32_t                                    attachmentCount;
-			&m_colorImageView.get(),						// const VkImageView*                          pAttachments;
-			m_renderSize.x(),								// uint32_t                                    width;
-			m_renderSize.y(),								// uint32_t                                    height;
-			1u,												// uint32_t                                    layers;
-		};
-
-		m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
-	}
-
-	// Graphics pipeline
-	{
-		const deUint32	vertexStride	= sizeof(Vec4);
-		const VkFormat	vertexFormat	= VK_FORMAT_R32G32B32A32_SFLOAT;
-
-		const VkVertexInputBindingDescription bindingDesc =
-		{
-			0u,									// uint32_t				binding;
-			vertexStride,						// uint32_t				stride;
-			VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
-		};
-		const VkVertexInputAttributeDescription attributeDesc =
-		{
-			0u,									// uint32_t			location;
-			0u,									// uint32_t			binding;
-			vertexFormat,						// VkFormat			format;
-			0u,									// uint32_t			offset;
-		};
-
-		const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
-			DE_NULL,														// const void*                                 pNext;
-			(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
-			1u,																// uint32_t                                    vertexBindingDescriptionCount;
-			&bindingDesc,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
-			1u,																// uint32_t                                    vertexAttributeDescriptionCount;
-			&attributeDesc,													// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
-		};
-
-		const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
-			DE_NULL,														// const void*                                 pNext;
-			(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
-			m_primitiveTopology,											// VkPrimitiveTopology                         topology;
-			VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
-		};
-
-		const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
-			DE_NULL,														// const void*                                 pNext;
-			(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
-			m_numPatchControlPoints,										// uint32_t                                    patchControlPoints;
-		};
-
-		const VkViewport viewport = makeViewport(
-			0.0f, 0.0f,
-			static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
-			0.0f, 1.0f);
-
-		const VkRect2D scissor = {
-			makeOffset2D(0, 0),
-			makeExtent2D(m_renderSize.x(), m_renderSize.y()),
-		};
-
-		const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
-			DE_NULL,												// const void*                                 pNext;
-			(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
-			1u,														// uint32_t                                    viewportCount;
-			&viewport,												// const VkViewport*                           pViewports;
-			1u,														// uint32_t                                    scissorCount;
-			&scissor,												// const VkRect2D*                             pScissors;
-		};
-
-		const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
-			DE_NULL,														// const void*                              pNext;
-			(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
-			m_depthClampEnable,												// VkBool32                                 depthClampEnable;
-			VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
-			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
-			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
-			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
-			VK_FALSE,														// VkBool32									depthBiasEnable;
-			0.0f,															// float									depthBiasConstantFactor;
-			0.0f,															// float									depthBiasClamp;
-			0.0f,															// float									depthBiasSlopeFactor;
-			m_lineWidth,													// float									lineWidth;
-		};
-
-		const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
-			DE_NULL,													// const void*								pNext;
-			(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
-			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
-			VK_FALSE,													// VkBool32									sampleShadingEnable;
-			0.0f,														// float									minSampleShading;
-			DE_NULL,													// const VkSampleMask*						pSampleMask;
-			VK_FALSE,													// VkBool32									alphaToCoverageEnable;
-			VK_FALSE													// VkBool32									alphaToOneEnable;
-		};
-
-		const VkStencilOpState stencilOpState = makeStencilOpState(
-			VK_STENCIL_OP_KEEP,		// stencil fail
-			VK_STENCIL_OP_KEEP,		// depth & stencil pass
-			VK_STENCIL_OP_KEEP,		// depth only fail
-			VK_COMPARE_OP_NEVER,	// compare op
-			0u,						// compare mask
-			0u,						// write mask
-			0u);					// reference
-
-		const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
-			DE_NULL,													// const void*								pNext;
-			(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
-			VK_FALSE,													// VkBool32									depthTestEnable;
-			VK_FALSE,													// VkBool32									depthWriteEnable;
-			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
-			VK_FALSE,													// VkBool32									depthBoundsTestEnable;
-			VK_FALSE,													// VkBool32									stencilTestEnable;
-			stencilOpState,												// VkStencilOpState							front;
-			stencilOpState,												// VkStencilOpState							back;
-			0.0f,														// float									minDepthBounds;
-			1.0f,														// float									maxDepthBounds;
-		};
-
-		const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
-		const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
-		{
-			m_blendEnable,						// VkBool32					blendEnable;
-			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
-			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
-			VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
-			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
-			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
-			VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
-			colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
-		};
-
-		const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
-		{
-			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
-			DE_NULL,													// const void*									pNext;
-			(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
-			VK_FALSE,													// VkBool32										logicOpEnable;
-			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
-			1u,															// deUint32										attachmentCount;
-			&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
-			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
-		};
-
-		// Create shader stages
-
-		std::vector<VkPipelineShaderStageCreateInfo>	shaderStages;
-		VkShaderStageFlags								stageFlags = (VkShaderStageFlags)0;
-
-		DE_ASSERT(shaders.size() <= MAX_NUM_SHADER_MODULES);
-		for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
-		{
-			m_shaderModules[shaderNdx] = createShaderModule(vk, device, *shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
-
-			const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
-			{
-				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
-				DE_NULL,												// const void*							pNext;
-				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
-				shaders[shaderNdx].stage,								// VkShaderStageFlagBits				stage;
-				*m_shaderModules[shaderNdx],							// VkShaderModule						module;
-				"main",													// const char*							pName;
-				DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
-			};
-
-			shaderStages.push_back(pipelineShaderStageInfo);
-			stageFlags |= shaders[shaderNdx].stage;
-		}
-
-		DE_ASSERT(
-			(m_primitiveTopology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
-			(stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
-
-		const bool tessellationEnabled = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
-		const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
-		{
-			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
-			DE_NULL,																// const void*										pNext;
-			(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
-			static_cast<deUint32>(shaderStages.size()),								// deUint32											stageCount;
-			&shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
-			&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
-			&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
-			(tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),		// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
-			&pipelineViewportStateInfo,												// const VkPipelineViewportStateCreateInfo*			pViewportState;
-			&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
-			&pipelineMultisampleStateInfo,											// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
-			&pipelineDepthStencilStateInfo,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
-			&pipelineColorBlendStateInfo,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
-			DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
-			*m_pipelineLayout,														// VkPipelineLayout									layout;
-			*m_renderPass,															// VkRenderPass										renderPass;
-			0u,																		// deUint32											subpass;
-			DE_NULL,																// VkPipeline										basePipelineHandle;
-			0,																		// deInt32											basePipelineIndex;
-		};
-
-		m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
-	}
-
-	// Record commands
-	{
-		const VkDeviceSize zeroOffset = 0ull;
-
-		beginCommandBuffer(vk, *m_cmdBuffer);
-
-		// Begin render pass
-		{
-			const VkClearValue	clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
-			const VkRect2D		renderArea =
-			{
-				makeOffset2D(0, 0),
-				makeExtent2D(m_renderSize.x(), m_renderSize.y())
-			};
-
-			const VkRenderPassBeginInfo renderPassBeginInfo = {
-				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
-				DE_NULL,										// const void*             pNext;
-				*m_renderPass,									// VkRenderPass            renderPass;
-				*m_framebuffer,									// VkFramebuffer           framebuffer;
-				renderArea,										// VkRect2D                renderArea;
-				1u,												// uint32_t                clearValueCount;
-				&clearValue,									// const VkClearValue*     pClearValues;
-			};
-
-			vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-		}
-
-		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
-		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
-
-		vk.cmdDraw(*m_cmdBuffer, m_numVertices, 1u, 0u, 1u);
-		vk.cmdEndRenderPass(*m_cmdBuffer);
-
-		// Barrier: draw -> copy from image
-		{
-			const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
-				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
-				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-				**m_colorImage, m_colorSubresourceRange);
-
-			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
-				0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
-		}
-
-		{
-			const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), m_imageExtent);
-			vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
-		}
-
-		// Barrier: copy to buffer -> host read
-		{
-			const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
-				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
-				**m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
-
-			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
-				0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
-		}
-
-		endCommandBuffer(vk, *m_cmdBuffer);
-	}
-}
-
-void DrawContext::draw (void)
-{
-	const DeviceInterface&	vk			= m_context.getDeviceInterface();
-	const VkDevice			device		= m_context.getDevice();
-	const VkQueue			queue		= m_context.getUniversalQueue();
-	tcu::TestLog&			log			= m_context.getTestContext().getLog();
-
-	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
-
-	log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
-}
-
-tcu::ConstPixelBufferAccess DrawContext::getColorPixels (void) const
-{
-	const DeviceInterface&	vk			= m_context.getDeviceInterface();
-	const VkDevice			device		= m_context.getDevice();
-
-	const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
-	invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
-
-	return tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, alloc.getHostPtr());
+	if (((flags & FEATURE_SHADER_CULL_DISTANCE) != 0) && !features.shaderCullDistance)
+		throw tcu::NotSupportedError("Shader CullDistance not supported");
 }
 
 std::vector<Vec4> genVertices (const VkPrimitiveTopology topology, const Vec4& offset, const float slope)
diff --git a/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp b/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp
deleted file mode 100644
index 4b95413..0000000
--- a/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/*------------------------------------------------------------------------
- * Vulkan Conformance Tests
- * ------------------------
- *
- * Copyright (c) 2016 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *//*!
- * \file
- * \brief Clipping tests utilities
- *//*--------------------------------------------------------------------*/
-
-#include "vktClippingUtil.hpp"
-#include "vkTypeUtil.hpp"
-
-namespace vkt
-{
-namespace clipping
-{
-using namespace vk;
-
-VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
-										 const VkBufferUsageFlags	usage)
-{
-	const VkBufferCreateInfo bufferCreateInfo =
-	{
-		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
-		DE_NULL,								// const void*			pNext;
-		(VkBufferCreateFlags)0,					// VkBufferCreateFlags	flags;
-		bufferSize,								// VkDeviceSize			size;
-		usage,									// VkBufferUsageFlags	usage;
-		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
-		0u,										// deUint32				queueFamilyIndexCount;
-		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
-	};
-	return bufferCreateInfo;
-}
-
-VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
-											   const VkAccessFlags	dstAccessMask,
-											   const VkBuffer		buffer,
-											   const VkDeviceSize	offset,
-											   const VkDeviceSize	bufferSizeBytes)
-{
-	const VkBufferMemoryBarrier barrier =
-	{
-		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
-		DE_NULL,									// const void*		pNext;
-		srcAccessMask,								// VkAccessFlags	srcAccessMask;
-		dstAccessMask,								// VkAccessFlags	dstAccessMask;
-		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
-		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
-		buffer,										// VkBuffer			buffer;
-		offset,										// VkDeviceSize		offset;
-		bufferSizeBytes,							// VkDeviceSize		size;
-	};
-	return barrier;
-}
-
-VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
-											 const VkAccessFlags			dstAccessMask,
-											 const VkImageLayout			oldLayout,
-											 const VkImageLayout			newLayout,
-											 const VkImage					image,
-											 const VkImageSubresourceRange	subresourceRange)
-{
-	const VkImageMemoryBarrier barrier =
-	{
-		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
-		DE_NULL,										// const void*				pNext;
-		srcAccessMask,									// VkAccessFlags			outputMask;
-		dstAccessMask,									// VkAccessFlags			inputMask;
-		oldLayout,										// VkImageLayout			oldLayout;
-		newLayout,										// VkImageLayout			newLayout;
-		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
-		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
-		image,											// VkImage					image;
-		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
-	};
-	return barrier;
-}
-
-Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
-{
-	const VkCommandPoolCreateInfo info =
-	{
-		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
-		DE_NULL,											// const void*				pNext;
-		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
-		queueFamilyIndex,									// deUint32					queueFamilyIndex;
-	};
-	return createCommandPool(vk, device, &info);
-}
-
-Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
-{
-	const VkCommandBufferAllocateInfo info =
-	{
-		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
-		DE_NULL,											// const void*			pNext;
-		commandPool,										// VkCommandPool		commandPool;
-		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
-		1u,													// deUint32				commandBufferCount;
-	};
-	return allocateCommandBuffer(vk, device, &info);
-}
-
-Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
-										 const VkDevice					device,
-										 const VkDescriptorPool			descriptorPool,
-										 const VkDescriptorSetLayout	setLayout)
-{
-	const VkDescriptorSetAllocateInfo info =
-	{
-		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
-		DE_NULL,											// const void*					pNext;
-		descriptorPool,										// VkDescriptorPool				descriptorPool;
-		1u,													// deUint32						descriptorSetCount;
-		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
-	};
-	return allocateDescriptorSet(vk, device, &info);
-}
-
-Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
-										   const VkDevice				device,
-										   const VkDescriptorSetLayout	descriptorSetLayout)
-{
-	const VkPipelineLayoutCreateInfo info =
-	{
-		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
-		DE_NULL,											// const void*					pNext;
-		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
-		1u,													// deUint32						setLayoutCount;
-		&descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
-		0u,													// deUint32						pushConstantRangeCount;
-		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
-	};
-	return createPipelineLayout(vk, device, &info);
-}
-
-Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&		vk,
-															 const VkDevice				device)
-{
-	const VkPipelineLayoutCreateInfo info =
-	{
-		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
-		DE_NULL,											// const void*					pNext;
-		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
-		0u,													// deUint32						setLayoutCount;
-		DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
-		0u,													// deUint32						pushConstantRangeCount;
-		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
-	};
-	return createPipelineLayout(vk, device, &info);
-}
-
-Move<VkImageView> makeImageView (const DeviceInterface&			vk,
-								 const VkDevice					device,
-								 const VkImage					image,
-								 const VkImageViewType			viewType,
-								 const VkFormat					format,
-								 const VkImageSubresourceRange	subresourceRange)
-{
-	const VkImageViewCreateInfo imageViewParams =
-	{
-		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
-		DE_NULL,										// const void*				pNext;
-		(VkImageViewCreateFlags)0,						// VkImageViewCreateFlags	flags;
-		image,											// VkImage					image;
-		viewType,										// VkImageViewType			viewType;
-		format,											// VkFormat					format;
-		makeComponentMappingRGBA(),						// VkComponentMapping		components;
-		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
-	};
-	return createImageView(vk, device, &imageViewParams);
-}
-
-VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers	subresourceLayers,
-									   const VkExtent3D					extent)
-{
-	const VkBufferImageCopy copyParams =
-	{
-		0ull,										//	VkDeviceSize				bufferOffset;
-		0u,											//	deUint32					bufferRowLength;
-		0u,											//	deUint32					bufferImageHeight;
-		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
-		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
-		extent,										//	VkExtent3D					imageExtent;
-	};
-	return copyParams;
-}
-
-void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
-{
-	const VkCommandBufferBeginInfo info =
-	{
-		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
-		DE_NULL,										// const void*                              pNext;
-		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
-		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
-	};
-	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
-}
-
-void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
-{
-	VK_CHECK(vk.endCommandBuffer(commandBuffer));
-}
-
-void submitCommandsAndWait (const DeviceInterface&	vk,
-							const VkDevice			device,
-							const VkQueue			queue,
-							const VkCommandBuffer	commandBuffer)
-{
-	const VkFenceCreateInfo fenceInfo =
-	{
-		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
-		DE_NULL,								// const void*			pNext;
-		(VkFenceCreateFlags)0,					// VkFenceCreateFlags	flags;
-	};
-	const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
-
-	const VkSubmitInfo submitInfo =
-	{
-		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
-		DE_NULL,							// const void*                    pNext;
-		0u,									// uint32_t                       waitSemaphoreCount;
-		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
-		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
-		1u,									// uint32_t                       commandBufferCount;
-		&commandBuffer,						// const VkCommandBuffer*         pCommandBuffers;
-		0u,									// uint32_t                       signalSemaphoreCount;
-		DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
-	};
-	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
-	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
-}
-
-void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
-{
-	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
-
-	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
-		throw tcu::NotSupportedError("Tessellation shader not supported");
-
-	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
-		throw tcu::NotSupportedError("Geometry shader not supported");
-
-	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
-		throw tcu::NotSupportedError("Double-precision floats not supported");
-
-	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
-		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
-
-	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
-		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
-
-	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
-		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
-
-	if (((flags & FEATURE_DEPTH_CLAMP) != 0) && !features.depthClamp)
-		throw tcu::NotSupportedError("Depth clamp not supported");
-
-	if (((flags & FEATURE_LARGE_POINTS) != 0) && !features.largePoints)
-		throw tcu::NotSupportedError("Large points not supported");
-
-	if (((flags & FEATURE_WIDE_LINES) != 0) && !features.wideLines)
-		throw tcu::NotSupportedError("Wide lines not supported");
-
-	if (((flags & FEATURE_SHADER_CLIP_DISTANCE) != 0) && !features.shaderClipDistance)
-		throw tcu::NotSupportedError("Shader ClipDistance not supported");
-
-	if (((flags & FEATURE_SHADER_CULL_DISTANCE) != 0) && !features.shaderCullDistance)
-		throw tcu::NotSupportedError("Shader CullDistance not supported");
-}
-
-std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
-{
-	std::string name(getPrimitiveTopologyName(topology));
-	return de::toLower(name.substr(22));
-}
-
-} // clipping
-} // vkt
diff --git a/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.hpp b/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.hpp
deleted file mode 100644
index c975813..0000000
--- a/external/vulkancts/modules/vulkan/clipping/vktClippingUtil.hpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef _VKTCLIPPINGUTIL_HPP
-#define _VKTCLIPPINGUTIL_HPP
-/*------------------------------------------------------------------------
- * Vulkan Conformance Tests
- * ------------------------
- *
- * Copyright (c) 2016 The Khronos Group Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *//*!
- * \file
- * \brief Clipping tests utilities
- *//*--------------------------------------------------------------------*/
-
-#include "vkDefs.hpp"
-#include "vkQueryUtil.hpp"
-#include "vkMemUtil.hpp"
-#include "vkRefUtil.hpp"
-#include "vkPrograms.hpp"
-#include "tcuVector.hpp"
-
-namespace vkt
-{
-namespace clipping
-{
-
-class Buffer
-{
-public:
-										Buffer			(const vk::DeviceInterface&		vk,
-														 const vk::VkDevice				device,
-														 vk::Allocator&					allocator,
-														 const vk::VkBufferCreateInfo&	bufferCreateInfo,
-														 const vk::MemoryRequirement	memoryRequirement)
-
-											: m_buffer		(createBuffer(vk, device, &bufferCreateInfo))
-											, m_allocation	(allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
-										{
-											VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
-										}
-
-	const vk::VkBuffer&					get				(void) const { return *m_buffer; }
-	const vk::VkBuffer&					operator*		(void) const { return get(); }
-	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }
-
-private:
-	const vk::Unique<vk::VkBuffer>		m_buffer;
-	const de::UniquePtr<vk::Allocation>	m_allocation;
-
-	// "deleted"
-										Buffer			(const Buffer&);
-	Buffer&								operator=		(const Buffer&);
-};
-
-class Image
-{
-public:
-										Image			(const vk::DeviceInterface&		vk,
-														 const vk::VkDevice				device,
-														 vk::Allocator&					allocator,
-														 const vk::VkImageCreateInfo&	imageCreateInfo,
-														 const vk::MemoryRequirement	memoryRequirement)
-
-											: m_image		(createImage(vk, device, &imageCreateInfo))
-											, m_allocation	(allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
-										{
-											VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
-										}
-
-	const vk::VkImage&					get				(void) const { return *m_image; }
-	const vk::VkImage&					operator*		(void) const { return get(); }
-	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }
-
-private:
-	const vk::Unique<vk::VkImage>		m_image;
-	const de::UniquePtr<vk::Allocation>	m_allocation;
-
-	// "deleted"
-										Image			(const Image&);
-	Image&								operator=		(const Image&);
-};
-
-enum FeatureFlagBits
-{
-	FEATURE_TESSELLATION_SHADER							= 1u << 0,
-	FEATURE_GEOMETRY_SHADER								= 1u << 1,
-	FEATURE_SHADER_FLOAT_64								= 1u << 2,
-	FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			= 1u << 3,
-	FEATURE_FRAGMENT_STORES_AND_ATOMICS					= 1u << 4,
-	FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	= 1u << 5,
-	FEATURE_DEPTH_CLAMP									= 1u << 6,
-	FEATURE_LARGE_POINTS								= 1u << 7,
-	FEATURE_WIDE_LINES									= 1u << 8,
-	FEATURE_SHADER_CLIP_DISTANCE						= 1u << 9,
-	FEATURE_SHADER_CULL_DISTANCE						= 1u << 10,
-};
-typedef deUint32 FeatureFlags;
-
-vk::VkBufferCreateInfo			makeBufferCreateInfo						(const vk::VkDeviceSize bufferSize, const vk::VkBufferUsageFlags usage);
-vk::Move<vk::VkCommandPool>		makeCommandPool								(const vk::DeviceInterface& vk, const vk::VkDevice device, const deUint32 queueFamilyIndex);
-vk::Move<vk::VkCommandBuffer>	makeCommandBuffer							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkCommandPool commandPool);
-vk::Move<vk::VkDescriptorSet>	makeDescriptorSet							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorPool descriptorPool, const vk::VkDescriptorSetLayout setLayout);
-vk::Move<vk::VkPipelineLayout>	makePipelineLayout							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorSetLayout descriptorSetLayout);
-vk::Move<vk::VkPipelineLayout>	makePipelineLayoutWithoutDescriptors		(const vk::DeviceInterface& vk, const vk::VkDevice device);
-vk::Move<vk::VkImageView>		makeImageView								(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkImage image, const vk::VkImageViewType viewType, const vk::VkFormat format, const vk::VkImageSubresourceRange subresourceRange);
-vk::VkBufferImageCopy			makeBufferImageCopy							(const vk::VkImageSubresourceLayers subresourceLayers, const vk::VkExtent3D extent);
-vk::VkBufferMemoryBarrier		makeBufferMemoryBarrier						(const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkBuffer buffer, const vk::VkDeviceSize offset, const vk::VkDeviceSize bufferSizeBytes);
-vk::VkImageMemoryBarrier		makeImageMemoryBarrier						(const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkImageLayout oldLayout, const vk::VkImageLayout newLayout, const vk::VkImage image, const vk::VkImageSubresourceRange subresourceRange);
-
-void							beginCommandBuffer							(const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer);
-void							endCommandBuffer							(const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer);
-void							submitCommandsAndWait						(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkQueue queue, const vk::VkCommandBuffer commandBuffer);
-void							requireFeatures								(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const FeatureFlags flags);
-
-std::string						getPrimitiveTopologyShortName				(const vk::VkPrimitiveTopology topology);
-
-} // clipping
-} // vkt
-
-#endif // _VKTCLIPPINGUTIL_HPP
diff --git a/external/vulkancts/modules/vulkan/vktDrawUtil.cpp b/external/vulkancts/modules/vulkan/vktDrawUtil.cpp
new file mode 100644
index 0000000..ae59db4
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/vktDrawUtil.cpp
@@ -0,0 +1,744 @@
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Utility for generating simple work
+ *//*--------------------------------------------------------------------*/
+
+#include "vktDrawUtil.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkTypeUtil.hpp"
+#include "tcuTestLog.hpp"
+
+namespace vkt
+{
+namespace drawutil
+{
+
+using namespace de;
+using namespace tcu;
+using namespace vk;
+
+VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
+										 const VkBufferUsageFlags	usage)
+{
+	const VkBufferCreateInfo bufferCreateInfo =
+	{
+		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
+		DE_NULL,								// const void*			pNext;
+		(VkBufferCreateFlags)0,					// VkBufferCreateFlags	flags;
+		bufferSize,								// VkDeviceSize			size;
+		usage,									// VkBufferUsageFlags	usage;
+		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
+		0u,										// deUint32				queueFamilyIndexCount;
+		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
+	};
+	return bufferCreateInfo;
+}
+
+VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
+											   const VkAccessFlags	dstAccessMask,
+											   const VkBuffer		buffer,
+											   const VkDeviceSize	offset,
+											   const VkDeviceSize	bufferSizeBytes)
+{
+	const VkBufferMemoryBarrier barrier =
+	{
+		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
+		DE_NULL,									// const void*		pNext;
+		srcAccessMask,								// VkAccessFlags	srcAccessMask;
+		dstAccessMask,								// VkAccessFlags	dstAccessMask;
+		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
+		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
+		buffer,										// VkBuffer			buffer;
+		offset,										// VkDeviceSize		offset;
+		bufferSizeBytes,							// VkDeviceSize		size;
+	};
+	return barrier;
+}
+
+VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
+											 const VkAccessFlags			dstAccessMask,
+											 const VkImageLayout			oldLayout,
+											 const VkImageLayout			newLayout,
+											 const VkImage					image,
+											 const VkImageSubresourceRange	subresourceRange)
+{
+	const VkImageMemoryBarrier barrier =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
+		DE_NULL,										// const void*				pNext;
+		srcAccessMask,									// VkAccessFlags			outputMask;
+		dstAccessMask,									// VkAccessFlags			inputMask;
+		oldLayout,										// VkImageLayout			oldLayout;
+		newLayout,										// VkImageLayout			newLayout;
+		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
+		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
+		image,											// VkImage					image;
+		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
+	};
+	return barrier;
+}
+
+Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
+{
+	const VkCommandPoolCreateInfo info =
+	{
+		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
+		DE_NULL,											// const void*				pNext;
+		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
+		queueFamilyIndex,									// deUint32					queueFamilyIndex;
+	};
+	return createCommandPool(vk, device, &info);
+}
+
+Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
+{
+	const VkCommandBufferAllocateInfo info =
+	{
+		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
+		DE_NULL,											// const void*			pNext;
+		commandPool,										// VkCommandPool		commandPool;
+		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
+		1u,													// deUint32				commandBufferCount;
+	};
+	return allocateCommandBuffer(vk, device, &info);
+}
+
+Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
+										 const VkDevice					device,
+										 const VkDescriptorPool			descriptorPool,
+										 const VkDescriptorSetLayout	setLayout)
+{
+	const VkDescriptorSetAllocateInfo info =
+	{
+		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
+		DE_NULL,											// const void*					pNext;
+		descriptorPool,										// VkDescriptorPool				descriptorPool;
+		1u,													// deUint32						descriptorSetCount;
+		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
+	};
+	return allocateDescriptorSet(vk, device, &info);
+}
+
+Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
+										   const VkDevice				device,
+										   const VkDescriptorSetLayout	descriptorSetLayout)
+{
+	const VkPipelineLayoutCreateInfo info =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
+		DE_NULL,											// const void*					pNext;
+		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
+		1u,													// deUint32						setLayoutCount;
+		&descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
+		0u,													// deUint32						pushConstantRangeCount;
+		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
+	};
+	return createPipelineLayout(vk, device, &info);
+}
+
+Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&		vk,
+															 const VkDevice				device)
+{
+	const VkPipelineLayoutCreateInfo info =
+	{
+		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
+		DE_NULL,											// const void*					pNext;
+		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
+		0u,													// deUint32						setLayoutCount;
+		DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
+		0u,													// deUint32						pushConstantRangeCount;
+		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
+	};
+	return createPipelineLayout(vk, device, &info);
+}
+
+Move<VkImageView> makeImageView (const DeviceInterface&			vk,
+								 const VkDevice					device,
+								 const VkImage					image,
+								 const VkImageViewType			viewType,
+								 const VkFormat					format,
+								 const VkImageSubresourceRange	subresourceRange)
+{
+	const VkImageViewCreateInfo imageViewParams =
+	{
+		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
+		DE_NULL,										// const void*				pNext;
+		(VkImageViewCreateFlags)0,						// VkImageViewCreateFlags	flags;
+		image,											// VkImage					image;
+		viewType,										// VkImageViewType			viewType;
+		format,											// VkFormat					format;
+		makeComponentMappingRGBA(),						// VkComponentMapping		components;
+		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
+	};
+	return createImageView(vk, device, &imageViewParams);
+}
+
+VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers	subresourceLayers,
+									   const VkExtent3D					extent)
+{
+	const VkBufferImageCopy copyParams =
+	{
+		0ull,										//	VkDeviceSize				bufferOffset;
+		0u,											//	deUint32					bufferRowLength;
+		0u,											//	deUint32					bufferImageHeight;
+		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
+		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
+		extent,										//	VkExtent3D					imageExtent;
+	};
+	return copyParams;
+}
+
+void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
+{
+	const VkCommandBufferBeginInfo info =
+	{
+		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
+		DE_NULL,										// const void*                              pNext;
+		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
+		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
+	};
+	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
+}
+
+void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
+{
+	VK_CHECK(vk.endCommandBuffer(commandBuffer));
+}
+
+void submitCommandsAndWait (const DeviceInterface&	vk,
+							const VkDevice			device,
+							const VkQueue			queue,
+							const VkCommandBuffer	commandBuffer)
+{
+	const VkFenceCreateInfo fenceInfo =
+	{
+		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
+		DE_NULL,								// const void*			pNext;
+		(VkFenceCreateFlags)0,					// VkFenceCreateFlags	flags;
+	};
+	const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
+
+	const VkSubmitInfo submitInfo =
+	{
+		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
+		DE_NULL,							// const void*                    pNext;
+		0u,									// uint32_t                       waitSemaphoreCount;
+		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
+		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
+		1u,									// uint32_t                       commandBufferCount;
+		&commandBuffer,						// const VkCommandBuffer*         pCommandBuffers;
+		0u,									// uint32_t                       signalSemaphoreCount;
+		DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
+	};
+	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
+	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
+}
+
+std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
+{
+	std::string name(getPrimitiveTopologyName(topology));
+	return de::toLower(name.substr(22));
+}
+DrawContext::DrawContext (Context&						context,
+						  const std::vector<Shader>&	shaders,
+						  const std::vector<Vec4>&		vertices,
+						  const VkPrimitiveTopology		primitiveTopology,
+						  const deUint32				renderSize,
+						  const bool					depthClampEnable,
+						  const bool					blendEnable,
+						  const float					lineWidth)
+	: m_context					(context)
+	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
+	, m_depthFormat				(VK_FORMAT_D32_SFLOAT)
+	, m_colorSubresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
+	, m_depthSubresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u))
+	, m_renderSize				(renderSize, renderSize)
+	, m_imageExtent				(makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
+	, m_primitiveTopology		(primitiveTopology)
+	, m_depthClampEnable		(depthClampEnable)
+	, m_blendEnable				(blendEnable)
+	, m_numVertices				(static_cast<deUint32>(vertices.size()))
+	, m_lineWidth				(lineWidth)
+	, m_numPatchControlPoints	(NUM_PATCH_CONTROL_POINTS)		// we're treating patches as triangles
+{
+	const DeviceInterface&	vk			= m_context.getDeviceInterface();
+	const VkDevice			device		= m_context.getDevice();
+	Allocator&				allocator	= m_context.getDefaultAllocator();
+
+	// Command buffer
+	{
+		m_cmdPool	= makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
+		m_cmdBuffer	= makeCommandBuffer(vk, device, *m_cmdPool);
+	}
+
+	// Color attachment image
+	{
+		const VkImageUsageFlags usage			= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+		const VkImageCreateInfo	imageCreateInfo	=
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
+			DE_NULL,									// const void*              pNext;
+			(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
+			VK_IMAGE_TYPE_2D,							// VkImageType              imageType;
+			m_colorFormat,								// VkFormat                 format;
+			m_imageExtent,								// VkExtent3D               extent;
+			1u,											// uint32_t                 mipLevels;
+			1u,											// uint32_t                 arrayLayers;
+			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
+			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
+			usage,										// VkImageUsageFlags        usage;
+			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
+			VK_QUEUE_FAMILY_IGNORED,					// uint32_t                 queueFamilyIndexCount;
+			DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
+			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
+		};
+
+		m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
+		m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
+
+		// Buffer to copy attachment data after rendering
+
+		const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_colorFormat)) * m_renderSize.x() * m_renderSize.y();
+		m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
+			vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
+
+		{
+			const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
+			deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
+			flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
+		}
+	}
+
+	// Depth attachment image
+	{
+		const VkImageCreateInfo imageCreateInfo	=
+		{
+			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType
+			DE_NULL,										// const void*				pNext
+			0u,												// VkImageCreateFlags		flags
+			VK_IMAGE_TYPE_2D,								// VkImageType				imageType
+			m_depthFormat,									// VkFormat					depthFormat
+			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				externt
+			1u,												// deUint32					mipLevels
+			1u,												// deUint32					arrayLayers
+			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples
+			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling
+			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,	// VkImageUsageFlags		usage
+			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode
+			0u,												// deUint32					queueFamilyIndexCount
+			DE_NULL,										// const deUint32*			pQueueFamilyIndices
+			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout
+		};
+
+		m_depthImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::HostVisible));
+		m_depthImageView = makeImageView(vk, device, **m_depthImage, VK_IMAGE_VIEW_TYPE_2D, m_depthFormat, m_depthSubresourceRange);
+	}
+
+	// Vertex buffer
+	{
+		const VkDeviceSize bufferSize = vertices.size() * sizeof(vertices[0]);
+		m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
+			vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
+
+		const Allocation& alloc = m_vertexBuffer->getAllocation();
+		deMemcpy(alloc.getHostPtr(), &vertices[0], (size_t)bufferSize);
+		flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
+	}
+
+	// Pipeline layout
+	{
+		m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
+	}
+
+	// Renderpass
+	{
+		const VkAttachmentDescription colorAttachmentDescription =
+		{
+			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
+			m_colorFormat,										// VkFormat							format;
+			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
+			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
+			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
+			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
+			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
+			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
+		};
+
+		const VkAttachmentReference colorAttachmentReference =
+		{
+			0u,													// deUint32			attachment;
+			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
+		};
+
+		const VkAttachmentReference depthAttachmentReference =
+		{
+			VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
+			VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
+		};
+
+		const VkSubpassDescription subpassDescription =
+		{
+			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
+			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
+			0u,													// deUint32							inputAttachmentCount;
+			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
+			1u,													// deUint32							colorAttachmentCount;
+			&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
+			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
+			&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
+			0u,													// deUint32							preserveAttachmentCount;
+			DE_NULL												// const deUint32*					pPreserveAttachments;
+		};
+
+		const VkRenderPassCreateInfo renderPassInfo =
+		{
+			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
+			DE_NULL,											// const void*						pNext;
+			(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
+			1u,													// deUint32							attachmentCount;
+			&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
+			1u,													// deUint32							subpassCount;
+			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
+			0u,													// deUint32							dependencyCount;
+			DE_NULL												// const VkSubpassDependency*		pDependencies;
+		};
+
+		m_renderPass = createRenderPass(vk, device, &renderPassInfo);
+	}
+
+	// Framebuffer
+	{
+		const VkImageView attachmentBindInfos[] =
+		{
+			m_colorImageView.get(),
+			m_depthImageView.get()
+		};
+
+		const VkFramebufferCreateInfo framebufferInfo = {
+			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
+			DE_NULL,										// const void*                                 pNext;
+			(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
+			*m_renderPass,									// VkRenderPass                                renderPass;
+			DE_LENGTH_OF_ARRAY(attachmentBindInfos),		// uint32_t                                    attachmentCount;
+			attachmentBindInfos,							// const VkImageView*                          pAttachments;
+			m_renderSize.x(),								// uint32_t                                    width;
+			m_renderSize.y(),								// uint32_t                                    height;
+			1u,												// uint32_t                                    layers;
+		};
+
+		m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
+	}
+
+	// Graphics pipeline
+	{
+		const deUint32	vertexStride	= sizeof(Vec4);
+		const VkFormat	vertexFormat	= VK_FORMAT_R32G32B32A32_SFLOAT;
+
+		const VkVertexInputBindingDescription bindingDesc =
+		{
+			0u,									// uint32_t				binding;
+			vertexStride,						// uint32_t				stride;
+			VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
+		};
+		const VkVertexInputAttributeDescription attributeDesc =
+		{
+			0u,									// uint32_t			location;
+			0u,									// uint32_t			binding;
+			vertexFormat,						// VkFormat			format;
+			0u,									// uint32_t			offset;
+		};
+
+		const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
+			DE_NULL,														// const void*                                 pNext;
+			(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
+			1u,																// uint32_t                                    vertexBindingDescriptionCount;
+			&bindingDesc,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
+			1u,																// uint32_t                                    vertexAttributeDescriptionCount;
+			&attributeDesc,													// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
+		};
+
+		const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
+			DE_NULL,														// const void*                                 pNext;
+			(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
+			m_primitiveTopology,											// VkPrimitiveTopology                         topology;
+			VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
+		};
+
+		const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
+			DE_NULL,														// const void*                                 pNext;
+			(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
+			m_numPatchControlPoints,										// uint32_t                                    patchControlPoints;
+		};
+
+		const VkViewport viewport = makeViewport(
+			0.0f, 0.0f,
+			static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
+			0.0f, 1.0f);
+
+		const VkRect2D scissor = {
+			makeOffset2D(0, 0),
+			makeExtent2D(m_renderSize.x(), m_renderSize.y()),
+		};
+
+		const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
+			DE_NULL,												// const void*                                 pNext;
+			(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
+			1u,														// uint32_t                                    viewportCount;
+			&viewport,												// const VkViewport*                           pViewports;
+			1u,														// uint32_t                                    scissorCount;
+			&scissor,												// const VkRect2D*                             pScissors;
+		};
+
+		const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
+			DE_NULL,														// const void*                              pNext;
+			(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
+			m_depthClampEnable,												// VkBool32                                 depthClampEnable;
+			VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
+			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
+			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
+			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
+			VK_FALSE,														// VkBool32									depthBiasEnable;
+			0.0f,															// float									depthBiasConstantFactor;
+			0.0f,															// float									depthBiasClamp;
+			0.0f,															// float									depthBiasSlopeFactor;
+			m_lineWidth,													// float									lineWidth;
+		};
+
+		const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
+			DE_NULL,													// const void*								pNext;
+			(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
+			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
+			VK_FALSE,													// VkBool32									sampleShadingEnable;
+			0.0f,														// float									minSampleShading;
+			DE_NULL,													// const VkSampleMask*						pSampleMask;
+			VK_FALSE,													// VkBool32									alphaToCoverageEnable;
+			VK_FALSE													// VkBool32									alphaToOneEnable;
+		};
+
+		const VkStencilOpState stencilOpState = makeStencilOpState(
+			VK_STENCIL_OP_KEEP,		// stencil fail
+			VK_STENCIL_OP_KEEP,		// depth & stencil pass
+			VK_STENCIL_OP_KEEP,		// depth only fail
+			VK_COMPARE_OP_NEVER,	// compare op
+			0u,						// compare mask
+			0u,						// write mask
+			0u);					// reference
+
+		const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
+			DE_NULL,													// const void*								pNext;
+			(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
+			VK_FALSE,													// VkBool32									depthTestEnable;
+			VK_FALSE,													// VkBool32									depthWriteEnable;
+			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
+			VK_FALSE,													// VkBool32									depthBoundsTestEnable;
+			VK_FALSE,													// VkBool32									stencilTestEnable;
+			stencilOpState,												// VkStencilOpState							front;
+			stencilOpState,												// VkStencilOpState							back;
+			0.0f,														// float									minDepthBounds;
+			1.0f,														// float									maxDepthBounds;
+		};
+
+		const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+		const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
+		{
+			m_blendEnable,						// VkBool32					blendEnable;
+			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
+			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
+			VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
+			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
+			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
+			VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
+			colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
+		};
+
+		const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
+		{
+			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
+			DE_NULL,													// const void*									pNext;
+			(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
+			VK_FALSE,													// VkBool32										logicOpEnable;
+			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
+			1u,															// deUint32										attachmentCount;
+			&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
+			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
+		};
+
+		// Create shader stages
+
+		std::vector<VkPipelineShaderStageCreateInfo>	shaderStages;
+		VkShaderStageFlags								stageFlags = (VkShaderStageFlags)0;
+
+		DE_ASSERT(shaders.size() <= MAX_NUM_SHADER_MODULES);
+		for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
+		{
+			m_shaderModules[shaderNdx] = createShaderModule(vk, device, *shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
+
+			const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
+			{
+				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
+				DE_NULL,												// const void*							pNext;
+				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
+				shaders[shaderNdx].stage,								// VkShaderStageFlagBits				stage;
+				*m_shaderModules[shaderNdx],							// VkShaderModule						module;
+				"main",													// const char*							pName;
+				DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
+			};
+
+			shaderStages.push_back(pipelineShaderStageInfo);
+			stageFlags |= shaders[shaderNdx].stage;
+		}
+
+		DE_ASSERT(
+			(m_primitiveTopology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
+			(stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
+
+		const bool tessellationEnabled = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
+		const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
+		{
+			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
+			DE_NULL,																// const void*										pNext;
+			(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
+			static_cast<deUint32>(shaderStages.size()),								// deUint32											stageCount;
+			&shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
+			&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
+			&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
+			(tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),		// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
+			&pipelineViewportStateInfo,												// const VkPipelineViewportStateCreateInfo*			pViewportState;
+			&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
+			&pipelineMultisampleStateInfo,											// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
+			&pipelineDepthStencilStateInfo,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
+			&pipelineColorBlendStateInfo,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
+			DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
+			*m_pipelineLayout,														// VkPipelineLayout									layout;
+			*m_renderPass,															// VkRenderPass										renderPass;
+			0u,																		// deUint32											subpass;
+			DE_NULL,																// VkPipeline										basePipelineHandle;
+			0,																		// deInt32											basePipelineIndex;
+		};
+
+		m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
+	}
+
+	// Record commands
+	{
+		const VkDeviceSize zeroOffset = 0ull;
+
+		beginCommandBuffer(vk, *m_cmdBuffer);
+
+		// Begin render pass
+		{
+			const VkClearValue	clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+			const VkRect2D		renderArea =
+			{
+				makeOffset2D(0, 0),
+				makeExtent2D(m_renderSize.x(), m_renderSize.y())
+			};
+
+			const VkRenderPassBeginInfo renderPassBeginInfo = {
+				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
+				DE_NULL,										// const void*             pNext;
+				*m_renderPass,									// VkRenderPass            renderPass;
+				*m_framebuffer,									// VkFramebuffer           framebuffer;
+				renderArea,										// VkRect2D                renderArea;
+				1u,												// uint32_t                clearValueCount;
+				&clearValue,									// const VkClearValue*     pClearValues;
+			};
+
+			vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+		}
+
+		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
+
+		vk.cmdDraw(*m_cmdBuffer, m_numVertices, 1u, 0u, 1u);
+		vk.cmdEndRenderPass(*m_cmdBuffer);
+
+		// Barrier: draw -> copy from image
+		{
+			const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
+				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+				**m_colorImage, m_colorSubresourceRange);
+
+			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
+				0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+		}
+
+		{
+			const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), m_imageExtent);
+			vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
+		}
+
+		// Barrier: copy to buffer -> host read
+		{
+			const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
+				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
+				**m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
+
+			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
+				0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
+		}
+
+		endCommandBuffer(vk, *m_cmdBuffer);
+	}
+}
+
+void DrawContext::draw (void)
+{
+	const DeviceInterface&	vk			= m_context.getDeviceInterface();
+	const VkDevice			device		= m_context.getDevice();
+	const VkQueue			queue		= m_context.getUniversalQueue();
+	tcu::TestLog&			log			= m_context.getTestContext().getLog();
+
+	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
+
+	log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
+}
+
+tcu::ConstPixelBufferAccess DrawContext::getColorPixels (void) const
+{
+	const DeviceInterface&	vk			= m_context.getDeviceInterface();
+	const VkDevice			device		= m_context.getDevice();
+
+	const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
+	invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
+
+	return tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, alloc.getHostPtr());
+}
+} // drawutil
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/vktDrawUtil.hpp b/external/vulkancts/modules/vulkan/vktDrawUtil.hpp
new file mode 100644
index 0000000..9a74092
--- /dev/null
+++ b/external/vulkancts/modules/vulkan/vktDrawUtil.hpp
@@ -0,0 +1,118 @@
+#ifndef _VKTDRAWUTIL_HPP
+#define _VKTDRAWUTIL_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Utility for generating simple work
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+
+#include "deUniquePtr.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkImageUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace drawutil
+{
+
+enum Constants
+{
+	RENDER_SIZE								= 16,
+	RENDER_SIZE_LARGE						= 128,
+	NUM_RENDER_PIXELS						= RENDER_SIZE * RENDER_SIZE,
+	NUM_PATCH_CONTROL_POINTS				= 3,
+	MAX_NUM_SHADER_MODULES					= 5,
+	MAX_CLIP_DISTANCES						= 8,
+	MAX_CULL_DISTANCES						= 8,
+	MAX_COMBINED_CLIP_AND_CULL_DISTANCES	= 8,
+};
+
+struct Shader
+{
+	vk::VkShaderStageFlagBits	stage;
+	const vk::ProgramBinary*	binary;
+
+	Shader (const vk::VkShaderStageFlagBits stage_, const vk::ProgramBinary& binary_)
+		: stage		(stage_)
+		, binary	(&binary_)
+	{
+	}
+};
+//! Sets up a graphics pipeline and enables simple draw calls to predefined attachments.
+//! Clip volume uses wc = 1.0, which gives clip coord ranges: x = [-1, 1], y = [-1, 1], z = [0, 1]
+//! Clip coords (-1,-1) map to viewport coords (0, 0).
+class DrawContext
+{
+public:
+									DrawContext		(Context&						context,
+													 const std::vector<Shader>&		shaders,
+													 const std::vector<tcu::Vec4>&	vertices,
+													 const vk::VkPrimitiveTopology	primitiveTopology,
+													 const deUint32					renderSize			= static_cast<deUint32>(RENDER_SIZE),
+													 const bool						depthClampEnable	= false,
+													 const bool						blendEnable			= false,
+													 const float					lineWidth			= 1.0f);
+
+	void							draw			(void);
+	tcu::ConstPixelBufferAccess		getColorPixels	(void) const;
+
+private:
+	Context&									m_context;
+	const vk::VkFormat							m_colorFormat;
+	const vk::VkFormat							m_depthFormat;
+	const vk::VkImageSubresourceRange			m_colorSubresourceRange;
+	const vk::VkImageSubresourceRange			m_depthSubresourceRange;
+	const tcu::UVec2							m_renderSize;
+	const vk::VkExtent3D						m_imageExtent;
+	const vk::VkPrimitiveTopology				m_primitiveTopology;
+	const bool									m_depthClampEnable;
+	const bool									m_blendEnable;
+	const deUint32								m_numVertices;
+	const float									m_lineWidth;
+	const deUint32								m_numPatchControlPoints;
+	de::MovePtr<vk::BufferWithMemory>			m_vertexBuffer;
+	de::MovePtr<vk::ImageWithMemory>			m_colorImage;
+	de::MovePtr<vk::ImageWithMemory>			m_depthImage;
+	de::MovePtr<vk::BufferWithMemory>			m_colorAttachmentBuffer;
+	vk::refdetails::Move<vk::VkImageView>		m_colorImageView;
+	vk::refdetails::Move<vk::VkImageView>		m_depthImageView;
+	vk::refdetails::Move<vk::VkRenderPass>		m_renderPass;
+	vk::refdetails::Move<vk::VkFramebuffer>		m_framebuffer;
+	vk::refdetails::Move<vk::VkPipelineLayout>	m_pipelineLayout;
+	vk::refdetails::Move<vk::VkPipeline>		m_pipeline;
+	vk::refdetails::Move<vk::VkCommandPool>		m_cmdPool;
+	vk::refdetails::Move<vk::VkCommandBuffer>	m_cmdBuffer;
+	vk::refdetails::Move<vk::VkShaderModule>	m_shaderModules[MAX_NUM_SHADER_MODULES];
+
+									DrawContext		(const DrawContext&);	// "deleted"
+	DrawContext&					operator=		(const DrawContext&);	// "deleted"
+};
+std::string getPrimitiveTopologyShortName (const vk::VkPrimitiveTopology topology);
+
+} // drwwutil
+} // vkt
+
+#endif // _VKTDRAWUTIL_HPP