1abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*------------------------------------------------------------------------
2abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Vulkan Conformance Tests
3abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * ------------------------
4abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
5abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2014 The Android Open Source Project
6abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2016 The Khronos Group Inc.
7abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
8abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Licensed under the Apache License, Version 2.0 (the "License");
9abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * you may not use this file except in compliance with the License.
10abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * You may obtain a copy of the License at
11abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
12abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *      http://www.apache.org/licenses/LICENSE-2.0
13abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
14abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Unless required by applicable law or agreed to in writing, software
15abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * distributed under the License is distributed on an "AS IS" BASIS,
16abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * See the License for the specific language governing permissions and
18abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * limitations under the License.
19abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *
20abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*!
21abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \file
22abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Tessellation Miscellaneous Draw Tests
23abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/
24abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
25abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationMiscDrawTests.hpp"
26abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTestCaseUtil.hpp"
27abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationUtil.hpp"
28abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
29abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuTestLog.hpp"
30abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuImageIO.hpp"
31abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuTexture.hpp"
32abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuImageCompare.hpp"
33abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
34abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkDefs.hpp"
35abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkQueryUtil.hpp"
36abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkBuilderUtil.hpp"
37abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkImageUtil.hpp"
38abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkTypeUtil.hpp"
39abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkStrUtil.hpp"
40abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
41abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deUniquePtr.hpp"
42abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deStringUtil.hpp"
43abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
44abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include <string>
45abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include <vector>
46abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
47abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace vkt
48abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
49abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace tessellation
50abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
51abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
52abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiusing namespace vk;
53abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
54abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace
55abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
56abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
57abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct CaseDefinition
58abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
59abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	TessPrimitiveType	primitiveType;
60abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	SpacingMode			spacingMode;
61abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::string			referenceImagePathPrefix;	//!< without case suffix and extension (e.g. "_1.png")
62abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski};
63abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
64abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline CaseDefinition makeCaseDefinition (const TessPrimitiveType	primitiveType,
65abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  const SpacingMode			spacingMode,
66abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski										  const std::string&		referenceImagePathPrefix)
67abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
68abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	CaseDefinition caseDef;
69abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	caseDef.primitiveType = primitiveType;
70abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	caseDef.spacingMode = spacingMode;
71abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	caseDef.referenceImagePathPrefix = referenceImagePathPrefix;
72abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return caseDef;
73abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
74abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
75abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<TessLevels> genTessLevelCases (const SpacingMode spacingMode)
76abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
77abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	static const TessLevels tessLevelCases[] =
78abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
79abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ { 9.0f,	9.0f	},	{ 9.0f,		9.0f,	9.0f,	9.0f	} },
80abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ { 8.0f,	11.0f	},	{ 13.0f,	15.0f,	18.0f,	21.0f	} },
81abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{ { 17.0f,	14.0f	},	{ 3.0f,		6.0f,	9.0f,	12.0f	} },
82abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
83abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
84abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::vector<TessLevels> resultTessLevels(DE_LENGTH_OF_ARRAY(tessLevelCases));
85abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
86abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < DE_LENGTH_OF_ARRAY(tessLevelCases); ++tessLevelCaseNdx)
87abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
88abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		TessLevels& tessLevels = resultTessLevels[tessLevelCaseNdx];
89abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
90abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < 2; ++i)
91abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessLevels.inner[i] = static_cast<float>(getClampedRoundedTessLevel(spacingMode, tessLevelCases[tessLevelCaseNdx].inner[i]));
92abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
93abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		for (int i = 0; i < 4; ++i)
94abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tessLevels.outer[i] = static_cast<float>(getClampedRoundedTessLevel(spacingMode, tessLevelCases[tessLevelCaseNdx].outer[i]));
95abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
96abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
97abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return resultTessLevels;
98abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
99abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<tcu::Vec2> genVertexPositions (const TessPrimitiveType primitiveType)
101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	std::vector<tcu::Vec2> positions;
103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	positions.reserve(4);
104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	if (primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2( 0.8f,    0.6f));
108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2( 0.0f, -0.786f));
109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2(-0.8f,    0.6f));
110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else if (primitiveType == TESSPRIMITIVETYPE_QUADS || primitiveType == TESSPRIMITIVETYPE_ISOLINES)
112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2(-0.8f, -0.8f));
114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2( 0.8f, -0.8f));
115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2(-0.8f,  0.8f));
116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		positions.push_back(tcu::Vec2( 0.8f,  0.8f));
117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	else
119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		DE_ASSERT(false);
120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return positions;
122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Common test function used by all test cases.
125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus runTest (Context& context, const CaseDefinition caseDef)
126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER);
128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const DeviceInterface&	vk					= context.getDeviceInterface();
130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDevice			device				= context.getDevice();
131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkQueue			queue				= context.getUniversalQueue();
132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	Allocator&				allocator			= context.getDefaultAllocator();
134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const std::vector<TessLevels> tessLevelCases = genTessLevelCases(caseDef.spacingMode);
136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const std::vector<tcu::Vec2>  vertexData	 = genVertexPositions(caseDef.primitiveType);
137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const deUint32				  inPatchSize	 = (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 4);
138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Vertex input: positions
140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkFormat	   vertexFormat		   = VK_FORMAT_R32G32_SFLOAT;
142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const deUint32	   vertexStride		   = tcu::getPixelSize(mapVkFormat(vertexFormat));
143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDeviceSize vertexDataSizeBytes = sizeInBytes(vertexData);
144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Buffer vertexBuffer(vk, device, allocator,
146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible);
147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(inPatchSize == vertexData.size());
149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(sizeof(vertexData[0]) == vertexStride);
150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const Allocation& alloc = vertexBuffer.getAllocation();
153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		deMemcpy(alloc.getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeBytes));
154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexDataSizeBytes);
156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// No barrier needed, flushed memory is automatically visible
157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Color attachment
160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const tcu::IVec2			  renderSize				 = tcu::IVec2(256, 256);
162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkFormat				  colorFormat				 = VK_FORMAT_R8G8B8A8_UNORM;
163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Image					  colorAttachmentImage		 (vk, device, allocator,
165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 1u),
166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski															 MemoryRequirement::Any);
167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Color output buffer: image will be copied here for verification
169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDeviceSize colorBufferSizeBytes = renderSize.x()*renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Buffer	   colorBuffer			(vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
172abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
173abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Input buffer: tessellation levels. Data is filled in later.
174abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
175abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Buffer tessLevelsBuffer(vk, device, allocator,
176abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		makeBufferCreateInfo(sizeof(TessLevels), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
177abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
178abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Descriptors
179abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
180abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
181abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
182abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.build(vk, device));
183abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
184abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
185abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
186abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
187abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
188abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
189abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
190abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const VkDescriptorBufferInfo tessLevelsBufferInfo = makeDescriptorBufferInfo(tessLevelsBuffer.get(), 0ull, sizeof(TessLevels));
191abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
192abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DescriptorSetUpdateBuilder()
193abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &tessLevelsBufferInfo)
194abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.update(vk, device);
195abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
196abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Pipeline
197abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
198abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkImageView>		colorAttachmentView	(makeImageView		(vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange));
199abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkRenderPass>		renderPass			(makeRenderPass		(vk, device, colorFormat));
200abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkFramebuffer>		framebuffer			(makeFramebuffer	(vk, device, *renderPass, *colorAttachmentView, renderSize.x(), renderSize.y(), 1u));
201abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout	(vk, device, *descriptorSetLayout));
202abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkCommandPool>		cmdPool				(makeCommandPool	(vk, device, queueFamilyIndex));
203abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkCommandBuffer>	cmdBuffer			(makeCommandBuffer	(vk, device, *cmdPool));
204abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
205abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	const Unique<VkPipeline> pipeline(GraphicsPipelineBuilder()
206abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setRenderSize				  (renderSize)
207abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setVertexInputSingleAttribute(vertexFormat, vertexStride)
208abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setPatchControlPoints		  (inPatchSize)
209abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader					  (vk, device, VK_SHADER_STAGE_VERTEX_BIT,					context.getBinaryCollection().get("vert"), DE_NULL)
210abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader					  (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,	context.getBinaryCollection().get("tesc"), DE_NULL)
211abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader					  (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get("tese"), DE_NULL)
212abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.setShader					  (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT,				context.getBinaryCollection().get("frag"), DE_NULL)
213abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		.build						  (vk, device, *pipelineLayout, *renderPass));
214abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
215abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Draw commands
216abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
217abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	deUint32 numPassedCases = 0;
218abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
219abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (deUint32 tessLevelCaseNdx = 0; tessLevelCaseNdx < tessLevelCases.size(); ++tessLevelCaseNdx)
220abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
221abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		context.getTestContext().getLog()
222abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< tcu::TestLog::Message
223abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "Tessellation levels: " << getTessellationLevelsString(tessLevelCases[tessLevelCaseNdx], caseDef.primitiveType)
224abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< tcu::TestLog::EndMessage;
225abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
226abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Upload tessellation levels data to the input buffer
227abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
228abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const Allocation& alloc = tessLevelsBuffer.getAllocation();
229abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			TessLevels* const bufferTessLevels = static_cast<TessLevels*>(alloc.getHostPtr());
230abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			*bufferTessLevels = tessLevelCases[tessLevelCaseNdx];
231abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(TessLevels));
232abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
233abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
234abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Reset the command buffer and begin recording.
235abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		beginCommandBuffer(vk, *cmdBuffer);
236abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
237abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Change color attachment image layout
238abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
239abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			// State is slightly different on the first iteration.
240abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkImageLayout currentLayout = (tessLevelCaseNdx == 0 ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
2416e5ef4c51158771e71f72c70980b4dbd78f011f2Pyry Haulos			const VkAccessFlags srcFlags	  = (tessLevelCaseNdx == 0 ? (VkAccessFlags)0 : (VkAccessFlags)VK_ACCESS_TRANSFER_READ_BIT);
242abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
243abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
244abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				srcFlags, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
245abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				currentLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
246abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				*colorAttachmentImage, colorImageSubresourceRange);
247abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
248abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u,
249abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
250abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
251abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
252abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Begin render pass
253abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
254abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkRect2D renderArea = {
255abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				makeOffset2D(0, 0),
256abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				makeExtent2D(renderSize.x(), renderSize.y()),
257abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			};
258abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
259abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
260abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
261abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
262abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
263abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
264abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
265abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
266abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkDeviceSize vertexBufferOffset = 0ull;
267abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
268abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
269abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
270abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Process enough vertices to make a patch.
271abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		vk.cmdDraw(*cmdBuffer, inPatchSize, 1u, 0u, 0u);
272abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		endRenderPass(vk, *cmdBuffer);
273abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
274abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		// Copy render result to a host-visible buffer
275abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
276abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkImageMemoryBarrier colorAttachmentPreCopyBarrier = makeImageMemoryBarrier(
277abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
278abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
279abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				*colorAttachmentImage, colorImageSubresourceRange);
280abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
281abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
282abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentPreCopyBarrier);
283abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
284abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
2851d185cb7ef57f375fcdf78cb50a7b4b5e3e4923ePyry Haulos			const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(renderSize.x(), renderSize.y(), 1), makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
286abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorAttachmentImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &copyRegion);
287abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
288abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
289abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
290abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes);
291abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
292abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
293abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				0u, DE_NULL, 1u, &postCopyBarrier, 0u, DE_NULL);
294abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
295abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
296abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		endCommandBuffer(vk, *cmdBuffer);
297abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
298abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
299abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		{
300abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const Allocation& colorBufferAlloc = colorBuffer.getAllocation();
301abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			invalidateMappedMemoryRange(vk, device, colorBufferAlloc.getMemory(), colorBufferAlloc.getOffset(), colorBufferSizeBytes);
302abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
303abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			// Verify case result
304abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const tcu::ConstPixelBufferAccess resultImageAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc.getHostPtr());
305abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
306abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			// Load reference image
307abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			const std::string referenceImagePath = caseDef.referenceImagePathPrefix + "_" + de::toString(tessLevelCaseNdx) + ".png";
308abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tcu::TextureLevel referenceImage;
309abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			tcu::ImageIO::loadPNG(referenceImage, context.getTestContext().getArchive(), referenceImagePath.c_str());
310abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
311abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			if (tcu::fuzzyCompare(context.getTestContext().getLog(), "ImageComparison", "Image Comparison",
312abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski								  referenceImage.getAccess(), resultImageAccess, 0.002f, tcu::COMPARE_LOG_RESULT))
313abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				++numPassedCases;
314abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		}
315abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	} // tessLevelCaseNdx
316abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
317abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return (numPassedCases == tessLevelCases.size() ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Failure"));
318abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
319abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
320abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline const char* getTessLevelsSSBODeclaration (void)
321abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
322abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return	"layout(set = 0, binding = 0, std430) readonly restrict buffer TessLevels {\n"
323abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"    float inner0;\n"
324abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"    float inner1;\n"
325abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"    float outer0;\n"
326abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"    float outer1;\n"
327abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"    float outer2;\n"
328abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"    float outer3;\n"
329abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			"} sb_levels;\n";
330abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
331abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
332abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Add vertex, fragment, and tessellation control shaders.
333abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid initCommonPrograms (vk::SourceCollections& programCollection, const CaseDefinition caseDef)
334abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
335abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(!programCollection.glslSources.contains("vert"));
336abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(!programCollection.glslSources.contains("tesc"));
337abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(!programCollection.glslSources.contains("frag"));
338abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
339abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Vertex shader
340abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
341abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
342abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
343abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
344abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) in  highp vec2 in_v_position;\n"
345abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out highp vec2 in_tc_position;\n"
346abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
347abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
348abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
349abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    in_tc_position = in_v_position;\n"
350abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
351abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
352abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
353abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
354abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
355abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Tessellation control shader
356abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
357abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const int numVertices = (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 4);
358abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
359abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
360abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
361abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "#extension GL_EXT_tessellation_shader : require\n"
362abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
363abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(vertices = " << numVertices << ") out;\n"
364abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
365abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< getTessLevelsSSBODeclaration()
366abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
367abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) in  highp vec2 in_tc_position[];\n"
368abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out highp vec2 in_te_position[];\n"
369abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
370abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
371abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
372abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    in_te_position[gl_InvocationID] = in_tc_position[gl_InvocationID];\n"
373abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
374abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelInner[0] = sb_levels.inner0;\n"
375abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelInner[1] = sb_levels.inner1;\n"
376abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
377abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[0] = sb_levels.outer0;\n"
378abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[1] = sb_levels.outer1;\n"
379abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[2] = sb_levels.outer2;\n"
380abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_TessLevelOuter[3] = sb_levels.outer3;\n"
381abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
382abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
383abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
384abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
385abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
386abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Fragment shader
387abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
388abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
389abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
390abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
391abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) in  highp   vec4 in_f_color;\n"
392abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out mediump vec4 o_color;\n"
393abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
394abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
395abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
396abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    o_color = in_f_color;\n"
397abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
398abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
399abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
400abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
401abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
402abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
403abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid initProgramsFillCoverCase (vk::SourceCollections& programCollection, const CaseDefinition caseDef)
404abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
405abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES || caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS);
406abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
407abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	initCommonPrograms(programCollection, caseDef);
408abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
409abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Tessellation evaluation shader
410abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
411abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
412abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
413abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "#extension GL_EXT_tessellation_shader : require\n"
414abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
415abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(" << getTessPrimitiveTypeShaderName(caseDef.primitiveType) << ", "
416abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						 << getSpacingModeShaderName(caseDef.spacingMode) << ") in;\n"
417abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
418abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) in  highp vec2 in_te_position[];\n"
419abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out highp vec4 in_f_color;\n"
420abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
421abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
422abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
423abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<<	(caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
424abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp float d = 3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z));\n"
425abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner0 = in_te_position[0];\n"
426abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner1 = in_te_position[1];\n"
427abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner2 = in_te_position[2];\n"
428abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 pos =  corner0*gl_TessCoord.x + corner1*gl_TessCoord.y + corner2*gl_TessCoord.z;\n"
429abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 fromCenter = pos - (corner0 + corner1 + corner2) / 3.0;\n"
430abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp float f = (1.0 - length(fromCenter)) * (1.5 - d);\n"
431abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    pos += 0.75 * f * fromCenter / (length(fromCenter) + 0.3);\n"
432abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    gl_Position = vec4(pos, 0.0, 1.0);\n"
433abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				: caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS ?
434abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner0 = in_te_position[0];\n"
435abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner1 = in_te_position[1];\n"
436abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner2 = in_te_position[2];\n"
437abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner3 = in_te_position[3];\n"
438abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n"
439abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"                   + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n"
440abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"                   + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*corner2\n"
441abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"                   + (    gl_TessCoord.x)*(    gl_TessCoord.y)*corner3;\n"
442abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp float d = 2.0 * min(abs(gl_TessCoord.x-0.5), abs(gl_TessCoord.y-0.5));\n"
443abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 fromCenter = pos - (corner0 + corner1 + corner2 + corner3) / 4.0;\n"
444abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp float f = (1.0 - length(fromCenter)) * sqrt(1.7 - d);\n"
445abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    pos += 0.75 * f * fromCenter / (length(fromCenter) + 0.3);\n"
446abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    gl_Position = vec4(pos, 0.0, 1.0);\n"
447abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				: "")
448abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    in_f_color = vec4(1.0);\n"
449abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
450abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
451abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
452abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
453abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
454abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
455abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid initProgramsFillNonOverlapCase (vk::SourceCollections& programCollection, const CaseDefinition caseDef)
456abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
457abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES || caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS);
458abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
459abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	initCommonPrograms(programCollection, caseDef);
460abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
461abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Tessellation evaluation shader
462abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
463abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
464abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
465abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "#extension GL_EXT_tessellation_shader : require\n"
466abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
467abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(" << getTessPrimitiveTypeShaderName(caseDef.primitiveType) << ", "
468abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						 << getSpacingModeShaderName(caseDef.spacingMode) << ") in;\n"
469abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
470abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< getTessLevelsSSBODeclaration()
471abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
472abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) in  highp vec2 in_te_position[];\n"
473abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out highp vec4 in_f_color;\n"
474abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
475abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
476abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
477abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<<	(caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ?
478abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner0 = in_te_position[0];\n"
479abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner1 = in_te_position[1];\n"
480abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner2 = in_te_position[2];\n"
481abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 pos =  corner0*gl_TessCoord.x + corner1*gl_TessCoord.y + corner2*gl_TessCoord.z;\n"
482abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    gl_Position = vec4(pos, 0.0, 1.0);\n"
483abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp int numConcentricTriangles = int(round(sb_levels.inner0)) / 2 + 1;\n"
484abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp float d = 3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z));\n"
485abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp int phase = int(d*float(numConcentricTriangles)) % 3;\n"
486abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n"
487abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"               : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n"
488abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"               :              vec4(0.0, 0.0, 1.0, 1.0);\n"
489abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski				: caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS ?
490abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner0 = in_te_position[0];\n"
491abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner1 = in_te_position[1];\n"
492abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner2 = in_te_position[2];\n"
493abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 corner3 = in_te_position[3];\n"
494abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n"
495abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"                   + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n"
496abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"                   + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*corner2\n"
497abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"                   + (    gl_TessCoord.x)*(    gl_TessCoord.y)*corner3;\n"
498abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    gl_Position = vec4(pos, 0.0, 1.0);\n"
499abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp int phaseX = int(round((0.5 - abs(gl_TessCoord.x-0.5)) * sb_levels.inner0));\n"
500abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp int phaseY = int(round((0.5 - abs(gl_TessCoord.y-0.5)) * sb_levels.inner1));\n"
501abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    highp int phase = min(phaseX, phaseY) % 3;\n"
502abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"    in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n"
503abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"               : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n"
504abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					"               :              vec4(0.0, 0.0, 1.0, 1.0);\n"
505abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski					: "")
506abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
507abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
508abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
509abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
510abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
511abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
512abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid initProgramsIsolinesCase (vk::SourceCollections& programCollection, const CaseDefinition caseDef)
513abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
514abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	DE_ASSERT(caseDef.primitiveType == TESSPRIMITIVETYPE_ISOLINES);
515abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
516abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	initCommonPrograms(programCollection, caseDef);
517abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
518abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Tessellation evaluation shader
519abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
520abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		std::ostringstream src;
521abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
522abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "#extension GL_EXT_tessellation_shader : require\n"
523abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
524abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(" << getTessPrimitiveTypeShaderName(caseDef.primitiveType) << ", "
525abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski						 << getSpacingModeShaderName(caseDef.spacingMode) << ") in;\n"
526abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
527abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< getTessLevelsSSBODeclaration()
528abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
529abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) in  highp vec2 in_te_position[];\n"
530abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "layout(location = 0) out highp vec4 in_f_color;\n"
531abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "\n"
532abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "void main (void)\n"
533abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "{\n"
534abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp vec2 corner0 = in_te_position[0];\n"
535abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp vec2 corner1 = in_te_position[1];\n"
536abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp vec2 corner2 = in_te_position[2];\n"
537abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp vec2 corner3 = in_te_position[3];\n"
538abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n"
539abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "                   + (    gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n"
540abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "                   + (1.0-gl_TessCoord.x)*(    gl_TessCoord.y)*corner2\n"
541abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "                   + (    gl_TessCoord.x)*(    gl_TessCoord.y)*corner3;\n"
542abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    pos.y += 0.15*sin(gl_TessCoord.x*10.0);\n"
543abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    gl_Position = vec4(pos, 0.0, 1.0);\n"
544abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp int phaseX = int(round(gl_TessCoord.x*sb_levels.outer1));\n"
545abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp int phaseY = int(round(gl_TessCoord.y*sb_levels.outer0));\n"
546abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    highp int phase = (phaseX + phaseY) % 3;\n"
547abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "    in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n"
548abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "               : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n"
549abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "               :              vec4(0.0, 0.0, 1.0, 1.0);\n"
550abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski			<< "}\n";
551abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
552abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
553abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
554abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
555abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
556abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline std::string getReferenceImagePathPrefix (const std::string& caseName)
557abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
558abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return "vulkan/data/tessellation/" + caseName + "_ref";
559abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
560abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
561abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // anonymous
562abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
563abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! These tests correspond to dEQP-GLES31.functional.tessellation.misc_draw.*
564abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCaseGroup* createMiscDrawTests (tcu::TestContext& testCtx)
565abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{
566abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "misc_draw", "Miscellaneous draw-result-verifying cases"));
567abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
568abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	static const TessPrimitiveType primitivesNoIsolines[] =
569abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
570abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		TESSPRIMITIVETYPE_TRIANGLES,
571abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		TESSPRIMITIVETYPE_QUADS,
572abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	};
573abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
574abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Triangle fill case
575abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitivesNoIsolines); ++primitiveTypeNdx)
576abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; ++spacingModeNdx)
577abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
578abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const TessPrimitiveType primitiveType = primitivesNoIsolines[primitiveTypeNdx];
579abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const SpacingMode		spacingMode	  = static_cast<SpacingMode>(spacingModeNdx);
580abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const std::string		caseName	  = std::string() + "fill_cover_" + getTessPrimitiveTypeShaderName(primitiveType) + "_" + getSpacingModeShaderName(spacingMode);
581abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
582abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		addFunctionCaseWithPrograms(group.get(), caseName, "Check that there are no obvious gaps in the triangle-filled area of a tessellated shape",
583abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									initProgramsFillCoverCase, runTest, makeCaseDefinition(primitiveType, spacingMode, getReferenceImagePathPrefix(caseName)));
584abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
585abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
586abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Triangle non-overlap case
587abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitivesNoIsolines); ++primitiveTypeNdx)
588abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; ++spacingModeNdx)
589abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
590abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const TessPrimitiveType primitiveType = primitivesNoIsolines[primitiveTypeNdx];
591abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const SpacingMode		spacingMode	  = static_cast<SpacingMode>(spacingModeNdx);
592abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const std::string		caseName	  = std::string() + "fill_overlap_" + getTessPrimitiveTypeShaderName(primitiveType) + "_" + getSpacingModeShaderName(spacingMode);
593abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
594abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		addFunctionCaseWithPrograms(group.get(), caseName, "Check that there are no obvious triangle overlaps in the triangle-filled area of a tessellated shape",
595abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									initProgramsFillNonOverlapCase, runTest, makeCaseDefinition(primitiveType, spacingMode, getReferenceImagePathPrefix(caseName)));
596abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
597abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
598abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	// Isolines
599abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; ++spacingModeNdx)
600abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	{
601abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const SpacingMode spacingMode = static_cast<SpacingMode>(spacingModeNdx);
602abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		const std::string caseName    = std::string() + "isolines_" + getSpacingModeShaderName(spacingMode);
603abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
604abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski		addFunctionCaseWithPrograms(group.get(), caseName, "Basic isolines render test",
605abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski									initProgramsIsolinesCase, runTest, makeCaseDefinition(TESSPRIMITIVETYPE_ISOLINES, spacingMode, getReferenceImagePathPrefix(caseName)));
606abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	}
607abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
608abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski	return group.release();
609abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}
610abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski
611abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // tessellation
612abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // vkt
613