196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski/*------------------------------------------------------------------------
296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * Vulkan Conformance Tests
396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * ------------------------
496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *
596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * Copyright (c) 2016 The Khronos Group Inc.
696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *
796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * Licensed under the Apache License, Version 2.0 (the "License");
896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * you may not use this file except in compliance with the License.
996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * You may obtain a copy of the License at
1096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *
1196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *      http://www.apache.org/licenses/LICENSE-2.0
1296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *
1396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * Unless required by applicable law or agreed to in writing, software
1496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * distributed under the License is distributed on an "AS IS" BASIS,
1596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * See the License for the specific language governing permissions and
1796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * limitations under the License.
1896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *
1996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *//*!
2096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * \file
2196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski * \brief Clipping tests
2296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski *//*--------------------------------------------------------------------*/
2396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
2496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vktClippingTests.hpp"
2596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vktTestCase.hpp"
2696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vktTestGroupUtil.hpp"
2796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vktTestCaseUtil.hpp"
2896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vktClippingUtil.hpp"
2996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vkRefUtil.hpp"
3096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vkTypeUtil.hpp"
3196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "vkImageUtil.hpp"
3296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "deUniquePtr.hpp"
3396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "deStringUtil.hpp"
3496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski#include "deRandom.hpp"
3596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
3696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskinamespace vkt
3796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
3896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskinamespace clipping
3996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
4096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskinamespace
4196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
4296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiusing namespace vk;
4396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiusing de::MovePtr;
4496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiusing tcu::UVec2;
4596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiusing tcu::Vec4;
4696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiusing tcu::IVec2;
4796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
4896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskienum Constants
4996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
5096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	RENDER_SIZE								= 16,
5196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	RENDER_SIZE_LARGE						= 128,
5296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	NUM_RENDER_PIXELS						= RENDER_SIZE * RENDER_SIZE,
5396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	NUM_PATCH_CONTROL_POINTS				= 3,
5496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MAX_NUM_SHADER_MODULES					= 5,
5596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MAX_CLIP_DISTANCES						= 8,
5696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MAX_CULL_DISTANCES						= 8,
5796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MAX_COMBINED_CLIP_AND_CULL_DISTANCES	= 8,
5896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski};
5996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
6096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskistruct Shader
6196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
6296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	VkShaderStageFlagBits	stage;
6396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const ProgramBinary*	binary;
6496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
6596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Shader (const VkShaderStageFlagBits stage_, const ProgramBinary& binary_)
6696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		: stage		(stage_)
6796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		, binary	(&binary_)
6896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
6996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
7096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski};
7196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
7296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Sets up a graphics pipeline and enables simple draw calls to predefined attachments.
7396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Clip volume uses wc = 1.0, which gives clip coord ranges: x = [-1, 1], y = [-1, 1], z = [0, 1]
7496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Clip coords (-1,-1) map to viewport coords (0, 0).
7596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiclass DrawContext
7696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
7796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskipublic:
7896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski									DrawContext		(Context&						context,
7996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const std::vector<Shader>&		shaders,
8096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const std::vector<Vec4>&		vertices,
8196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const VkPrimitiveTopology		primitiveTopology,
8296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const deUint32					renderSize			= static_cast<deUint32>(RENDER_SIZE),
8396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const bool						depthClampEnable	= false,
8496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const bool						blendEnable			= false,
8596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski													 const float					lineWidth			= 1.0f);
8696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
8796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	void							draw			(void);
8896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::ConstPixelBufferAccess		getColorPixels	(void) const;
8996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
9096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiprivate:
9196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Context&						m_context;
9296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkFormat					m_colorFormat;
9396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkImageSubresourceRange	m_colorSubresourceRange;
9496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const UVec2						m_renderSize;
9596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkExtent3D				m_imageExtent;
9696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkPrimitiveTopology		m_primitiveTopology;
9796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const bool						m_depthClampEnable;
9896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const bool						m_blendEnable;
9996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const deUint32					m_numVertices;
10096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float						m_lineWidth;
10196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const deUint32					m_numPatchControlPoints;
10296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MovePtr<Buffer>					m_vertexBuffer;
10396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MovePtr<Image>					m_colorImage;
10496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	MovePtr<Buffer>					m_colorAttachmentBuffer;
10596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkImageView>				m_colorImageView;
10696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkRenderPass>				m_renderPass;
10796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkFramebuffer>				m_framebuffer;
10896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkPipelineLayout>			m_pipelineLayout;
10996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkPipeline>				m_pipeline;
11096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkCommandPool>				m_cmdPool;
11196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkCommandBuffer>			m_cmdBuffer;
11296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Move<VkShaderModule>			m_shaderModules[MAX_NUM_SHADER_MODULES];
11396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
11496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski									DrawContext		(const DrawContext&);	// "deleted"
11596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DrawContext&					operator=		(const DrawContext&);	// "deleted"
11696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski};
11796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
11896aebab21a68bd028540b76577ba5ba383a1bc50Maciej JesionowskiDrawContext::DrawContext (Context&						context,
11996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const std::vector<Shader>&	shaders,
12096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const std::vector<Vec4>&		vertices,
12196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const VkPrimitiveTopology		primitiveTopology,
12296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const deUint32				renderSize,
12396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const bool					depthClampEnable,
12496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const bool					blendEnable,
12596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						  const float					lineWidth)
12696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	: m_context					(context)
12796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
12896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_colorSubresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
12996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_renderSize				(renderSize, renderSize)
13096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_imageExtent				(makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
13196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_primitiveTopology		(primitiveTopology)
13296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_depthClampEnable		(depthClampEnable)
13396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_blendEnable				(blendEnable)
13496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_numVertices				(static_cast<deUint32>(vertices.size()))
13596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_lineWidth				(lineWidth)
13696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	, m_numPatchControlPoints	(NUM_PATCH_CONTROL_POINTS)		// we're treating patches as triangles
13796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
13896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const DeviceInterface&	vk			= m_context.getDeviceInterface();
13996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkDevice			device		= m_context.getDevice();
14096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	Allocator&				allocator	= m_context.getDefaultAllocator();
14196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
14296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Command buffer
14396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
14496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_cmdPool	= makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
14596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_cmdBuffer	= makeCommandBuffer(vk, device, *m_cmdPool);
14696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
14796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
14896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Color attachment image
14996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
15096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkImageUsageFlags usage			= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
15196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkImageCreateInfo	imageCreateInfo	=
15296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
15396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
15496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,									// const void*              pNext;
15596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
15696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_TYPE_2D,							// VkImageType              imageType;
15796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_colorFormat,								// VkFormat                 format;
15896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_imageExtent,								// VkExtent3D               extent;
15996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,											// uint32_t                 mipLevels;
16096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,											// uint32_t                 arrayLayers;
16196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
16296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
16396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			usage,										// VkImageUsageFlags        usage;
16496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
16596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_QUEUE_FAMILY_IGNORED,					// uint32_t                 queueFamilyIndexCount;
16696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
16796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
16896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
16996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
17096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_colorImage = MovePtr<Image>(new Image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
17196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);
17296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
17396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Buffer to copy attachment data after rendering
17496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
17596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_colorFormat)) * m_renderSize.x() * m_renderSize.y();
17696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_colorAttachmentBuffer = MovePtr<Buffer>(new Buffer(
17796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
17896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
17996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
18096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
181c9bb815d740a9b45ac40ce62ec438d942fc26d47Pyry Haulos			deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
18296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
18396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
18496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
18596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
18696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Vertex buffer
18796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
18896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkDeviceSize bufferSize = vertices.size() * sizeof(vertices[0]);
18996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_vertexBuffer = MovePtr<Buffer>(new Buffer(
19096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
19196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
19296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const Allocation& alloc = m_vertexBuffer->getAllocation();
193c9bb815d740a9b45ac40ce62ec438d942fc26d47Pyry Haulos		deMemcpy(alloc.getHostPtr(), &vertices[0], (size_t)bufferSize);
19496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
19596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
19696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
19796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Pipeline layout
19896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
19996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
20096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
20196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
20296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Renderpass
20396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
20496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkAttachmentDescription colorAttachmentDescription =
20596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
20696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
20796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_colorFormat,										// VkFormat							format;
20896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
20996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
21096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
21196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
21296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
21396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
21496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
21596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
21696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
21796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkAttachmentReference colorAttachmentReference =
21896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
21996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,													// deUint32			attachment;
22096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
22196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
22296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
22396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkAttachmentReference depthAttachmentReference =
22496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
22596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
22696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
22796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
22896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
22996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkSubpassDescription subpassDescription =
23096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
23196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
23296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
23396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,													// deUint32							inputAttachmentCount;
23496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
23596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,													// deUint32							colorAttachmentCount;
23696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
23796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
23896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
23996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,													// deUint32							preserveAttachmentCount;
24096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL												// const deUint32*					pPreserveAttachments;
24196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
24296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
24396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkRenderPassCreateInfo renderPassInfo =
24496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
24596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
24696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,											// const void*						pNext;
24796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
24896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,													// deUint32							attachmentCount;
24996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
25096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,													// deUint32							subpassCount;
25196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
25296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,													// deUint32							dependencyCount;
25396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL												// const VkSubpassDependency*		pDependencies;
25496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
25596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
25696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_renderPass = createRenderPass(vk, device, &renderPassInfo);
25796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
25896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
25996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Framebuffer
26096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
26196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkFramebufferCreateInfo framebufferInfo = {
26296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
26396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,										// const void*                                 pNext;
26496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
26596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			*m_renderPass,									// VkRenderPass                                renderPass;
26696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,												// uint32_t                                    attachmentCount;
26796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&m_colorImageView.get(),						// const VkImageView*                          pAttachments;
26896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_renderSize.x(),								// uint32_t                                    width;
26996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_renderSize.y(),								// uint32_t                                    height;
27096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,												// uint32_t                                    layers;
27196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
27296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
27396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
27496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
27596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
27696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Graphics pipeline
27796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
27896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const deUint32	vertexStride	= sizeof(Vec4);
27996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkFormat	vertexFormat	= VK_FORMAT_R32G32B32A32_SFLOAT;
28096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
28196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkVertexInputBindingDescription bindingDesc =
28296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
28396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,									// uint32_t				binding;
28496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertexStride,						// uint32_t				stride;
28596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
28696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
28796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkVertexInputAttributeDescription attributeDesc =
28896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
28996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,									// uint32_t			location;
29096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,									// uint32_t			binding;
29196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertexFormat,						// VkFormat			format;
29296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,									// uint32_t			offset;
29396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
29496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
29596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
29696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
29796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
29896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,														// const void*                                 pNext;
29996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
30096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,																// uint32_t                                    vertexBindingDescriptionCount;
30196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&bindingDesc,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
30296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,																// uint32_t                                    vertexAttributeDescriptionCount;
30396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&attributeDesc,													// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
30496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
30596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
30696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
30796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
30896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
30996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,														// const void*                                 pNext;
31096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
31196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_primitiveTopology,											// VkPrimitiveTopology                         topology;
31296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
31396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
31496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
31596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
31696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
31796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
31896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,														// const void*                                 pNext;
31996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
32096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_numPatchControlPoints,										// uint32_t                                    patchControlPoints;
32196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
32296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
32396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkViewport viewport = makeViewport(
32496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f, 0.0f,
32596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
32696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f, 1.0f);
32796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
32896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkRect2D scissor = {
32996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			makeOffset2D(0, 0),
33096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			makeExtent2D(m_renderSize.x(), m_renderSize.y()),
33196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
33296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
33396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
33496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
33596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
33696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,												// const void*                                 pNext;
33796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
33896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,														// uint32_t                                    viewportCount;
33996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&viewport,												// const VkViewport*                           pViewports;
34096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,														// uint32_t                                    scissorCount;
34196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&scissor,												// const VkRect2D*                             pScissors;
34296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
34396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
34496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
34596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
34696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
34796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,														// const void*                              pNext;
34896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
34996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_depthClampEnable,												// VkBool32                                 depthClampEnable;
35096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
35196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
35296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
35396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
35496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,														// VkBool32									depthBiasEnable;
35596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f,															// float									depthBiasConstantFactor;
35696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f,															// float									depthBiasClamp;
35796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f,															// float									depthBiasSlopeFactor;
35896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_lineWidth,													// float									lineWidth;
35996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
36096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
36196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
36296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
36396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
36496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,													// const void*								pNext;
36596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
36696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
36796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32									sampleShadingEnable;
36896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f,														// float									minSampleShading;
36996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,													// const VkSampleMask*						pSampleMask;
37096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32									alphaToCoverageEnable;
37196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE													// VkBool32									alphaToOneEnable;
37296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
37396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
37496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkStencilOpState stencilOpState = makeStencilOpState(
37596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STENCIL_OP_KEEP,		// stencil fail
37696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STENCIL_OP_KEEP,		// depth & stencil pass
37796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STENCIL_OP_KEEP,		// depth only fail
37896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_COMPARE_OP_NEVER,	// compare op
37996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,						// compare mask
38096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,						// write mask
38196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u);					// reference
38296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
38396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
38496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
38596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
38696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,													// const void*								pNext;
38796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
38896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32									depthTestEnable;
38996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32									depthWriteEnable;
39096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
39196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32									depthBoundsTestEnable;
39296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32									stencilTestEnable;
39396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			stencilOpState,												// VkStencilOpState							front;
39496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			stencilOpState,												// VkStencilOpState							back;
39596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0.0f,														// float									minDepthBounds;
39696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1.0f,														// float									maxDepthBounds;
39796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
39896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
39996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
40096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
40196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
40296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_blendEnable,						// VkBool32					blendEnable;
40396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
40496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
40596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
40696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
40796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
40896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
40996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
41096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
41196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
41296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
41396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
41496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
41596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,													// const void*									pNext;
41696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
41796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_FALSE,													// VkBool32										logicOpEnable;
41896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
41996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			1u,															// deUint32										attachmentCount;
42096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
42196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
42296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
42396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
42496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Create shader stages
42596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
42696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::vector<VkPipelineShaderStageCreateInfo>	shaderStages;
42796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		VkShaderStageFlags								stageFlags = (VkShaderStageFlags)0;
42896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
42996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DE_ASSERT(shaders.size() <= MAX_NUM_SHADER_MODULES);
43096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		for (deUint32 shaderNdx = 0; shaderNdx < shaders.size(); ++shaderNdx)
43196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
43296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			m_shaderModules[shaderNdx] = createShaderModule(vk, device, *shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
43396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
43496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
43596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
43696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
43796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				DE_NULL,												// const void*							pNext;
43896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
43996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				shaders[shaderNdx].stage,								// VkShaderStageFlagBits				stage;
44096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				*m_shaderModules[shaderNdx],							// VkShaderModule						module;
44196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				"main",													// const char*							pName;
44296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
44396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			};
44496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
44596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			shaderStages.push_back(pipelineShaderStageInfo);
44696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			stageFlags |= shaders[shaderNdx].stage;
44796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
44896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
44996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DE_ASSERT(
45096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(m_primitiveTopology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
45196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
45296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
45396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const bool tessellationEnabled = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
45496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
45596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
45696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
45796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,																// const void*										pNext;
45896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
45996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			static_cast<deUint32>(shaderStages.size()),								// deUint32											stageCount;
46096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
46196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
46296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
46396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			(tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),		// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
46496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineViewportStateInfo,												// const VkPipelineViewportStateCreateInfo*			pViewportState;
46596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
46696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineMultisampleStateInfo,											// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
46796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineDepthStencilStateInfo,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
46896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			&pipelineColorBlendStateInfo,											// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
46996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
47096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			*m_pipelineLayout,														// VkPipelineLayout									layout;
47196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			*m_renderPass,															// VkRenderPass										renderPass;
47296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0u,																		// deUint32											subpass;
47396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_NULL,																// VkPipeline										basePipelineHandle;
47496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			0,																		// deInt32											basePipelineIndex;
47596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
47696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
47796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
47896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
47996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
48096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Record commands
48196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
48296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkDeviceSize zeroOffset = 0ull;
48396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
48496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		beginCommandBuffer(vk, *m_cmdBuffer);
48596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
48696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Begin render pass
48796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
48896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkClearValue	clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
48996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkRect2D		renderArea =
49096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
49196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				makeOffset2D(0, 0),
49296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				makeExtent2D(m_renderSize.x(), m_renderSize.y())
49396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			};
49496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
49596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkRenderPassBeginInfo renderPassBeginInfo = {
49696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
49796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				DE_NULL,										// const void*             pNext;
49896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				*m_renderPass,									// VkRenderPass            renderPass;
49996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				*m_framebuffer,									// VkFramebuffer           framebuffer;
50096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				renderArea,										// VkRect2D                renderArea;
50196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				1u,												// uint32_t                clearValueCount;
50296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				&clearValue,									// const VkClearValue*     pClearValues;
50396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			};
50496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
50596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
50696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
50796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
50896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
50996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
51096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
51196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vk.cmdDraw(*m_cmdBuffer, m_numVertices, 1u, 0u, 1u);
51296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vk.cmdEndRenderPass(*m_cmdBuffer);
51396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
51496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Barrier: draw -> copy from image
51596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
51696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
51796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
51896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
51996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				**m_colorImage, m_colorSubresourceRange);
52096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
52196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
52296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
52396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
52496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
52596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
52696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), m_imageExtent);
52796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
52896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
52996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
53096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Barrier: copy to buffer -> host read
53196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
53296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
53396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
53496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				**m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
53596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
53696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
53796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
53896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
53996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
54096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		endCommandBuffer(vk, *m_cmdBuffer);
54196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
54296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
54396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
54496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid DrawContext::draw (void)
54596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
54696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const DeviceInterface&	vk			= m_context.getDeviceInterface();
54796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkDevice			device		= m_context.getDevice();
54896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkQueue			queue		= m_context.getUniversalQueue();
54996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog&			log			= m_context.getTestContext().getLog();
55096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
55196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
55296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
55396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
55496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
55596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
55696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::ConstPixelBufferAccess DrawContext::getColorPixels (void) const
55796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
55896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const DeviceInterface&	vk			= m_context.getDeviceInterface();
55996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkDevice			device		= m_context.getDevice();
56096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
56196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
56296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
56396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
56496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return tcu::ConstPixelBufferAccess(mapVkFormat(m_colorFormat), m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, alloc.getHostPtr());
56596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
56696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
56796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskistd::vector<Vec4> genVertices (const VkPrimitiveTopology topology, const Vec4& offset, const float slope)
56896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
56996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float p  = 1.0f;
57096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float hp = 0.5f;
57196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float z  = 0.0f;
57296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float w  = 1.0f;
57396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
57496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Vec4> vertices;
57596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
57696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// We're setting adjacent vertices to zero where needed, as we don't use them in meaningful way.
57796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
57896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	switch (topology)
57996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
58096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
58196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(0.0f, 0.0f, slope/2.0f + z, w));
58296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( -hp,  -hp,              z, w));
58396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(  hp,  -hp,      slope + z, w));
58496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( -hp,   hp,              z, w));
58596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(  hp,   hp,      slope + z, w));
58696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
58796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
58896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
58996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
59096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// line 0
59196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));
59296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// line 1
59396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));
59496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// line 2
59596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
59696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
59796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
59896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
59996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
60096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// line 0
60196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
60296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
60396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));
60496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// line 1
60596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
60696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
60796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));
60896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// line 2
60996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
61096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
61196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
61296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
61396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
61496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// line 0
61596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// line 1
61696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// line 2
61796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
61896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
61996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
62096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
62196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
62296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// line 0
62396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// line 1
62496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// line 2
62596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
62696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
62796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
62896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
62996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));
63096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
63196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// triangle 0
63296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));
63396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));
63496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// triangle 1
63596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
63696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
63796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
63896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));
63996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
64096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
64196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
64296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// triangle 0
64396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
64496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));
64596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
64696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));
64796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
64896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// triangle 1
64996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
65096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
65196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
65296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
65396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
65496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));
65596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// triangle 0
65696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// triangle 1
65796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
65896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
65996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
66096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
66196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
66296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));
66396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
66496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));	// triangle 0
66596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
66696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// triangle 1
66796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4());
66896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
66996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
67096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
67196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p, -p, slope + z, w));
67296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p, -p,         z, w));
67396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4(-p,  p,         z, w));	// triangle 0
67496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(offset + Vec4( p,  p, slope + z, w));	// triangle 1
67596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
67696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
67796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
67896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_ASSERT(0);
67996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
68096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
68196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		default:
68296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_ASSERT(0);
68396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
68496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
68596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return vertices;
68696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
68796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
68896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskibool inline isColorInRange (const Vec4& color, const Vec4& minColor, const Vec4& maxColor)
68996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
69096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (minColor.x() <= color.x() && color.x() <= maxColor.x())
69196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		&& (minColor.y() <= color.y() && color.y() <= maxColor.y())
69296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		&& (minColor.z() <= color.z() && color.z() <= maxColor.z())
69396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		&& (minColor.w() <= color.w() && color.w() <= maxColor.w());
69496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
69596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
69696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Count pixels that match color within threshold, in the specified region.
69796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiint countPixels (const tcu::ConstPixelBufferAccess pixels, const IVec2& regionOffset, const IVec2& regionSize, const Vec4& color, const Vec4& colorThreshold)
69896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
69996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const Vec4	minColor	= color - colorThreshold;
70096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const Vec4	maxColor	= color + colorThreshold;
70196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int	xEnd		= regionOffset.x() + regionSize.x();
70296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int	yEnd		= regionOffset.y() + regionSize.y();
70396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	int			numPixels	= 0;
70496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
70596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DE_ASSERT(xEnd <= pixels.getWidth());
70696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DE_ASSERT(yEnd <= pixels.getHeight());
70796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
70896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	for (int y = regionOffset.y(); y < yEnd; ++y)
70996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	for (int x = regionOffset.x(); x < xEnd; ++x)
71096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
71196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (isColorInRange(pixels.getPixel(x, y), minColor, maxColor))
71296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			++numPixels;
71396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
71496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
71596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return numPixels;
71696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
71796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
71896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskiint countPixels (const tcu::ConstPixelBufferAccess pixels, const Vec4& color, const Vec4& colorThreshold)
71996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
72096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return countPixels(pixels, IVec2(), IVec2(pixels.getWidth(), pixels.getHeight()), color, colorThreshold);
72196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
72296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
72396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Clipping against the default clip volume.
72496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskinamespace ClipVolume
72596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
72696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
72796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Used by wide lines test.
72896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskienum LineOrientation
72996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
73096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	LINE_ORIENTATION_AXIS_ALIGNED,
73196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	LINE_ORIENTATION_DIAGONAL,
73296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski};
73396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
73411e0c42693ee11d03b569c8c39debdee61b4132fPetros Bantolasvoid addSimplePrograms (SourceCollections& programCollection, const float pointSize = 0.0f)
73596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
73696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Vertex shader
73796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
73811e0c42693ee11d03b569c8c39debdee61b4132fPetros Bantolas		const bool usePointSize = pointSize > 0.0f;
73996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
74096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
74196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
74296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
74396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in vec4 v_position;\n"
74496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
74596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "out gl_PerVertex {\n"
74696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    vec4  gl_Position;\n"
74796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< (usePointSize ? "    float gl_PointSize;\n" : "")
74896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "};\n"
74996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
75096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
75196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
75296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_Position = v_position;\n"
75396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< (usePointSize ? "    gl_PointSize = " + de::floatToString(pointSize, 1) + ";\n" : "")
75496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "}\n";
75596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
75696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
75796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
75896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
75996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Fragment shader
76096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
76196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
76296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
76396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
76496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 o_color;\n"
76596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
76696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
76796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
76896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    o_color = vec4(1.0, gl_FragCoord.z, 0.0, 1.0);\n"
76996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "}\n";
77096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
77196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
77296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
77396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
77496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
77596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid initPrograms (SourceCollections& programCollection, const VkPrimitiveTopology topology)
77696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
77711e0c42693ee11d03b569c8c39debdee61b4132fPetros Bantolas	const float pointSize = (topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST ? 1.0f : 0.0f);
77811e0c42693ee11d03b569c8c39debdee61b4132fPetros Bantolas	addSimplePrograms(programCollection, pointSize);
77996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
78096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
78196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid initPrograms (SourceCollections& programCollection, const LineOrientation lineOrientation)
78296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
78396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DE_UNREF(lineOrientation);
78411e0c42693ee11d03b569c8c39debdee61b4132fPetros Bantolas	addSimplePrograms(programCollection);
78596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
78696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
78796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid initProgramsPointSize (SourceCollections& programCollection)
78896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
78911e0c42693ee11d03b569c8c39debdee61b4132fPetros Bantolas	addSimplePrograms(programCollection, 0.75f * RENDER_SIZE);
79096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
79196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
79296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Primitives fully inside the clip volume.
79396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testPrimitivesInside (Context& context, const VkPrimitiveTopology topology)
79496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
79596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	int minExpectedBlackPixels = 0;
79696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
79796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	switch (topology)
79896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
79996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
80096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			// We draw only 5 points.
80196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			minExpectedBlackPixels = NUM_RENDER_PIXELS - 5;
80296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
80396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
80496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
80596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
80696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
80796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
80896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			// Allow for some error.
80996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			minExpectedBlackPixels = NUM_RENDER_PIXELS - 3 * RENDER_SIZE;
81096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
81196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
81296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
81396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
81496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
81596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
81696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
81796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			// All render area should be covered.
81896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			minExpectedBlackPixels = 0;
81996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
82096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
82196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		default:
82296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_ASSERT(0);
82396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
82496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
82596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
82696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
82796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
82896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
82996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
83096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog&	log			= context.getTestContext().getLog();
83196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	int				numPassed	= 0;
83296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
83396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	static const struct
83496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
83596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const char* const	desc;
83696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		float				zPos;
83796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	} cases[] =
83896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
83996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives at near clipping plane, z = 0.0",	0.0f, },
84096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives at z = 0.5",							0.5f, },
84196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives at far clipping plane, z = 1.0",		1.0f, },
84296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	};
84396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
84496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); ++caseNdx)
84596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
84696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		log << tcu::TestLog::Message << cases[caseNdx].desc << tcu::TestLog::EndMessage;
84796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
84896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const std::vector<Vec4> vertices = genVertices(topology, Vec4(0.0f, 0.0f, cases[caseNdx].zPos, 0.0f), 0.0f);
84996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DrawContext drawContext(context, shaders, vertices, topology);
85096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		drawContext.draw();
85196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
85296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const int numBlackPixels = countPixels(drawContext.getColorPixels(), Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4());
85396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (numBlackPixels >= minExpectedBlackPixels)
85496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			++numPassed;
85596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
85696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
85796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numPassed == DE_LENGTH_OF_ARRAY(cases) ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Rendered image(s) are incorrect"));
85896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
85996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
86096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Primitives fully outside the clip volume.
86196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testPrimitivesOutside (Context& context, const VkPrimitiveTopology topology)
86296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
86396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
86496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
86596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
86696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
86796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog&	log			= context.getTestContext().getLog();
86896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	int				numPassed	= 0;
86996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
87096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	static const struct
87196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
87296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const char* const	desc;
87396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		float				zPos;
87496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	} cases[] =
87596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
87696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives in front of the near clipping plane, z < 0.0",	-0.5f, },
87796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives behind the far clipping plane, z > 1.0",			 1.5f, },
87896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	};
87996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
88096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	log << tcu::TestLog::Message << "Drawing primitives outside the clip volume. Expecting an empty image." << tcu::TestLog::EndMessage;
88196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
88296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); ++caseNdx)
88396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
88496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		log << tcu::TestLog::Message << cases[caseNdx].desc << tcu::TestLog::EndMessage;
88596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
88696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const std::vector<Vec4> vertices = genVertices(topology, Vec4(0.0f, 0.0f, cases[caseNdx].zPos, 0.0f), 0.0f);
88796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DrawContext drawContext(context, shaders, vertices, topology);
88896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		drawContext.draw();
88996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
89096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// All pixels must be black -- nothing is drawn.
89196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const int numBlackPixels = countPixels(drawContext.getColorPixels(), Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4());
89296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (numBlackPixels == NUM_RENDER_PIXELS)
89396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			++numPassed;
89496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
89596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
89696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numPassed == DE_LENGTH_OF_ARRAY(cases) ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Rendered image(s) are incorrect"));
89796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
89896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
89996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Primitives partially outside the clip volume, but depth clamped
90096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testPrimitivesDepthClamp (Context& context, const VkPrimitiveTopology topology)
90196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
90296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_DEPTH_CLAMP);
90396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
90496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
90596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
90696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
90796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
90896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int		numCases		= 4;
90996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const IVec2		regionSize		= IVec2(RENDER_SIZE/2, RENDER_SIZE);	//! size of the clamped region
91096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int		regionPixels	= regionSize.x() * regionSize.y();
91196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog&	log				= context.getTestContext().getLog();
91296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	int				numPassed		= 0;
91396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
91496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	static const struct
91596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
91696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const char* const	desc;
91796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		float				zPos;
91896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		bool				depthClampEnable;
91996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		IVec2				regionOffset;
92096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		Vec4				color;
92196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	} cases[numCases] =
92296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
92396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives intersecting the near clipping plane, depth clamp disabled",	-0.5f,	false,	IVec2(0, 0),				Vec4(0.0f, 0.0f, 0.0f, 1.0f) },
92496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives intersecting the near clipping plane, depth clamp enabled",	-0.5f,	true,	IVec2(0, 0),				Vec4(1.0f, 0.0f, 0.0f, 1.0f) },
92596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives intersecting the far clipping plane, depth clamp disabled",	 0.5f,	false,	IVec2(RENDER_SIZE/2, 0),	Vec4(0.0f, 0.0f, 0.0f, 1.0f) },
92696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{ "Draw primitives intersecting the far clipping plane, depth clamp enabled",	 0.5f,	true,	IVec2(RENDER_SIZE/2, 0),	Vec4(1.0f, 1.0f, 0.0f, 1.0f) },
92796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	};
92896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
92996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Per case minimum number of colored pixels.
93096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	int caseMinPixels[numCases] = { 0, 0, 0, 0 };
93196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
93296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	switch (topology)
93396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
93496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
93596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[0] = caseMinPixels[2] = regionPixels - 1;
93696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[1] = caseMinPixels[3] = 2;
93796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
93896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
93996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
94096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
94196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
94296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
94396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[0] = regionPixels;
94496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[1] = RENDER_SIZE - 2;
94596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[2] = regionPixels;
94696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[3] = 2 * (RENDER_SIZE - 2);
94796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
94896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
94996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
95096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
95196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
95296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
95396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
95496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			caseMinPixels[0] = caseMinPixels[1] = caseMinPixels[2] = caseMinPixels[3] = regionPixels;
95596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
95696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
95796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		default:
95896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			DE_ASSERT(0);
95996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			break;
96096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
96196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
96296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	for (int caseNdx = 0; caseNdx < numCases; ++caseNdx)
96396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
96496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		log << tcu::TestLog::Message << cases[caseNdx].desc << tcu::TestLog::EndMessage;
96596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
96696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const std::vector<Vec4> vertices = genVertices(topology, Vec4(0.0f, 0.0f, cases[caseNdx].zPos, 0.0f), 1.0f);
96796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DrawContext drawContext(context, shaders, vertices, topology, static_cast<deUint32>(RENDER_SIZE), cases[caseNdx].depthClampEnable);
96896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		drawContext.draw();
96996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
97096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const int numPixels = countPixels(drawContext.getColorPixels(), cases[caseNdx].regionOffset, regionSize, cases[caseNdx].color, Vec4());
97196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
97296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (numPixels >= caseMinPixels[caseNdx])
97396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			++numPassed;
97496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
97596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
97696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numPassed == numCases ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Rendered image(s) are incorrect"));
97796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
97896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
97996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Large point clipping
98096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Spec: If the primitive under consideration is a point, then clipping passes it unchanged if it lies within the clip volume;
98196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//!       otherwise, it is discarded.
98296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testLargePoints (Context& context)
98396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
98496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_LARGE_POINTS);
98596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
98696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
98796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
98896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
98996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
99096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Vec4> vertices;
99196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
99296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const float delta	= 0.1f;  // much smaller than the point size
99396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const float p		= 1.0f + delta;
99496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
99596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(  -p,   -p, 0.1f, 1.0f));
99696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(  -p,    p, 0.2f, 1.0f));
99796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(   p,    p, 0.4f, 1.0f));
99896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(   p,   -p, 0.6f, 1.0f));
99996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(0.0f,   -p, 0.8f, 1.0f));
100096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(   p, 0.0f, 0.9f, 1.0f));
100196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(0.0f,    p, 0.1f, 1.0f));
100296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(  -p, 0.0f, 0.2f, 1.0f));
100396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
100496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
100596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog&	log	= context.getTestContext().getLog();
100696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
100796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	log << tcu::TestLog::Message << "Drawing several large points just outside the clip volume. Expecting an empty image." << tcu::TestLog::EndMessage;
100896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
100996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DrawContext drawContext(context, shaders, vertices, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
101096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	drawContext.draw();
101196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
101296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// All pixels must be black -- nothing is drawn.
101396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int numBlackPixels = countPixels(drawContext.getColorPixels(), Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4());
101496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
101596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numBlackPixels == NUM_RENDER_PIXELS ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Rendered image(s) are incorrect"));
101696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
101796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
101896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Wide line clipping
101996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//! Spec: If the primitive is a line segment, then clipping does nothing to it if it lies entirely within the clip volume, and discards it
102096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski//!       if it lies entirely outside the volume.
102196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testWideLines (Context& context, const LineOrientation lineOrientation)
102296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
102396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_WIDE_LINES);
102496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
102596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
102696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
102796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
102896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
102996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float delta = 0.1f;  // much smaller than the line width
103096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
103196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Vec4> vertices;
103296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	if (lineOrientation == LINE_ORIENTATION_AXIS_ALIGNED)
103396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
103496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Axis-aligned lines just outside the clip volume.
103596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const float p = 1.0f + delta;
103696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const float q = 0.9f;
103796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
103896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(-p, -q, 0.1f, 1.0f));
103996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(-p,  q, 0.9f, 1.0f));	// line 0
104096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(-q,  p, 0.1f, 1.0f));
104196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4( q,  p, 0.9f, 1.0f));	// line 1
104296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4( p,  q, 0.1f, 1.0f));
104396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4( p, -q, 0.9f, 1.0f));	// line 2
104496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4( q, -p, 0.1f, 1.0f));
104596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(-q, -p, 0.9f, 1.0f));	// line 3
104696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
104796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	else if (lineOrientation == LINE_ORIENTATION_DIAGONAL)
104896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
104996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Diagonal lines just outside the clip volume.
105096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const float p = 2.0f + delta;
105196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
105296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(  -p, 0.0f, 0.1f, 1.0f));
105396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(0.0f,   -p, 0.9f, 1.0f));	// line 0
105496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(0.0f,   -p, 0.1f, 1.0f));
105596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(   p, 0.0f, 0.9f, 1.0f));	// line 1
105696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(   p, 0.0f, 0.1f, 1.0f));
105796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(0.0f,    p, 0.9f, 1.0f));	// line 2
105896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(0.0f,    p, 0.1f, 1.0f));
105996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		vertices.push_back(Vec4(  -p, 0.0f, 0.9f, 1.0f));	// line 3
106096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
106196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	else
106296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DE_ASSERT(0);
106396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
106496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits;
106596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
106696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const float		lineWidth	= std::min(static_cast<float>(RENDER_SIZE), limits.lineWidthRange[1]);
106796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog&	log			= context.getTestContext().getLog();
106896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
106996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	log << tcu::TestLog::Message << "Drawing several wide lines just outside the clip volume. Expecting an empty image." << tcu::TestLog::EndMessage
107096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		<< tcu::TestLog::Message << "Line width is " << lineWidth << "." << tcu::TestLog::EndMessage;
107196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
107296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DrawContext drawContext(context, shaders, vertices, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, static_cast<deUint32>(RENDER_SIZE), false, false, lineWidth);
107396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	drawContext.draw();
107496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
107596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// All pixels must be black -- nothing is drawn.
107696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int numBlackPixels = countPixels(drawContext.getColorPixels(), Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4());
107796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
107896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numBlackPixels == NUM_RENDER_PIXELS ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Rendered image(s) are incorrect"));
107996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
108096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
108196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski} // ClipVolume ns
108296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
108396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskinamespace ClipDistance
108496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
108596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
108696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskistruct CaseDefinition
108796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
108896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const VkPrimitiveTopology	topology;
108996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const bool					dynamicIndexing;
109096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const bool					enableTessellation;
109196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const bool					enableGeometry;
109296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int					numClipDistances;
109396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int					numCullDistances;
109496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
109596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	CaseDefinition (const VkPrimitiveTopology	topology_,
109696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const int					numClipDistances_,
109796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const int					numCullDistances_,
109896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const bool					enableTessellation_,
109996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const bool					enableGeometry_,
110096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const bool					dynamicIndexing_)
110196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		: topology					(topology_)
110296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		, dynamicIndexing			(dynamicIndexing_)
110396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		, enableTessellation		(enableTessellation_)
110496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		, enableGeometry			(enableGeometry_)
110596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		, numClipDistances			(numClipDistances_)
110696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		, numCullDistances			(numCullDistances_)
110796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
110896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
110996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski};
111096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
111196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid initPrograms (SourceCollections& programCollection, const CaseDefinition caseDef)
111296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
111396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DE_ASSERT(caseDef.numClipDistances + caseDef.numCullDistances <= MAX_COMBINED_CLIP_AND_CULL_DISTANCES);
111496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
111596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::string perVertexBlock;
111696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
111796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream str;
111896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		str << "gl_PerVertex {\n"
111996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    vec4  gl_Position;\n";
112096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numClipDistances > 0)
112196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			str << "    float gl_ClipDistance[" << caseDef.numClipDistances << "];\n";
112296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numCullDistances > 0)
112396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			str << "    float gl_CullDistance[" << caseDef.numCullDistances << "];\n";
112496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		str << "}";
112596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		perVertexBlock = str.str();
112696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
112796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
112896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Vertex shader
112996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
113096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
113196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
113296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
113396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in  vec4 v_position;\n"
113496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color;\n"
113596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
113696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "out " << perVertexBlock << ";\n"
113796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
113896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
113996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
114096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_Position = v_position;\n"
114196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    out_color   = vec4(1.0, 0.5 * (v_position.x + 1.0), 0.0, 1.0);\n"
114296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
114396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    const int barNdx = gl_VertexIndex / 6;\n";
114496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.dynamicIndexing)
114596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
114696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.numClipDistances > 0)
114796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    for (int i = 0; i < " << caseDef.numClipDistances << "; ++i)\n"
114896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "        gl_ClipDistance[i] = (barNdx == i ? v_position.y : 0.0);\n";
114996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.numCullDistances > 0)
115096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    for (int i = 0; i < " << caseDef.numCullDistances << "; ++i)\n"
115196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "        gl_CullDistance[i] = 0.0;\n";
115296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
115396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		else
115496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
115596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < caseDef.numClipDistances; ++i)
115696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    gl_ClipDistance[" << i << "] = (barNdx == " << i << " ? v_position.y : 0.0);\n";
115796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < caseDef.numCullDistances; ++i)
115896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    gl_CullDistance[" << i << "] = 0.0;\n";		// don't cull anything
115996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
116096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src	<< "}\n";
116196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
116296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
116396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
116496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
116596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	if (caseDef.enableTessellation)
116696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
116796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
116896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
116996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
117096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(vertices = " << NUM_PATCH_CONTROL_POINTS << ") out;\n"
117196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
117296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in  vec4 in_color[];\n"
117396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color[];\n"
117496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
117596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "in " << perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
117696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
117796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "out " << perVertexBlock << " gl_out[];\n"
117896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
117996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
118096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
118196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_TessLevelInner[0] = 1.0;\n"
118296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_TessLevelInner[1] = 1.0;\n"
118396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
118496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_TessLevelOuter[0] = 1.0;\n"
118596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_TessLevelOuter[1] = 1.0;\n"
118696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_TessLevelOuter[2] = 1.0;\n"
118796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_TessLevelOuter[3] = 1.0;\n"
118896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
118996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
119096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    out_color[gl_InvocationID]          = in_color[gl_InvocationID];\n"
119196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n";
119296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.dynamicIndexing)
119396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
119496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.numClipDistances > 0)
119596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    for (int i = 0; i < " << caseDef.numClipDistances << "; ++i)\n"
119696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "        gl_out[gl_InvocationID].gl_ClipDistance[i] = gl_in[gl_InvocationID].gl_ClipDistance[i];\n";
119796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.numCullDistances > 0)
119896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    for (int i = 0; i < " << caseDef.numCullDistances << "; ++i)\n"
119996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "        gl_out[gl_InvocationID].gl_CullDistance[i] = gl_in[gl_InvocationID].gl_CullDistance[i];\n";
120096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
120196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		else
120296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
120396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < caseDef.numClipDistances; ++i)
120496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    gl_out[gl_InvocationID].gl_ClipDistance[" << i << "] = gl_in[gl_InvocationID].gl_ClipDistance[" << i << "];\n";
120596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < caseDef.numCullDistances; ++i)
120696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    gl_out[gl_InvocationID].gl_CullDistance[" << i << "] = gl_in[gl_InvocationID].gl_CullDistance[" << i << "];\n";
120796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
120896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << "}\n";
120996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
121096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
121196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
121296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
121396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	if (caseDef.enableTessellation)
121496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
121596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DE_ASSERT(NUM_PATCH_CONTROL_POINTS == 3);  // assumed in shader code
121696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
121796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
121896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
121996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
122096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(triangles, equal_spacing, ccw) in;\n"
122196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
122296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in  vec4 in_color[];\n"
122396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color;\n"
122496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
122596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "in " << perVertexBlock << " gl_in[gl_MaxPatchVertices];\n"
122696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
122796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "out " << perVertexBlock << ";\n"
122896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
122996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
123096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
123196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    vec3 px     = gl_TessCoord.x * gl_in[0].gl_Position.xyz;\n"
123296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    vec3 py     = gl_TessCoord.y * gl_in[1].gl_Position.xyz;\n"
123396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    vec3 pz     = gl_TessCoord.z * gl_in[2].gl_Position.xyz;\n"
123496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_Position = vec4(px + py + pz, 1.0);\n"
123596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    out_color   = (in_color[0] + in_color[1] + in_color[2]) / 3.0;\n"
123696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n";
123796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.dynamicIndexing)
123896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
123996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.numClipDistances > 0)
124096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    for (int i = 0; i < " << caseDef.numClipDistances << "; ++i)\n"
124196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "        gl_ClipDistance[i] = gl_TessCoord.x * gl_in[0].gl_ClipDistance[i]\n"
124296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                           + gl_TessCoord.y * gl_in[1].gl_ClipDistance[i]\n"
124396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                           + gl_TessCoord.z * gl_in[2].gl_ClipDistance[i];\n";
124496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.numCullDistances > 0)
124596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    for (int i = 0; i < " << caseDef.numCullDistances << "; ++i)\n"
124696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "        gl_CullDistance[i] = gl_TessCoord.x * gl_in[0].gl_CullDistance[i]\n"
124796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                           + gl_TessCoord.y * gl_in[1].gl_CullDistance[i]\n"
124896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                           + gl_TessCoord.z * gl_in[2].gl_CullDistance[i];\n";
124996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
125096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		else
125196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
125296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < caseDef.numClipDistances; ++i)
125396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    gl_ClipDistance[" << i << "] = gl_TessCoord.x * gl_in[0].gl_ClipDistance[" << i << "]\n"
125496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                       + gl_TessCoord.y * gl_in[1].gl_ClipDistance[" << i << "]\n"
125596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                       + gl_TessCoord.z * gl_in[2].gl_ClipDistance[" << i << "];\n";
125696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < caseDef.numCullDistances; ++i)
125796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "    gl_CullDistance[" << i << "] = gl_TessCoord.x * gl_in[0].gl_CullDistance[" << i << "]\n"
125896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                       + gl_TessCoord.y * gl_in[1].gl_CullDistance[" << i << "]\n"
125996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					<< "                       + gl_TessCoord.z * gl_in[2].gl_CullDistance[" << i << "];\n";
126096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
126196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << "}\n";
126296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
126396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
126496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
126596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
126696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	if (caseDef.enableGeometry)
126796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
126896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
126996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
127096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
127196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(triangles) in;\n"
127296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(triangle_strip, max_vertices = 3) out;\n"
127396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
127496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in  vec4 in_color[];\n"
127596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 out_color;\n"
127696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
127796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "in " << perVertexBlock << " gl_in[];\n"
127896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
127996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "out " << perVertexBlock << ";\n"
128096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
128196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
128296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n";
128396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		for (int vertNdx = 0; vertNdx < 3; ++vertNdx)
128496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
128596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (vertNdx > 0)
128696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				src << "\n";
128796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			src << "    gl_Position = gl_in[" << vertNdx << "].gl_Position;\n"
128896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				<< "    out_color   = in_color[" << vertNdx << "];\n";
128996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			if (caseDef.dynamicIndexing)
129096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
129196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				if (caseDef.numClipDistances > 0)
129296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					src << "    for (int i = 0; i < " << caseDef.numClipDistances << "; ++i)\n"
129396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						<< "        gl_ClipDistance[i] = gl_in[" << vertNdx << "].gl_ClipDistance[i];\n";
129496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				if (caseDef.numCullDistances > 0)
129596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					src << "    for (int i = 0; i < " << caseDef.numCullDistances << "; ++i)\n"
129696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						<< "        gl_CullDistance[i] = gl_in[" << vertNdx << "].gl_CullDistance[i];\n";
129796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			}
129896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			else
129996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
130096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				for (int i = 0; i < caseDef.numClipDistances; ++i)
130196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					src << "    gl_ClipDistance[" << i << "] = gl_in[" << vertNdx << "].gl_ClipDistance[" << i << "];\n";
130296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				for (int i = 0; i < caseDef.numCullDistances; ++i)
130396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					src << "    gl_CullDistance[" << i << "] = gl_in[" << vertNdx << "].gl_CullDistance[" << i << "];\n";
130496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			}
130596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			src << "    EmitVertex();\n";
130696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
130796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src	<< "}\n";
130896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
130996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
131096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
131196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
131296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Fragment shader
131396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
131496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
131596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
131696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
131796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in flat vec4 in_color;\n"
131896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 o_color;\n"
131996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
132096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
132196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
132296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    o_color = vec4(in_color.rgb + vec3(0.0, 0.0, 0.5), 1.0);\n"  // mix with a constant color in case variable wasn't passed correctly through stages
132396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "}\n";
132496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
132596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
132696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
132796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
132896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
132996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testClipDistance (Context& context, const CaseDefinition caseDef)
133096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
133196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Check test requirements
133296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
133396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const InstanceInterface&		vki			= context.getInstanceInterface();
133496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPhysicalDevice			physDevice	= context.getPhysicalDevice();
133596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPhysicalDeviceLimits	limits		= getPhysicalDeviceProperties(vki, physDevice).limits;
133696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
133796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		FeatureFlags requirements = (FeatureFlags)0;
133896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
133996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numClipDistances > 0)
134096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			requirements |= FEATURE_SHADER_CLIP_DISTANCE;
134196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numCullDistances > 0)
134296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			requirements |= FEATURE_SHADER_CULL_DISTANCE;
134396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.enableTessellation)
134496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			requirements |= FEATURE_TESSELLATION_SHADER;
134596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.enableGeometry)
134696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			requirements |= FEATURE_GEOMETRY_SHADER;
134796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
134896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		requireFeatures(vki, physDevice, requirements);
134996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
135096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Check limits for supported features
135196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
135296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numClipDistances > 0 && limits.maxClipDistances < MAX_CLIP_DISTANCES)
135396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			return tcu::TestStatus::fail("maxClipDistances smaller than the minimum required by the spec");
135496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numCullDistances > 0 && limits.maxCullDistances < MAX_CULL_DISTANCES)
135596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			return tcu::TestStatus::fail("maxCullDistances smaller than the minimum required by the spec");
135696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		if (caseDef.numCullDistances > 0 && limits.maxCombinedClipAndCullDistances < MAX_COMBINED_CLIP_AND_CULL_DISTANCES)
135796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			return tcu::TestStatus::fail("maxCombinedClipAndCullDistances smaller than the minimum required by the spec");
135896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
135996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
136096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
136196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
136296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
136396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	if (caseDef.enableTessellation)
136496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
136596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		shaders.push_back(Shader(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		context.getBinaryCollection().get("tesc")));
136696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		shaders.push_back(Shader(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	context.getBinaryCollection().get("tese")));
136796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
136896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	if (caseDef.enableGeometry)
136996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		shaders.push_back(Shader(VK_SHADER_STAGE_GEOMETRY_BIT,	context.getBinaryCollection().get("geom")));
137096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
137196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int numBars = MAX_COMBINED_CLIP_AND_CULL_DISTANCES;
137296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
137396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Vec4> vertices;
137496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
137596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const float	dx = 2.0f / numBars;
137696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		for (int i = 0; i < numBars; ++i)
137796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
137896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const float x = -1.0f + dx * static_cast<float>(i);
137996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
138096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4(x,      -1.0f, 0.0f, 1.0f));
138196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4(x,       1.0f, 0.0f, 1.0f));
138296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4(x + dx, -1.0f, 0.0f, 1.0f));
138396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
138496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4(x,       1.0f, 0.0f, 1.0f));
138596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4(x + dx,  1.0f, 0.0f, 1.0f));
138696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			vertices.push_back(Vec4(x + dx, -1.0f, 0.0f, 1.0f));
138796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
138896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
138996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
139096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog& log = context.getTestContext().getLog();
139196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
139296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	log << tcu::TestLog::Message << "Drawing " << numBars << " colored bars, clipping the first " << caseDef.numClipDistances << tcu::TestLog::EndMessage
139396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		<< tcu::TestLog::Message << "Using " << caseDef.numClipDistances << " ClipDistance(s) and " << caseDef.numCullDistances << " CullDistance(s)" << tcu::TestLog::EndMessage
139496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		<< tcu::TestLog::Message << "Expecting upper half of the clipped bars to be black." << tcu::TestLog::EndMessage;
139596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
139696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DrawContext drawContext(context, shaders, vertices, caseDef.topology);
139796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	drawContext.draw();
139896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
139996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Count black pixels in the whole image.
140096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int numBlackPixels		= countPixels(drawContext.getColorPixels(), Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4());
140196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const IVec2	clipRegion			= IVec2(caseDef.numClipDistances * RENDER_SIZE / numBars, RENDER_SIZE / 2);
140296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int expectedClippedPixels	= clipRegion.x() * clipRegion.y();
140396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Make sure the bottom half has no black pixels (possible if image became corrupted).
140496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int guardPixels			= countPixels(drawContext.getColorPixels(), IVec2(0, RENDER_SIZE/2), clipRegion, Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4());
140596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
140696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numBlackPixels == expectedClippedPixels && guardPixels == 0 ? tcu::TestStatus::pass("OK")
140796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski																		: tcu::TestStatus::fail("Rendered image(s) are incorrect"));
140896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
140996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
141096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski} // ClipDistance ns
141196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
141296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskinamespace ClipDistanceComplementarity
141396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
141496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
141596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid initPrograms (SourceCollections& programCollection, const int numClipDistances)
141696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
141796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Vertex shader
141896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
141996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DE_ASSERT(numClipDistances > 0);
142096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const int clipDistanceLastNdx = numClipDistances - 1;
142196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
142296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
142396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
142496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
142596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) in vec4 v_position;    // we are passing ClipDistance in w component\n"
142696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
142796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "out gl_PerVertex {\n"
142896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    vec4  gl_Position;\n"
142996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    float gl_ClipDistance[" << numClipDistances << "];\n"
143096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "};\n"
143196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
143296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
143396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
143496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    gl_Position        = vec4(v_position.xyz, 1.0);\n";
143596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		for (int i = 0; i < clipDistanceLastNdx; ++i)
143696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			src << "    gl_ClipDistance[" << i << "] = 0.0;\n";
143796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << "    gl_ClipDistance[" << clipDistanceLastNdx << "] = v_position.w;\n"
143896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "}\n";
143996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
144096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
144196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
144296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
144396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Fragment shader
144496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
144596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::ostringstream src;
144696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
144796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
144896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "layout(location = 0) out vec4 o_color;\n"
144996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "\n"
145096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "void main (void)\n"
145196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "{\n"
145296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "    o_color = vec4(1.0, 1.0, 1.0, 0.5);\n"
145396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			<< "}\n";
145496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
145596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
145696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
145796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
145896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
145996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestStatus testComplementarity (Context& context, const int numClipDistances)
146096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
146196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Check test requirements
146296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
146396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const InstanceInterface&		vki			= context.getInstanceInterface();
146496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const VkPhysicalDevice			physDevice	= context.getPhysicalDevice();
146596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
146696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		requireFeatures(vki, physDevice, FEATURE_SHADER_CLIP_DISTANCE);
146796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
146896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
146996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Shader> shaders;
147096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT,	context.getBinaryCollection().get("vert")));
147196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT,	context.getBinaryCollection().get("frag")));
147296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
147396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	std::vector<Vec4> vertices;
147496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
147596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		de::Random	rnd						(1234);
147696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const int	numSections				= 16;
147796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		const int	numVerticesPerSection	= 4;	// logical verticies, due to triangle list topology we actually use 6 per section
147896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
147996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		DE_ASSERT(RENDER_SIZE_LARGE % numSections == 0);
148096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
148196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		std::vector<float> clipDistances(numVerticesPerSection * numSections);
148296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		for (int i = 0; i < static_cast<int>(clipDistances.size()); ++i)
148396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			clipDistances[i] = rnd.getFloat(-1.0f, 1.0f);
148496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
148596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Two sets of identical primitives, but with a different ClipDistance sign.
148696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		for (int setNdx = 0; setNdx < 2; ++setNdx)
148796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
148896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const float sign = (setNdx == 0 ? 1.0f : -1.0f);
148996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const float	dx	 = 2.0f / static_cast<float>(numSections);
149096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
149196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int i = 0; i < numSections; ++i)
149296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
149396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const int	ndxBase	= numVerticesPerSection * i;
149496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const float x		= -1.0f + dx * static_cast<float>(i);
149596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const Vec4	p0		= Vec4(x,      -1.0f, 0.0f, sign * clipDistances[ndxBase + 0]);
149696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const Vec4	p1		= Vec4(x,       1.0f, 0.0f, sign * clipDistances[ndxBase + 1]);
149796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const Vec4	p2		= Vec4(x + dx,  1.0f, 0.0f, sign * clipDistances[ndxBase + 2]);
149896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const Vec4	p3		= Vec4(x + dx, -1.0f, 0.0f, sign * clipDistances[ndxBase + 3]);
149996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
150096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				vertices.push_back(p0);
150196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				vertices.push_back(p1);
150296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				vertices.push_back(p2);
150396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
150496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				vertices.push_back(p2);
150596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				vertices.push_back(p3);
150696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				vertices.push_back(p0);
150796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			}
150896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
150996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
151096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
151196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestLog& log = context.getTestContext().getLog();
151296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
151396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	log << tcu::TestLog::Message << "Draw two sets of primitives with blending, differing only with ClipDistance sign." << tcu::TestLog::EndMessage
151496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		<< tcu::TestLog::Message << "Using " << numClipDistances << " clipping plane(s), one of them possibly having negative values." << tcu::TestLog::EndMessage
151596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		<< tcu::TestLog::Message << "Expecting a uniform gray area, no missing (black) nor overlapped (white) pixels." << tcu::TestLog::EndMessage;
151696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
151796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	DrawContext drawContext(context, shaders, vertices, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, static_cast<deUint32>(RENDER_SIZE_LARGE), false, true);
151896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	drawContext.draw();
151996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
152096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int numGrayPixels		= countPixels(drawContext.getColorPixels(), Vec4(0.5f, 0.5f, 0.5f, 1.0f), Vec4(0.02f, 0.02f, 0.02f, 0.0f));
152196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	const int numExpectedPixels	= RENDER_SIZE_LARGE * RENDER_SIZE_LARGE;
152296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
152396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return (numGrayPixels == numExpectedPixels ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Rendered image(s) are incorrect"));
152496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
152596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
152696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski} // ClipDistanceComplementarity ns
152796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
152896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskivoid addClippingTests (tcu::TestCaseGroup* clippingTestsGroup)
152996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
153096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	tcu::TestContext& testCtx = clippingTestsGroup->getTestContext();
153196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
153296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// Clipping against the clip volume
153396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
153496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		using namespace ClipVolume;
153596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
153696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		static const VkPrimitiveTopology cases[] =
153796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
153896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
153996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
154096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
154196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
154296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
154396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
154496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
154596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
154696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
154796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
154896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		};
1549a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos
155096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		MovePtr<tcu::TestCaseGroup> clipVolumeGroup(new tcu::TestCaseGroup(testCtx, "clip_volume", "clipping with the clip volume"));
155196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
155296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Fully inside the clip volume
155396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
155496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "inside", ""));
155596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
155696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); ++caseNdx)
155796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				addFunctionCaseWithPrograms<VkPrimitiveTopology>(
155896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					group.get(), getPrimitiveTopologyShortName(cases[caseNdx]), "", initPrograms, testPrimitivesInside, cases[caseNdx]);
155996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
156096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			clipVolumeGroup->addChild(group.release());
156196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
156296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
156396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Fully outside the clip volume
156496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
156596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "outside", ""));
156696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
156796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); ++caseNdx)
156896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				addFunctionCaseWithPrograms<VkPrimitiveTopology>(
156996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					group.get(), getPrimitiveTopologyShortName(cases[caseNdx]), "", initPrograms, testPrimitivesOutside, cases[caseNdx]);
157096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
157196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			clipVolumeGroup->addChild(group.release());
157296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
157396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
157496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Depth clamping
157596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
157696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "depth_clamp", ""));
157796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
157896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); ++caseNdx)
157996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				addFunctionCaseWithPrograms<VkPrimitiveTopology>(
158096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					group.get(), getPrimitiveTopologyShortName(cases[caseNdx]), "", initPrograms, testPrimitivesDepthClamp, cases[caseNdx]);
158196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
158296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			clipVolumeGroup->addChild(group.release());
158396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
158496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
158596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Large points and wide lines
158696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
158796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			// \note For both points and lines, if an unsupported size/width is selected, the nearest supported size will be chosen.
158896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			//       We do have to check for feature support though.
158996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
159096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "clipped", ""));
159196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
159296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			addFunctionCaseWithPrograms(group.get(), "large_points", "", initProgramsPointSize, testLargePoints);
159396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
159496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			addFunctionCaseWithPrograms<LineOrientation>(group.get(), "wide_lines_axis_aligned", "", initPrograms, testWideLines, LINE_ORIENTATION_AXIS_ALIGNED);
159596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			addFunctionCaseWithPrograms<LineOrientation>(group.get(), "wide_lines_diagonal",	 "", initPrograms, testWideLines, LINE_ORIENTATION_DIAGONAL);
159696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
159796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			clipVolumeGroup->addChild(group.release());
159896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
159996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
160096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		clippingTestsGroup->addChild(clipVolumeGroup.release());
160196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
160296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
160396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	// User-defined clip planes
160496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	{
160596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		MovePtr<tcu::TestCaseGroup> clipDistanceGroup(new tcu::TestCaseGroup(testCtx, "user_defined", "user-defined clip planes"));
160696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
160796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// ClipDistance, CullDistance and maxCombinedClipAndCullDistances usage
160896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
160996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			using namespace ClipDistance;
161096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
161196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			static const struct
161296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
161396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const char* const	groupName;
161496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const char* const	description;
161596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				bool				useCullDistance;
161696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			} caseGroups[] =
161796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
161896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				{ "clip_distance",		"use ClipDistance",										false },
161996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				{ "clip_cull_distance",	"use ClipDistance and CullDistance at the same time",	true  },
162096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			};
162196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
162296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const deUint32 flagTessellation = 1u << 0;
162396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			const deUint32 flagGeometry		= 1u << 1;
162496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
162596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(caseGroups); ++groupNdx)
162696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int indexingMode = 0; indexingMode < 2; ++indexingMode)
162796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			{
162896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const bool			dynamicIndexing	= (indexingMode == 1);
162996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				const std::string	mainGroupName	= de::toString(caseGroups[groupNdx].groupName) + (dynamicIndexing ? "_dynamic_index" : "");
163096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
163196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				MovePtr<tcu::TestCaseGroup>	mainGroup(new tcu::TestCaseGroup(testCtx, mainGroupName.c_str(), ""));
163296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
163396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				for (deUint32 shaderMask = 0u; shaderMask <= (flagTessellation | flagGeometry); ++shaderMask)
163496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				{
163596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const bool			useTessellation	= (shaderMask & flagTessellation) != 0;
163696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const bool			useGeometry		= (shaderMask & flagGeometry) != 0;
163796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					const std::string	shaderGroupName	= std::string("vert") + (useTessellation ? "_tess" : "") + (useGeometry ? "_geom" : "");
163896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
163996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					MovePtr<tcu::TestCaseGroup>	shaderGroup(new tcu::TestCaseGroup(testCtx, shaderGroupName.c_str(), ""));
164096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
164196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					for (int numClipPlanes = 1; numClipPlanes <= MAX_CLIP_DISTANCES; ++numClipPlanes)
164296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					{
164396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						const int					numCullPlanes	= (caseGroups[groupNdx].useCullDistance
164496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski																		? std::min(static_cast<int>(MAX_CULL_DISTANCES), MAX_COMBINED_CLIP_AND_CULL_DISTANCES - numClipPlanes)
164596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski																		: 0);
164696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						const std::string			caseName		= de::toString(numClipPlanes) + (numCullPlanes > 0 ? "_" + de::toString(numCullPlanes) : "");
164796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						const VkPrimitiveTopology	topology		= (useTessellation ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
164896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
164996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski						addFunctionCaseWithPrograms<CaseDefinition>(
165096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski							shaderGroup.get(), caseName, caseGroups[groupNdx].description, initPrograms, testClipDistance,
165196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski							CaseDefinition(topology, numClipPlanes, numCullPlanes, useTessellation, useGeometry, dynamicIndexing));
165296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					}
165396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski					mainGroup->addChild(shaderGroup.release());
165496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				}
165596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				clipDistanceGroup->addChild(mainGroup.release());
165696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			}
165796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
165896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
165996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		// Complementarity criterion (i.e. clipped and not clipped areas must add up to a complete primitive with no holes nor overlap)
166096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		{
166196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			using namespace ClipDistanceComplementarity;
166296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
166396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			MovePtr<tcu::TestCaseGroup>	group(new tcu::TestCaseGroup(testCtx, "complementarity", ""));
166496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
166596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			for (int numClipDistances = 1; numClipDistances <= MAX_CLIP_DISTANCES; ++numClipDistances)
166696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski				addFunctionCaseWithPrograms<int>(group.get(), de::toString(numClipDistances).c_str(), "", initPrograms, testComplementarity, numClipDistances);
166796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
166896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski			clippingTestsGroup->addChild(group.release());
166996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		}
167096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
167196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski		clippingTestsGroup->addChild(clipDistanceGroup.release());
167296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	}
167396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
167496aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
167596aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski} // anonymous
167696aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
167796aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowskitcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
167896aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski{
167996aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski	return createTestGroup(testCtx, "clipping", "Clipping tests", addClippingTests);
168096aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski}
168196aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski
168296aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski} // clipping
168396aebab21a68bd028540b76577ba5ba383a1bc50Maciej Jesionowski} // vkt
1684