• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Shader cross-stage interface tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSpvAsmCrossStageInterfaceTests.hpp"
25 
26 #include "tcuTestLog.hpp"
27 #include "tcuTextureUtil.hpp"
28 #include "tcuImageCompare.hpp"
29 
30 #include "vkDefs.hpp"
31 #include "vkMemUtil.hpp"
32 #include "deSharedPtr.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkStrUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40 
41 #include "deUniquePtr.hpp"
42 
43 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 
47 #include <map>
48 #include <vector>
49 
50 namespace vkt
51 {
52 namespace SpirVAssembly
53 {
54 using namespace vk;
55 
56 namespace
57 {
58 using std::string;
59 using std::map;
60 using std::vector;
61 
62 typedef de::SharedPtr<Unique<VkShaderModule> >	ShaderModuleSP;
63 using de::MovePtr;
64 
65 using tcu::Vec4;
66 
67 enum TestType
68 {
69 	TEST_TYPE_FLAT = 0,
70 	TEST_TYPE_NOPERSPECTIVE,
71 	TEST_TYPE_RELAXEDPRECISION,
72 	TEST_TYPE_LAST
73 };
74 
75 struct TestParameters
76 {
TestParametersvkt::SpirVAssembly::__anon21c269370111::TestParameters77 	TestParameters (TestType q, size_t s)
78 		:testOptions	(s)
79 		,qualifier		(q)
80 	{}
81 	vector<int>		testOptions;
82 	TestType		qualifier;
83 };
84 
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage,deUint32 queueFamilyIndex)85 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage, deUint32 queueFamilyIndex)
86 {
87 	const VkImageCreateInfo imageInfo	=
88 	{
89 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
90 		DE_NULL,									// const void*				pNext;
91 		(VkImageCreateFlags)0,						// VkImageCreateFlags		flags;
92 		imageType,									// VkImageType				imageType;
93 		format,										// VkFormat					format;
94 		{extent.width, extent.height, 1u},			// VkExtent3D				extent;
95 		1u,											// uint32_t					mipLevels;
96 		extent.depth,								// uint32_t					arrayLayers;
97 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
98 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
99 		usage,										// VkImageUsageFlags		usage;
100 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
101 		1u,											// uint32_t					queueFamilyIndexCount;
102 		&queueFamilyIndex,							// const uint32_t*			pQueueFamilyIndices;
103 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			initialLayout;
104 	};
105 	return imageInfo;
106 }
107 
imageBarrier(const DeviceInterface & vk,const VkCommandBuffer cmdBuffer,const VkImage image,const VkImageSubresourceRange subresourceRange,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkPipelineStageFlags srcStageMask,const VkPipelineStageFlags dstStageMask)108 void imageBarrier (const DeviceInterface&			vk,
109 				   const VkCommandBuffer			cmdBuffer,
110 				   const VkImage					image,
111 				   const VkImageSubresourceRange	subresourceRange,
112 				   const VkImageLayout				oldLayout,
113 				   const VkImageLayout				newLayout,
114 				   const VkAccessFlags				srcAccessMask,
115 				   const VkAccessFlags				dstAccessMask,
116 				   const VkPipelineStageFlags		srcStageMask,
117 				   const VkPipelineStageFlags		dstStageMask)
118 {
119 	const VkImageMemoryBarrier		barrier				=
120 	{
121 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
122 		DE_NULL,								// const void*				pNext;
123 		srcAccessMask,							// VkAccessFlags			srcAccessMask;
124 		dstAccessMask,							// VkAccessFlags			dstAccessMask;
125 		oldLayout,								// VkImageLayout			oldLayout;
126 		newLayout,								// VkImageLayout			newLayout;
127 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
128 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
129 		image,									// VkImage					image;
130 		subresourceRange,						// VkImageSubresourceRange	subresourceRange;
131 	};
132 
133 	vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL,
134 		0u, (const VkBufferMemoryBarrier*)DE_NULL,
135 		1u, &barrier);
136 }
137 
138 class CrossStageTestInstance : public TestInstance
139 {
140 public:
CrossStageTestInstance(Context & context,const TestParameters & parameters)141 	CrossStageTestInstance	(Context& context, const TestParameters& parameters)
142 	: TestInstance		(context)
143 	, m_parameters		(parameters)
144 	, m_verticesCount	(4u)
145 	, m_data			(2u * m_verticesCount)
146 	, m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
147 	, m_colorRed		(1.0f, 0.0f, 0.0f, 1.0f)
148 	, m_colorGreen		(0.0f, 1.0f, 0.0f, 1.0f)
149 	{
150 		createVertexData();
151 		m_extent.width	= 51u;
152 		m_extent.height	= 51u;
153 		m_extent.depth	= 1u;
154 	}
155 enum
156 {
157 	DECORATION_IN_VERTEX = 0,
158 	DECORATION_IN_FRAGMENT,
159 	DECORATION_IN_ALL_SHADERS,
160 	DECORATION_LAST
161 };
162 protected:
163 	tcu::TestStatus			iterate					(void);
164 private:
165 	void					createVertexData		(void);
166 	void					makeShaderModule		(map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModule,
167 													 const VkShaderStageFlagBits					stageFlag,
168 													 const int										optionNdx);
169 
170 	Move<VkPipeline>		makeGraphicsPipeline	(const VkRenderPass								renderPass,
171 													 const VkPipelineLayout							pipelineLayout,
172 													 const VkShaderStageFlagBits					stageFlags,
173 													 map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModules,
174 													 const VkPrimitiveTopology						primitiveTopology);
175 
176 	bool					checkImage				(VkImage										image,
177 													 VkCommandPool									cmdPool,
178 													 VkCommandBuffer								cmdBuffer,
179 													 const string&									description,
180 													 const tcu::Texture2DArray&						referenceFrame);
181 	void					interpolationFill		(tcu::Texture2DArray&							referenceFrame);
182 	void					perspectiveFill			(tcu::Texture2DArray&							referenceFrame);
183 	void					redFill					(tcu::Texture2DArray&							referenceFrame);
184 
185 	const TestParameters	m_parameters;
186 	const deUint32			m_verticesCount;
187 	vector<Vec4>			m_data;
188 	VkExtent3D				m_extent;
189 	const VkFormat			m_colorFormat;
190 	const Vec4				m_colorRed;
191 	const Vec4				m_colorGreen;
192 };
193 
iterate(void)194 tcu::TestStatus CrossStageTestInstance::iterate (void)
195 {
196 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
197 	const VkDevice							vkDevice				= m_context.getDevice();
198 	const VkPhysicalDeviceFeatures&			features				= m_context.getDeviceFeatures();
199 	const bool								supportsGeometry		= features.geometryShader == VK_TRUE;
200 	const bool								supportsTessellation	= features.tessellationShader == VK_TRUE;
201 	const VkDeviceSize						vertexDataSize			= static_cast<VkDeviceSize>(deAlignSize(static_cast<size_t>( m_data.size() * sizeof(Vec4)),
202 																		static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize)));
203 	const VkBufferCreateInfo				bufferInfo				= makeBufferCreateInfo(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
204 	Move<VkBuffer>							vertexBuffer			= createBuffer(vk, vkDevice, &bufferInfo);
205 	MovePtr<Allocation>						allocationVertex		= m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer),  MemoryRequirement::HostVisible);
206 
207 	const VkImageSubresourceRange			imageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
208 	const VkImageCreateInfo					colorAttachmentInfo		= makeImageCreateInfo(VK_IMAGE_TYPE_2D, m_extent, m_colorFormat,
209 																		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, m_context.getUniversalQueueFamilyIndex());
210 
211 	Move<VkImage>							colorAttachmentImage	= createImage(vk, vkDevice, &colorAttachmentInfo);
212 	MovePtr<Allocation>						allocationAttachment	= m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *colorAttachmentImage), MemoryRequirement::Any);
213 	VK_CHECK(vk.bindImageMemory(vkDevice, *colorAttachmentImage, allocationAttachment->getMemory(), allocationAttachment->getOffset()));
214 	Move<VkImageView>						colorAttachmentView		= makeImageView(vk, vkDevice, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, imageSubresourceRange);
215 
216 	MovePtr<tcu::Texture2DArray>			referenceImage1			= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_colorFormat), m_extent.width, m_extent.height, m_extent.depth));
217 	MovePtr<tcu::Texture2DArray>			referenceImage2			= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_colorFormat), m_extent.width, m_extent.height, m_extent.depth));
218 
219 	// Init host buffer data
220 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, allocationVertex->getMemory(), allocationVertex->getOffset()));
221 	deMemcpy(allocationVertex->getHostPtr(), m_data.data(), de::dataSize(m_data));
222 	flushAlloc(vk, vkDevice, *allocationVertex);
223 
224 	Move<VkRenderPass>						renderPass				= makeRenderPass (vk, vkDevice, m_colorFormat);
225 	Move<VkFramebuffer>						frameBuffer				= makeFramebuffer (vk, vkDevice, *renderPass, *colorAttachmentView, m_extent.width, m_extent.height);
226 	Move<VkPipelineLayout>					pipelineLayout			= makePipelineLayout (vk, vkDevice);
227 	Move<VkCommandPool>						cmdPool;
228 	Move<VkCommandBuffer>					cmdBuffer;
229 
230 	// cmdPool
231 	{
232 		const VkCommandPoolCreateInfo cmdPoolParams =
233 		{
234 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType		sType;
235 			DE_NULL,											// const void*			pNext;
236 			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCmdPoolCreateFlags	flags;
237 			m_context.getUniversalQueueFamilyIndex(),			// deUint32				queueFamilyIndex;
238 		};
239 		cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
240 	}
241 
242 	// cmdBuffer
243 	{
244 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
245 		{
246 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
247 			DE_NULL,											// const void*			pNext;
248 			*cmdPool,											// VkCommandPool		commandPool;
249 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
250 			1u,													// deUint32				bufferCount;
251 		};
252 		cmdBuffer	= allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
253 	}
254 
255 	if (!supportsTessellation)
256 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Tessellation not supported" << tcu::TestLog::EndMessage;
257 
258 	if (!supportsGeometry)
259 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Geometry not supported" << tcu::TestLog::EndMessage;
260 
261 	vector<deUint32> shadersStagesFlagsBits;
262 	shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
263 
264 	if (supportsTessellation)
265 		shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
266 
267 	if (supportsGeometry)
268 		shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
269 
270 	if (supportsTessellation && supportsGeometry)
271 		shadersStagesFlagsBits.push_back(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
272 
273 	referenceImage1->allocLevel(0);
274 	referenceImage2->allocLevel(0);
275 	switch(m_parameters.qualifier)
276 	{
277 	case TEST_TYPE_FLAT:
278 		interpolationFill(*referenceImage1);
279 		redFill(*referenceImage2);
280 		break;
281 	case TEST_TYPE_NOPERSPECTIVE:
282 		perspectiveFill(*referenceImage1);
283 		interpolationFill(*referenceImage2);
284 		break;
285 	case TEST_TYPE_RELAXEDPRECISION:
286 		interpolationFill(*referenceImage1);
287 		interpolationFill(*referenceImage2);
288 		break;
289 	default:
290 		DE_ASSERT(0);
291 	}
292 
293 	for (deUint32 optionNdx = 0; optionNdx < m_parameters.testOptions.size(); optionNdx++)
294 	for (size_t stagesNdx = 0ull; stagesNdx < shadersStagesFlagsBits.size(); stagesNdx++)
295 	{
296 		map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
297 		string										imageDescription;
298 		const VkClearValue							renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
299 		makeShaderModule(shaderModule, (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx], optionNdx);
300 
301 		Move<VkPipeline>			graphicsPipeline		= makeGraphicsPipeline (*renderPass, *pipelineLayout, (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx], shaderModule, ((VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx] & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
302 		const VkDeviceSize			vertexBufferOffset		= 0u;
303 
304 		beginCommandBuffer(vk, *cmdBuffer);
305 
306 		imageBarrier(vk, *cmdBuffer, *colorAttachmentImage, imageSubresourceRange,
307 			VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
308 			0u, VK_ACCESS_TRANSFER_WRITE_BIT,
309 			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
310 
311 		vk.cmdClearColorImage(*cmdBuffer, *colorAttachmentImage,  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &imageSubresourceRange);
312 
313 		imageBarrier(vk, *cmdBuffer, *colorAttachmentImage, imageSubresourceRange,
314 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
315 			VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
316 			VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
317 
318 		beginRenderPass(vk, *cmdBuffer, *renderPass, *frameBuffer, makeRect2D(0, 0, m_extent.width, m_extent.height), tcu::Vec4(0.0f));
319 
320 		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &(*vertexBuffer), &vertexBufferOffset);
321 
322 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
323 
324 		vk.cmdDraw(*cmdBuffer, m_verticesCount, 1u, 0u, 0u);
325 
326 		endRenderPass(vk, *cmdBuffer);
327 
328 		endCommandBuffer(vk, *cmdBuffer);
329 
330 		submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), *cmdBuffer);
331 		m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
332 
333 		{
334 			const string geometry		= (VK_SHADER_STAGE_GEOMETRY_BIT & (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx]) ? "Geometry->" : "";
335 			const string tessellation	= ( VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT & (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx]) ? "Tessellation->" : "";
336 			imageDescription = "Pipeline: Vertex->" + tessellation +  geometry + "Fragment | ";
337 		}
338 
339 		if (DECORATION_IN_VERTEX == m_parameters.testOptions[optionNdx])
340 			imageDescription+= "decoration in vertex | ";
341 		if (DECORATION_IN_FRAGMENT == m_parameters.testOptions[optionNdx])
342 			imageDescription+= "decoration in fragment | ";
343 		if (DECORATION_IN_ALL_SHADERS == m_parameters.testOptions[optionNdx])
344 			imageDescription+= "decoration in all shaders | ";
345 
346 		bool resultComparison = false;
347 		if (TEST_TYPE_RELAXEDPRECISION == m_parameters.qualifier)
348 		{
349 			resultComparison = checkImage(*colorAttachmentImage, *cmdPool, *cmdBuffer, imageDescription+" Expected Pass", *referenceImage1);
350 		}
351 		else
352 		{
353 			if (DECORATION_IN_VERTEX == m_parameters.testOptions[optionNdx])
354 				resultComparison = checkImage(*colorAttachmentImage, *cmdPool, *cmdBuffer, imageDescription+" Expected Pass", *referenceImage1);
355 			else if ((VkShaderStageFlagBits)(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) == (VkShaderStageFlagBits)shadersStagesFlagsBits[stagesNdx])
356 				resultComparison = checkImage(*colorAttachmentImage, *cmdPool, *cmdBuffer, imageDescription+" Expected Pass", *referenceImage2);
357 			else
358 				resultComparison = !checkImage(*colorAttachmentImage, *cmdPool, *cmdBuffer, imageDescription+" Expected Fail", *referenceImage1);
359 		}
360 
361 #ifdef CTS_USES_VULKANSC
362 		if (m_context.getTestContext().getCommandLine().isSubProcess())
363 #endif // CTS_USES_VULKANSC
364 		{
365 			if (!resultComparison)
366 				return tcu::TestStatus::fail("Fail");
367 		}
368 	}
369 	return tcu::TestStatus::pass("Pass");
370 }
371 
createVertexData(void)372 void CrossStageTestInstance::createVertexData (void)
373 {
374 	int ndx = -1;
375 	if (TEST_TYPE_NOPERSPECTIVE == m_parameters.qualifier)
376 		m_data[++ndx] = Vec4(-2.0f,-2.0f, 1.0f, 2.0f);	//position
377 	else
378 		m_data[++ndx] = Vec4(-1.0f,-1.0f, 1.0f, 1.0f);	//position
379 	m_data[++ndx] = m_colorRed;
380 
381 	if (TEST_TYPE_NOPERSPECTIVE == m_parameters.qualifier)
382 		m_data[++ndx] = Vec4(-2.0f, 2.0f, 1.0f, 2.0f);	//position
383 	else
384 		m_data[++ndx] = Vec4(-1.0f, 1.0f, 1.0f, 1.0f);	//position
385 	m_data[++ndx] = m_colorRed;
386 
387 	m_data[++ndx] = Vec4( 1.0f,-1.0f, 1.0f, 1.0f);	//position
388 	m_data[++ndx] = m_colorGreen;
389 
390 	m_data[++ndx] = Vec4( 1.0f, 1.0f, 1.0f, 1.0f);	//position
391 	m_data[++ndx] = m_colorGreen;
392 }
393 
makeShaderModule(map<VkShaderStageFlagBits,ShaderModuleSP> & shaderModule,const VkShaderStageFlagBits stageFlag,const int optionNdx)394 void CrossStageTestInstance::makeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModule,
395 											   const VkShaderStageFlagBits					stageFlag,
396 											   const int									optionNdx)
397 {
398 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
399 	const VkDevice			vkDevice	= m_context.getDevice();
400 
401 	std::ostringstream vertex;
402 	vertex<<"vertex"<<optionNdx;
403 	std::ostringstream fragment;
404 	fragment<<"fragment"<<optionNdx;
405 
406 	if (stageFlag & VK_SHADER_STAGE_VERTEX_BIT)
407 		shaderModule[VK_SHADER_STAGE_VERTEX_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(vertex.str()), 0))));
408 
409 	if (stageFlag & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
410 		shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
411 
412 	if (stageFlag & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
413 		shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
414 
415 	if (stageFlag & VK_SHADER_STAGE_GEOMETRY_BIT)
416 		shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geometry"), 0))));
417 
418 	if (stageFlag & VK_SHADER_STAGE_FRAGMENT_BIT)
419 		shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT] = (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get(fragment.str()), 0))));
420 }
421 
makeGraphicsPipeline(const VkRenderPass renderPass,const VkPipelineLayout pipelineLayout,const VkShaderStageFlagBits shaderFlags,map<VkShaderStageFlagBits,ShaderModuleSP> & shaderModules,const VkPrimitiveTopology primitiveTopology)422 Move<VkPipeline> CrossStageTestInstance::makeGraphicsPipeline (const VkRenderPass							renderPass,
423 															   const VkPipelineLayout						pipelineLayout,
424 															   const VkShaderStageFlagBits					shaderFlags,
425 															   map<VkShaderStageFlagBits, ShaderModuleSP>&	shaderModules,
426 															   const VkPrimitiveTopology					primitiveTopology)
427 {
428 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
429 	const VkDevice			vkDevice	= m_context.getDevice();
430 
431 	const VkVertexInputBindingDescription			vertexInputBindingDescription		=
432 	{
433 		0u,										// binding;
434 		static_cast<deUint32>(2u*sizeof(Vec4)),	// stride;
435 		VK_VERTEX_INPUT_RATE_VERTEX				// inputRate
436 	};
437 
438 	const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[]	=
439 	{
440 		{
441 			0u,
442 			0u,
443 			VK_FORMAT_R32G32B32A32_SFLOAT,
444 			0u
445 		},	// VertexElementData::position
446 		{
447 			1u,
448 			0u,
449 			VK_FORMAT_R32G32B32A32_SFLOAT,
450 			static_cast<deUint32>(sizeof(tcu::Vec4))
451 		},	// VertexElementData::color
452 	};
453 
454 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
455 	{																	// sType;
456 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// pNext;
457 		NULL,															// flags;
458 		0u,																// vertexBindingDescriptionCount;
459 		1u,																// pVertexBindingDescriptions;
460 		&vertexInputBindingDescription,									// vertexAttributeDescriptionCount;
461 		2u,																// pVertexAttributeDescriptions;
462 		vertexInputAttributeDescriptions
463 	};
464 
465 	const std::vector<VkViewport>					viewports							(1, makeViewport(m_extent));
466 	const std::vector<VkRect2D>						scissors							(1, makeRect2D(m_extent));
467 
468 	VkPipelineDepthStencilStateCreateInfo			depthStencilStateParams				=
469 	{
470 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
471 		DE_NULL,													// const void*								pNext;
472 		0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
473 		VK_TRUE,													// VkBool32									depthTestEnable;
474 		VK_TRUE,													// VkBool32									depthWriteEnable;
475 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp;
476 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
477 		VK_FALSE,													// VkBool32									stencilTestEnable;
478 		// VkStencilOpState front;
479 		{
480 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
481 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
482 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
483 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
484 			0u,						// deUint32		compareMask;
485 			0u,						// deUint32		writeMask;
486 			0u,						// deUint32		reference;
487 		},
488 		// VkStencilOpState back;
489 		{
490 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
491 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
492 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
493 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
494 			0u,						// deUint32		compareMask;
495 			0u,						// deUint32		writeMask;
496 			0u,						// deUint32		reference;
497 		},
498 		0.0f,	// float	minDepthBounds;
499 		1.0f,	// float	maxDepthBounds;
500 	};
501 
502 	const VkShaderModule	vertShader			= shaderFlags & VK_SHADER_STAGE_VERTEX_BIT ? **shaderModules[VK_SHADER_STAGE_VERTEX_BIT] : DE_NULL;
503 	const VkShaderModule	tessControlShader	= shaderFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? **shaderModules[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] : DE_NULL;
504 	const VkShaderModule	tessEvalShader		= shaderFlags & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ? **shaderModules[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] : DE_NULL;
505 	const VkShaderModule	geomShader			= shaderFlags & VK_SHADER_STAGE_GEOMETRY_BIT ? **shaderModules[VK_SHADER_STAGE_GEOMETRY_BIT] : DE_NULL;
506 	const VkShaderModule	fragShader			= shaderFlags & VK_SHADER_STAGE_FRAGMENT_BIT ? **shaderModules[VK_SHADER_STAGE_FRAGMENT_BIT] : DE_NULL;
507 
508 	return vk::makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
509 									vkDevice,					// const VkDevice                                device
510 									pipelineLayout,				// const VkPipelineLayout                        pipelineLayout
511 									vertShader,					// const VkShaderModule                          vertexShaderModule
512 									tessControlShader,			// const VkShaderModule                          tessellationControlShaderModule
513 									tessEvalShader,				// const VkShaderModule                          tessellationEvalShaderModule
514 									geomShader,					// const VkShaderModule                          geometryShaderModule
515 									fragShader,					// const VkShaderModule                          fragmentShaderModule
516 									renderPass,					// const VkRenderPass                            renderPass
517 									viewports,					// const std::vector<VkViewport>&                viewports
518 									scissors,					// const std::vector<VkRect2D>&                  scissors
519 									primitiveTopology,			// const VkPrimitiveTopology                     topology
520 									0u,							// const deUint32                                subpass
521 									4u,							// const deUint32                                patchControlPoints
522 									&vertexInputStateParams,	// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
523 									DE_NULL,					// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
524 									DE_NULL,					// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
525 									&depthStencilStateParams);	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
526 }
527 
checkImage(VkImage image,VkCommandPool cmdPool,VkCommandBuffer cmdBuffer,const string & description,const tcu::Texture2DArray & referenceFrame)528 bool CrossStageTestInstance::checkImage (VkImage image, VkCommandPool cmdPool, VkCommandBuffer cmdBuffer, const string& description, const tcu::Texture2DArray& referenceFrame)
529 {
530 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
531 	const VkDevice				vkDevice		= m_context.getDevice();
532 	const int					pixelSize		= referenceFrame.getFormat().getPixelSize();
533 	Move<VkBuffer>				buffer;
534 	MovePtr<Allocation>			bufferAlloc;
535 	vector<deUint8>				pixelAccessData	(m_extent.width * m_extent.height * m_extent.depth * pixelSize);
536 	tcu::PixelBufferAccess		dst				(referenceFrame.getFormat(), m_extent.width, m_extent.height, m_extent.depth, pixelAccessData.data());
537 	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * pixelSize;
538 
539 	// Create destination buffer
540 	{
541 		const VkBufferCreateInfo bufferParams =
542 		{
543 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
544 			DE_NULL,									// const void*			pNext;
545 			0u,											// VkBufferCreateFlags	flags;
546 			pixelDataSize,								// VkDeviceSize			size;
547 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
548 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
549 			0u,											// deUint32				queueFamilyIndexCount;
550 			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
551 		};
552 
553 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
554 		bufferAlloc	= m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
555 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
556 
557 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
558 		flushAlloc(vk, vkDevice, *bufferAlloc);
559 	}
560 
561 	beginCommandBuffer (vk, cmdBuffer);
562 	copyImageToBuffer(vk, cmdBuffer, image, *buffer, tcu::IVec2(m_extent.width, m_extent.height), 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, m_extent.depth);
563 	endCommandBuffer(vk, cmdBuffer);
564 	submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer);
565 	m_context.resetCommandPoolForVKSC(vkDevice, cmdPool);
566 
567 	// Read buffer data
568 	invalidateAlloc(vk, vkDevice, *bufferAlloc);
569 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
570 
571 	if (tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", description.c_str(), referenceFrame.getLevel(0), dst, tcu::Vec4(0.05f), tcu::COMPARE_LOG_EVERYTHING))
572 		return true;
573 	return false;
574 }
575 
interpolationFill(tcu::Texture2DArray & referenceFrame)576 void CrossStageTestInstance::interpolationFill (tcu::Texture2DArray& referenceFrame)
577 {
578 	for (deUint32 x = 0u; x < m_extent.width; ++x)
579 	{
580 		float u = static_cast<float>(x)/static_cast<float>(m_extent.width - 1);
581 		const Vec4 resultColor (m_colorRed.x() * (1.0f - u) + m_colorGreen.x() * u,
582 								m_colorRed.y() * (1.0f - u) + m_colorGreen.y() * u,
583 								m_colorRed.z() * (1.0f - u) + m_colorGreen.z() * u,
584 								m_colorRed.w() * (1.0f - u) + m_colorGreen.w() * u);
585 
586 		referenceFrame.getLevel(0).setPixel(resultColor,x,0);
587 	}
588 
589 	for (deUint32 y = 0u; y < m_extent.height; ++y)
590 	{
591 		deMemcpy (referenceFrame.getLevel(0).getPixelPtr(0,y), referenceFrame.getLevel(0).getPixelPtr(0,0), m_extent.width * m_extent.depth* referenceFrame.getFormat().getPixelSize());
592 	}
593 }
594 
perspectiveFill(tcu::Texture2DArray & referenceFrame)595 void CrossStageTestInstance::perspectiveFill (tcu::Texture2DArray& referenceFrame)
596 {
597 	float dynamics = 1.732f;
598 	float dynamicChange = 0.732f / static_cast<float>(m_extent.width);
599 	for (deUint32 x = 0u; x < m_extent.width; ++x)
600 	{
601 		float u = static_cast<float>(x)/static_cast<float>(m_extent.width - 1);
602 		const Vec4 resultColor (m_colorRed.x() * (1.0f - dynamics * u) + m_colorGreen.x() * u* dynamics,
603 								m_colorRed.y() * (1.0f - dynamics * u) + m_colorGreen.y() * u* dynamics,
604 								m_colorRed.z() * (1.0f - dynamics * u) + m_colorGreen.z() * u* dynamics,
605 								m_colorRed.w() * (1.0f - dynamics * u) + m_colorGreen.w() * u* dynamics);
606 		dynamics -= dynamicChange;
607 		if (dynamics < 1.0f)
608 			dynamics = 1.0f;
609 
610 		referenceFrame.getLevel(0).setPixel(resultColor,x,0);
611 	}
612 
613 	for (deUint32 y = 0u; y < m_extent.height; ++y)
614 	{
615 		deMemcpy (referenceFrame.getLevel(0).getPixelPtr(0,y), referenceFrame.getLevel(0).getPixelPtr(0,0), m_extent.width * m_extent.depth* referenceFrame.getFormat().getPixelSize());
616 	}
617 }
618 
redFill(tcu::Texture2DArray & referenceFrame)619 void CrossStageTestInstance::redFill (tcu::Texture2DArray& referenceFrame)
620 {
621 	for (deUint32 x = 0u; x < m_extent.width; ++x)
622 		referenceFrame.getLevel(0).setPixel(m_colorRed,x,0);
623 
624 	for (deUint32 y = 0u; y < m_extent.height; ++y)
625 		deMemcpy (referenceFrame.getLevel(0).getPixelPtr(0,y), referenceFrame.getLevel(0).getPixelPtr(0,0), m_extent.width * m_extent.depth* referenceFrame.getFormat().getPixelSize());
626 }
627 
628 struct Decorations
629 {
Decorationsvkt::SpirVAssembly::__anon21c269370111::Decorations630 	Decorations()
631 	{}
Decorationsvkt::SpirVAssembly::__anon21c269370111::Decorations632 	Decorations(const string& f, const string& v, const string& o)
633 		: fragment	(f)
634 		, vertex	(v)
635 		, others	(o)
636 	{}
637 	string fragment;
638 	string vertex;
639 	string others;
640 };
641 
642 class CrossStageBasicTestsCase : public vkt::TestCase
643 {
644 public:
CrossStageBasicTestsCase(tcu::TestContext & context,const char * name,const char * description,const TestParameters & parameters)645 	CrossStageBasicTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
646 		: TestCase			(context, name, description)
647 		, m_parameters		(parameters)
648 	{
649 	}
650 private:
651 	vkt::TestInstance*	createInstance		(vkt::Context& context) const;
652 	void				initPrograms		(SourceCollections& programCollection) const;
653 
654 	const TestParameters	m_parameters;
655 
656 };
657 
createInstance(vkt::Context & context) const658 vkt::TestInstance* CrossStageBasicTestsCase::createInstance (vkt::Context& context) const
659 {
660 	return new CrossStageTestInstance(context, m_parameters);
661 }
662 
initPrograms(SourceCollections & programCollection) const663 void CrossStageBasicTestsCase::initPrograms (SourceCollections& programCollection) const
664 {
665 	vector<Decorations> decorations;
666 	string epsilon = "3e-7";
667 	switch(m_parameters.qualifier)
668 	{
669 	case TEST_TYPE_FLAT:
670 		decorations.push_back(Decorations("",
671 								//Vertex
672 								"OpDecorate %color_out Flat\n"
673 								"OpDecorate %r_float_out Flat\n"
674 								"OpDecorate %rg_float_out Flat\n"
675 								"OpDecorate %rgb_float_out Flat\n"
676 								"OpDecorate %rgba_float_out Flat\n",
677 								""));
678 		decorations.push_back(Decorations(//Fragment
679 								"OpDecorate %color_in Flat\n"
680 								"OpDecorate %r_float_in Flat\n"
681 								"OpDecorate %rg_float_in Flat\n"
682 								"OpDecorate %rgb_float_in Flat\n"
683 								"OpDecorate %rgba_float_in Flat\n",
684 								"",
685 								""));
686 
687 		decorations.push_back(Decorations(//Fragment
688 								"OpDecorate %color_in Flat\n"
689 								"OpDecorate %r_float_in Flat\n"
690 								"OpDecorate %rg_float_in Flat\n"
691 								"OpDecorate %rgb_float_in Flat\n"
692 								"OpDecorate %rgba_float_in Flat\n",
693 								//Vertex
694 								"OpDecorate %color_out Flat\n"
695 								"OpDecorate %r_float_out Flat\n"
696 								"OpDecorate %rg_float_out Flat\n"
697 								"OpDecorate %rgb_float_out Flat\n"
698 								"OpDecorate %rgba_float_out Flat\n",
699 								""));
700 		epsilon = "0.0";
701 		break;
702 	case TEST_TYPE_NOPERSPECTIVE:
703 		decorations.push_back(Decorations("",
704 								//Vertex
705 								"OpDecorate %color_out NoPerspective\n"
706 								"OpDecorate %r_float_out NoPerspective\n"
707 								"OpDecorate %rg_float_out NoPerspective\n"
708 								"OpDecorate %rgb_float_out NoPerspective\n"
709 								"OpDecorate %rgba_float_out NoPerspective\n",
710 								""));
711 
712 		decorations.push_back(Decorations(//Fragment
713 								"OpDecorate %color_in NoPerspective\n"
714 								"OpDecorate %r_float_in NoPerspective\n"
715 								"OpDecorate %rg_float_in NoPerspective\n"
716 								"OpDecorate %rgb_float_in NoPerspective\n"
717 								"OpDecorate %rgba_float_in NoPerspective\n",
718 								"",
719 								""));
720 
721 		decorations.push_back(Decorations(//Fragment
722 								"OpDecorate %color_in NoPerspective\n"
723 								"OpDecorate %r_float_in NoPerspective\n"
724 								"OpDecorate %rg_float_in NoPerspective\n"
725 								"OpDecorate %rgb_float_in NoPerspective\n"
726 								"OpDecorate %rgba_float_in NoPerspective\n",
727 								//Vertex
728 								"OpDecorate %color_out NoPerspective\n"
729 								"OpDecorate %r_float_out NoPerspective\n"
730 								"OpDecorate %rg_float_out NoPerspective\n"
731 								"OpDecorate %rgb_float_out NoPerspective\n"
732 								"OpDecorate %rgba_float_out NoPerspective\n",
733 								//Others
734 								""));
735 		break;
736 	case TEST_TYPE_RELAXEDPRECISION:
737 		decorations.push_back(Decorations(//Fragment
738 								"OpDecorate %color_out RelaxedPrecision\n"
739 								"OpDecorate %color_in RelaxedPrecision\n"
740 								"OpDecorate %r_float_in RelaxedPrecision\n"
741 								"OpDecorate %rg_float_in RelaxedPrecision\n"
742 								"OpDecorate %rgb_float_in RelaxedPrecision\n"
743 								"OpDecorate %rgba_float_in RelaxedPrecision\n",
744 								//Vertex
745 								"OpDecorate %color_out RelaxedPrecision\n"
746 								"OpDecorate %color_in RelaxedPrecision\n"
747 								"OpDecorate %r_float_out RelaxedPrecision\n"
748 								"OpDecorate %rg_float_out RelaxedPrecision\n"
749 								"OpDecorate %rgb_float_out RelaxedPrecision\n"
750 								"OpDecorate %rgba_float_out RelaxedPrecision\n",
751 								//Others
752 								"OpDecorate %color_out RelaxedPrecision\n"
753 								"OpDecorate %color_in RelaxedPrecision\n"
754 								"OpDecorate %r_float_out RelaxedPrecision\n"
755 								"OpDecorate %rg_float_out RelaxedPrecision\n"
756 								"OpDecorate %rgb_float_out RelaxedPrecision\n"
757 								"OpDecorate %rgba_float_out RelaxedPrecision\n"
758 								"OpDecorate %r_float_in RelaxedPrecision\n"
759 								"OpDecorate %rg_float_in RelaxedPrecision\n"
760 								"OpDecorate %rgb_float_in RelaxedPrecision\n"
761 								"OpDecorate %rgba_float_in RelaxedPrecision\n"));
762 		epsilon = "2e-3";
763 		break;
764 	default:
765 		DE_ASSERT(0);
766 	}
767 
768 	//Spir-v spec: decoration flat can be used only in Shader (fragment or vertex)
769 	for (deUint32 ndx = 0; ndx < decorations.size(); ++ndx)
770 	{
771 
772 		/*#version 450
773 		layout(location = 0) in highp vec4 in_position;
774 		layout(location = 1) in vec4 in_color;
775 		layout(location = 0) out vec4 out_color;
776 		layout(location = 1) out float		r_float_out;
777 		layout(location = 2) out vec2		rg_float_out;
778 		layout(location = 3) out vec3		rgb_float_out;
779 		layout(location = 4) out vec4		rgba_float_out;
780 		void main (void)
781 		{
782 			gl_Position = in_position;
783 			out_color = in_color;
784 			r_float_out = in_color.r;
785 			rg_float_out = vec2(in_color.r, in_color.g);
786 			rgb_float_out = vec3(in_color.r, in_color.g,in_color.b);
787 			rgba_float_out = vec4(in_color.r, in_color.g, in_color.b, in_color.a);
788 		}
789 		*/
790 		const string vertexShaderSource =
791 		"; SPIR-V\n"
792 		"; Version: 1.3\n"
793 		"; Generator: Khronos Glslang Reference Front End; 2\n"
794 		"; Bound: 60\n"
795 		"; Schema: 0\n"
796 		"OpCapability Shader\n"
797 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
798 		"OpMemoryModel Logical GLSL450\n"
799 		"OpEntryPoint Vertex %4 \"main\" %13 %17 %color_out %color_in %r_float_out %rg_float_out %rgb_float_out %rgba_float_out\n"
800 		"OpMemberDecorate %11 0 BuiltIn Position\n"
801 		"OpMemberDecorate %11 1 BuiltIn PointSize\n"
802 		"OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
803 		"OpMemberDecorate %11 3 BuiltIn CullDistance\n"
804 		"OpDecorate %11 Block\n"
805 		"OpDecorate %17 Location 0\n"
806 		"OpDecorate %color_out Location 0\n"
807 		"OpDecorate %color_in Location 1\n"
808 		"OpDecorate %r_float_out Location 1\n"
809 		"OpDecorate %rg_float_out Location 2\n"
810 		"OpDecorate %rgb_float_out Location 3\n"
811 		"OpDecorate %rgba_float_out Location 4\n"
812 		+decorations[ndx].vertex+
813 		"%2 = OpTypeVoid\n"
814 		"%3 = OpTypeFunction %2\n"
815 		"%6 = OpTypeFloat 32\n"
816 		"%7 = OpTypeVector %6 4\n"
817 		"%8 = OpTypeInt 32 0\n"
818 		"%9 = OpConstant %8 1\n"
819 		"%10 = OpTypeArray %6 %9\n"
820 		"%11 = OpTypeStruct %7 %6 %10 %10\n"
821 		"%12 = OpTypePointer Output %11\n"
822 		"%13 = OpVariable %12 Output\n"
823 		"%14 = OpTypeInt 32 1\n"
824 		"%15 = OpConstant %14 0\n"
825 		"%16 = OpTypePointer Input %7\n"
826 		"%17 = OpVariable %16 Input\n"
827 		"%19 = OpTypePointer Output %7\n"
828 		"%color_out = OpVariable %19 Output\n"
829 		"%color_in = OpVariable %16 Input\n"
830 		"%24 = OpTypePointer Output %6\n"
831 		"%r_float_out = OpVariable %24 Output\n"
832 		"%26 = OpConstant %8 0\n"
833 		"%27 = OpTypePointer Input %6\n"
834 		"%30 = OpTypeVector %6 2\n"
835 		"%31 = OpTypePointer Output %30\n"
836 		"%rg_float_out = OpVariable %31 Output\n"
837 		"%38 = OpTypeVector %6 3\n"
838 		"%39 = OpTypePointer Output %38\n"
839 		"%rgb_float_out = OpVariable %39 Output\n"
840 		"%45 = OpConstant %8 2\n"
841 		"%rgba_float_out = OpVariable %19 Output\n"
842 		"%56 = OpConstant %8 3\n"
843 		"%4 = OpFunction %2 None %3\n"
844 		"%5 = OpLabel\n"
845 		"%18 = OpLoad %7 %17\n"
846 		"%20 = OpAccessChain %19 %13 %15\n"
847 		"OpStore %20 %18\n"
848 		"%23 = OpLoad %7 %color_in\n"
849 		"OpStore %color_out %23\n"
850 		"%28 = OpAccessChain %27 %color_in %26\n"
851 		"%29 = OpLoad %6 %28\n"
852 		"OpStore %r_float_out %29\n"
853 		"%33 = OpAccessChain %27 %color_in %26\n"
854 		"%34 = OpLoad %6 %33\n"
855 		"%35 = OpAccessChain %27 %color_in %9\n"
856 		"%36 = OpLoad %6 %35\n"
857 		"%37 = OpCompositeConstruct %30 %34 %36\n"
858 		"OpStore %rg_float_out %37\n"
859 		"%41 = OpAccessChain %27 %color_in %26\n"
860 		"%42 = OpLoad %6 %41\n"
861 		"%43 = OpAccessChain %27 %color_in %9\n"
862 		"%44 = OpLoad %6 %43\n"
863 		"%46 = OpAccessChain %27 %color_in %45\n"
864 		"%47 = OpLoad %6 %46\n"
865 		"%48 = OpCompositeConstruct %38 %42 %44 %47\n"
866 		"OpStore %rgb_float_out %48\n"
867 		"%50 = OpAccessChain %27 %color_in %26\n"
868 		"%51 = OpLoad %6 %50\n"
869 		"%52 = OpAccessChain %27 %color_in %9\n"
870 		"%53 = OpLoad %6 %52\n"
871 		"%54 = OpAccessChain %27 %color_in %45\n"
872 		"%55 = OpLoad %6 %54\n"
873 		"%57 = OpAccessChain %27 %color_in %56\n"
874 		"%58 = OpLoad %6 %57\n"
875 		"%59 = OpCompositeConstruct %7 %51 %53 %55 %58\n"
876 		"OpStore %rgba_float_out %59\n"
877 		"OpReturn\n"
878 		"OpFunctionEnd\n";
879 
880 		/* #version 450
881 		layout(location = 0) out vec4  color_out;
882 		layout(location = 0) in vec4   color_in;
883 		layout(location = 1) in float  r_float_in;
884 		layout(location = 2) in vec2   rg_float_in;
885 		layout(location = 3) in vec3   rgb_float_in;
886 		layout(location = 4) in vec4   rgba_float_in;
887 		void main()
888 		{
889 			float epsilon = 3e-7; // or 0.0 for flat, or 2e-3 for RelaxedPrecision (mediump)
890 			color_out = color_in;
891 			float epsilon_float = max(abs(r_float_in), abs(color_in.r)) * epsilon;
892 			if(abs(r_float_in - color_in.r) > epsilon_float)
893 				color_out.r = 1.0f;
894 			vec2 epsilon_vec2 = max(abs(rg_float_in), abs(color_in.rg)) * epsilon;
895 			if(any(greaterThan(abs(rg_float_in - color_in.rg), epsilon_vec2)))
896 				color_out.rg = vec2(1.0f);
897 			vec3 epsilon_vec3 = max(abs(rgb_float_in), abs(color_in.rgb)) * epsilon;
898 			if(any(greaterThan(abs(rgb_float_in - color_in.rgb), epsilon_vec3)))
899 				color_out.rgb = vec3(1.0f);
900 			vec4 epsilon_vec4 = max(abs(rgba_float_in), abs(color_in.rgba)) * epsilon;
901 			if(any(greaterThan(abs(rgba_float_in - color_in.rgba), epsilon_vec4)))
902 				color_out.rgba = vec4(1.0f);
903 		}
904 		*/
905 
906 		const string fragmentShaderSource =
907 		"; SPIR-V\n"
908 		"; Version: 1.3\n"
909 		"; Generator: Khronos Glslang Reference Front End; 2\n"
910 		"; Bound: 64\n"
911 		"; Schema: 0\n"
912 		"OpCapability Shader\n"
913 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
914 		"OpMemoryModel Logical GLSL450\n"
915 		"OpEntryPoint Fragment %4 \"main\" %color_out %color_in %r_float_in %rg_float_in %rgb_float_in %rgba_float_in\n"
916 		"OpExecutionMode %4 OriginUpperLeft\n"
917 		"OpDecorate %color_out Location 0\n"
918 		"OpDecorate %color_in Location 0\n"
919 		"OpDecorate %r_float_in Location 1\n"
920 		"OpDecorate %rg_float_in Location 2\n"
921 		"OpDecorate %rgb_float_in Location 3\n"
922 		"OpDecorate %rgba_float_in Location 4\n"
923 		+decorations[ndx].fragment+
924 		"%2 = OpTypeVoid\n"
925 		"%3 = OpTypeFunction %2\n"
926 		"%6 = OpTypeFloat 32\n"
927 		"%7 = OpTypeVector %6 4\n"
928 		"%8 = OpTypePointer Output %7\n"
929 		"%color_out = OpVariable %8 Output\n"
930 		"%10 = OpTypePointer Input %7\n"
931 		"%color_in = OpVariable %10 Input\n"
932 		"%13 = OpTypePointer Input %6\n"
933 		"%r_float_in = OpVariable %13 Input\n"
934 		"%16 = OpTypeInt 32 0\n"
935 		"%17 = OpConstant %16 0\n"
936 		"%20 = OpTypeBool\n"
937 		"%ep = OpConstant %6 " + epsilon + "\n"
938 		"%24 = OpConstant %6 1\n"
939 		"%25 = OpTypePointer Output %6\n"
940 		"%27 = OpTypeVector %6 2\n"
941 		"%28 = OpTypePointer Input %27\n"
942 		"%rg_float_in = OpVariable %28 Input\n"
943 		"%ep2 = OpConstantComposite %27 %ep %ep\n"
944 		"%33 = OpTypeVector %20 2\n"
945 		"%38 = OpConstantComposite %27 %24 %24\n"
946 		"%41 = OpTypeVector %6 3\n"
947 		"%42 = OpTypePointer Input %41\n"
948 		"%rgb_float_in = OpVariable %42 Input\n"
949 		"%ep3 = OpConstantComposite %41 %ep %ep %ep\n"
950 		"%47 = OpTypeVector %20 3\n"
951 		"%52 = OpConstantComposite %41 %24 %24 %24\n"
952 		"%rgba_float_in = OpVariable %10 Input\n"
953 		"%ep4 = OpConstantComposite %7 %ep %ep %ep %ep\n"
954 		"%58 = OpTypeVector %20 4\n"
955 		"%63 = OpConstantComposite %7 %24 %24 %24 %24\n"
956 		"%4 = OpFunction %2 None %3\n"
957 		"%5 = OpLabel\n"
958 		"%12 = OpLoad %7 %color_in\n"
959 		"OpStore %color_out %12\n"
960 		"%15 = OpLoad %6 %r_float_in\n"
961 		"%18 = OpAccessChain %13 %color_in %17\n"
962 		"%19 = OpLoad %6 %18\n"
963 		"%sub = OpFSub %6 %15 %19\n"
964 		"%abs = OpExtInst %6 %1 FAbs %sub\n"
965 		"%ep1abs0 = OpExtInst %6 %1 FAbs %15\n"
966 		"%ep1abs1 = OpExtInst %6 %1 FAbs %19\n"
967 		"%ep1gt = OpFOrdGreaterThan %20 %ep1abs0 %ep1abs1\n"
968 		"%ep1max = OpSelect %6 %ep1gt %ep1abs0 %ep1abs1\n"
969 		"%ep1rel = OpFMul %6 %ep1max %ep\n"
970 		"%cmp = OpFOrdGreaterThan %20 %abs %ep1rel\n"
971 		"OpSelectionMerge %23 None\n"
972 		"OpBranchConditional %cmp %22 %23\n"
973 		"%22 = OpLabel\n"
974 		"%26 = OpAccessChain %25 %color_out %17\n"
975 		"OpStore %26 %24\n"
976 		"OpBranch %23\n"
977 		"%23 = OpLabel\n"
978 		"%30 = OpLoad %27 %rg_float_in\n"
979 		"%31 = OpLoad %7 %color_in\n"
980 		"%32 = OpVectorShuffle %27 %31 %31 0 1\n"
981 		"%sub2 = OpFSub %27 %30 %32\n"
982 		"%abs2 = OpExtInst %27 %1 FAbs %sub2\n"
983 		"%ep2abs0 = OpExtInst %27 %1 FAbs %30\n"
984 		"%ep2abs1 = OpExtInst %27 %1 FAbs %32\n"
985 		"%ep2gt = OpFOrdGreaterThan %33 %ep2abs0 %ep2abs1\n"
986 		"%ep2max = OpSelect %27 %ep2gt %ep2abs0 %ep2abs1\n"
987 		"%ep2rel = OpFMul %27 %ep2max %ep2\n"
988 		"%cmp2 = OpFOrdGreaterThan %33 %abs2 %ep2rel\n"
989 		"%35 = OpAny %20 %cmp2\n"
990 		"OpSelectionMerge %37 None\n"
991 		"OpBranchConditional %35 %36 %37\n"
992 		"%36 = OpLabel\n"
993 		"%39 = OpLoad %7 %color_out\n"
994 		"%40 = OpVectorShuffle %7 %39 %38 4 5 2 3\n"
995 		"OpStore %color_out %40\n"
996 		"OpBranch %37\n"
997 		"%37 = OpLabel\n"
998 		"%44 = OpLoad %41 %rgb_float_in\n"
999 		"%45 = OpLoad %7 %color_in\n"
1000 		"%46 = OpVectorShuffle %41 %45 %45 0 1 2\n"
1001 		"%sub3 = OpFSub %41 %44 %46\n"
1002 		"%abs3 = OpExtInst %41 %1 FAbs %sub3\n"
1003 		"%ep3abs0 = OpExtInst %41 %1 FAbs %44\n"
1004 		"%ep3abs1 = OpExtInst %41 %1 FAbs %46\n"
1005 		"%ep3gt = OpFOrdGreaterThan %47 %ep3abs0 %ep3abs1\n"
1006 		"%ep3max = OpSelect %41 %ep3gt %ep3abs0 %ep3abs1\n"
1007 		"%ep3rel = OpFMul %41 %ep3max %ep3\n"
1008 		"%cmp3 = OpFOrdGreaterThan %47 %abs3 %ep3rel\n"
1009 		"%49 = OpAny %20 %cmp3\n"
1010 		"OpSelectionMerge %51 None\n"
1011 		"OpBranchConditional %49 %50 %51\n"
1012 		"%50 = OpLabel\n"
1013 		"%53 = OpLoad %7 %color_out\n"
1014 		"%54 = OpVectorShuffle %7 %53 %52 4 5 6 3\n"
1015 		"OpStore %color_out %54\n"
1016 		"OpBranch %51\n"
1017 		"%51 = OpLabel\n"
1018 		"%56 = OpLoad %7 %rgba_float_in\n"
1019 		"%57 = OpLoad %7 %color_in\n"
1020 		"%sub4 = OpFSub %7 %56 %57\n"
1021 		"%abs4 = OpExtInst %7 %1 FAbs %sub4\n"
1022 		"%ep4abs0 = OpExtInst %7 %1 FAbs %56\n"
1023 		"%ep4abs1 = OpExtInst %7 %1 FAbs %57\n"
1024 		"%ep4gt = OpFOrdGreaterThan %58 %ep4abs0 %ep4abs1\n"
1025 		"%ep4max = OpSelect %7 %ep4gt %ep4abs0 %ep4abs1\n"
1026 		"%ep4rel = OpFMul %7 %ep4max %ep4\n"
1027 		"%cmp4 = OpFOrdGreaterThan %58 %abs4 %ep4rel\n"
1028 		"%60 = OpAny %20 %cmp4\n"
1029 		"OpSelectionMerge %62 None\n"
1030 		"OpBranchConditional %60 %61 %62\n"
1031 		"%61 = OpLabel\n"
1032 		"OpStore %color_out %63\n"
1033 		"OpBranch %62\n"
1034 		"%62 = OpLabel\n"
1035 		"OpReturn\n"
1036 		"OpFunctionEnd\n";
1037 
1038 		std::ostringstream vertex;
1039 		vertex << "vertex" << ndx;
1040 		std::ostringstream fragment;
1041 		fragment << "fragment" << ndx;
1042 
1043 		programCollection.spirvAsmSources.add(vertex.str()) << vertexShaderSource;
1044 		programCollection.spirvAsmSources.add(fragment.str()) << fragmentShaderSource;
1045 	}
1046 	{
1047 		/*#version 450
1048 		#extension GL_EXT_tessellation_shader : require
1049 		layout(vertices = 4) out;
1050 		layout(location = 0) in vec4		in_color[];
1051 		layout(location = 1) in float		r_float_in[];
1052 		layout(location = 2) in vec2		rg_float_in[];
1053 		layout(location = 3) in vec3		rgb_float_in[];
1054 		layout(location = 4) in vec4		rgba_float_in[];
1055 		layout(location = 0) out vec4		out_color[];
1056 		layout(location = 1) out float		r_float_out[];
1057 		layout(location = 2) out vec2		rg_float_out[];
1058 		layout(location = 3) out vec3		rgb_float_out[];
1059 		layout(location = 4) out vec4		rgba_float_out[];
1060 		void main (void)
1061 		{
1062 			if ( gl_InvocationID == 0 )
1063 			{
1064 				gl_TessLevelInner[0] = 4.0f;
1065 				gl_TessLevelInner[1] = 4.0f;
1066 				gl_TessLevelOuter[0] = 4.0f;
1067 				gl_TessLevelOuter[1] = 4.0f;
1068 				gl_TessLevelOuter[2] = 4.0f;
1069 				gl_TessLevelOuter[3] = 4.0f;
1070 			}
1071 			out_color[gl_InvocationID] = in_color[gl_InvocationID];
1072 			r_float_out[gl_InvocationID] = r_float_in[gl_InvocationID];
1073 			rg_float_out[gl_InvocationID] = rg_float_in[gl_InvocationID];
1074 			rgb_float_out[gl_InvocationID] = rgb_float_in[gl_InvocationID];
1075 			rgba_float_out[gl_InvocationID] = rgba_float_in[gl_InvocationID];
1076 			gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
1077 		}*/
1078 
1079 		const string tessellationControlSource =
1080 		"; SPIR-V\n"
1081 		"; Version: 1.3\n"
1082 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1083 		"; Bound: 111\n"
1084 		"; Schema: 0\n"
1085 		"OpCapability Tessellation\n"
1086 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1087 		"OpMemoryModel Logical GLSL450\n"
1088 		"OpEntryPoint TessellationControl %4 \"main\" %8 %20 %29 %color_out %color_in %r_float_out %r_float_in %rg_float_out %rg_float_in %rgb_float_out %rgb_float_in %rgba_float_out %rgba_float_in %101 %106\n"
1089 		"OpExecutionMode %4 OutputVertices 4\n"
1090 		"OpDecorate %8 BuiltIn InvocationId\n"
1091 		"OpDecorate %20 Patch\n"
1092 		"OpDecorate %20 BuiltIn TessLevelInner\n"
1093 		"OpDecorate %29 Patch\n"
1094 		"OpDecorate %29 BuiltIn TessLevelOuter\n"
1095 		"OpDecorate %color_out Location 0\n"
1096 		"OpDecorate %color_in Location 0\n"
1097 		"OpDecorate %r_float_out Location 1\n"
1098 		"OpDecorate %r_float_in Location 1\n"
1099 		"OpDecorate %rg_float_out Location 2\n"
1100 		"OpDecorate %rg_float_in Location 2\n"
1101 		"OpDecorate %rgb_float_out Location 3\n"
1102 		"OpDecorate %rgb_float_in Location 3\n"
1103 		"OpDecorate %rgba_float_out Location 4\n"
1104 		"OpDecorate %rgba_float_in Location 4\n"
1105 		+decorations[0].others+
1106 		"OpMemberDecorate %98 0 BuiltIn Position\n"
1107 		"OpMemberDecorate %98 1 BuiltIn PointSize\n"
1108 		"OpMemberDecorate %98 2 BuiltIn ClipDistance\n"
1109 		"OpMemberDecorate %98 3 BuiltIn CullDistance\n"
1110 		"OpDecorate %98 Block\n"
1111 		"OpMemberDecorate %103 0 BuiltIn Position\n"
1112 		"OpMemberDecorate %103 1 BuiltIn PointSize\n"
1113 		"OpMemberDecorate %103 2 BuiltIn ClipDistance\n"
1114 		"OpMemberDecorate %103 3 BuiltIn CullDistance\n"
1115 		"OpDecorate %103 Block\n"
1116 		"%2 = OpTypeVoid\n"
1117 		"%3 = OpTypeFunction %2\n"
1118 		"%6 = OpTypeInt 32 1\n"
1119 		"%7 = OpTypePointer Input %6\n"
1120 		"%8 = OpVariable %7 Input\n"
1121 		"%10 = OpConstant %6 0\n"
1122 		"%11 = OpTypeBool\n"
1123 		"%15 = OpTypeFloat 32\n"
1124 		"%16 = OpTypeInt 32 0\n"
1125 		"%17 = OpConstant %16 2\n"
1126 		"%18 = OpTypeArray %15 %17\n"
1127 		"%19 = OpTypePointer Output %18\n"
1128 		"%20 = OpVariable %19 Output\n"
1129 		"%21 = OpConstant %15 4\n"
1130 		"%22 = OpTypePointer Output %15\n"
1131 		"%24 = OpConstant %6 1\n"
1132 		"%26 = OpConstant %16 4\n"
1133 		"%27 = OpTypeArray %15 %26\n"
1134 		"%28 = OpTypePointer Output %27\n"
1135 		"%29 = OpVariable %28 Output\n"
1136 		"%32 = OpConstant %6 2\n"
1137 		"%34 = OpConstant %6 3\n"
1138 		"%36 = OpTypeVector %15 4\n"
1139 		"%37 = OpTypeArray %36 %26\n"
1140 		"%38 = OpTypePointer Output %37\n"
1141 		"%color_out = OpVariable %38 Output\n"
1142 		"%41 = OpConstant %16 32\n"
1143 		"%42 = OpTypeArray %36 %41\n"
1144 		"%43 = OpTypePointer Input %42\n"
1145 		"%color_in = OpVariable %43 Input\n"
1146 		"%46 = OpTypePointer Input %36\n"
1147 		"%49 = OpTypePointer Output %36\n"
1148 		"%r_float_out = OpVariable %28 Output\n"
1149 		"%53 = OpTypeArray %15 %41\n"
1150 		"%54 = OpTypePointer Input %53\n"
1151 		"%r_float_in = OpVariable %54 Input\n"
1152 		"%57 = OpTypePointer Input %15\n"
1153 		"%61 = OpTypeVector %15 2\n"
1154 		"%62 = OpTypeArray %61 %26\n"
1155 		"%63 = OpTypePointer Output %62\n"
1156 		"%rg_float_out = OpVariable %63 Output\n"
1157 		"%66 = OpTypeArray %61 %41\n"
1158 		"%67 = OpTypePointer Input %66\n"
1159 		"%rg_float_in = OpVariable %67 Input\n"
1160 		"%70 = OpTypePointer Input %61\n"
1161 		"%73 = OpTypePointer Output %61\n"
1162 		"%75 = OpTypeVector %15 3\n"
1163 		"%76 = OpTypeArray %75 %26\n"
1164 		"%77 = OpTypePointer Output %76\n"
1165 		"%rgb_float_out = OpVariable %77 Output\n"
1166 		"%80 = OpTypeArray %75 %41\n"
1167 		"%81 = OpTypePointer Input %80\n"
1168 		"%rgb_float_in = OpVariable %81 Input\n"
1169 		"%84 = OpTypePointer Input %75\n"
1170 		"%87 = OpTypePointer Output %75\n"
1171 		"%rgba_float_out = OpVariable %38 Output\n"
1172 		"%rgba_float_in = OpVariable %43 Input\n"
1173 		"%96 = OpConstant %16 1\n"
1174 		"%97 = OpTypeArray %15 %96\n"
1175 		"%98 = OpTypeStruct %36 %15 %97 %97\n"
1176 		"%99 = OpTypeArray %98 %26\n"
1177 		"%100 = OpTypePointer Output %99\n"
1178 		"%101 = OpVariable %100 Output\n"
1179 		"%103 = OpTypeStruct %36 %15 %97 %97\n"
1180 		"%104 = OpTypeArray %103 %41\n"
1181 		"%105 = OpTypePointer Input %104\n"
1182 		"%106 = OpVariable %105 Input\n"
1183 		"%4 = OpFunction %2 None %3\n"
1184 		"%5 = OpLabel\n"
1185 		"%9 = OpLoad %6 %8\n"
1186 		"%12 = OpIEqual %11 %9 %10\n"
1187 		"OpSelectionMerge %14 None\n"
1188 		"OpBranchConditional %12 %13 %14\n"
1189 		"%13 = OpLabel\n"
1190 		"%23 = OpAccessChain %22 %20 %10\n"
1191 		"OpStore %23 %21\n"
1192 		"%25 = OpAccessChain %22 %20 %24\n"
1193 		"OpStore %25 %21\n"
1194 		"%30 = OpAccessChain %22 %29 %10\n"
1195 		"OpStore %30 %21\n"
1196 		"%31 = OpAccessChain %22 %29 %24\n"
1197 		"OpStore %31 %21\n"
1198 		"%33 = OpAccessChain %22 %29 %32\n"
1199 		"OpStore %33 %21\n"
1200 		"%35 = OpAccessChain %22 %29 %34\n"
1201 		"OpStore %35 %21\n"
1202 		"OpBranch %14\n"
1203 		"%14 = OpLabel\n"
1204 		"%40 = OpLoad %6 %8\n"
1205 		"%45 = OpLoad %6 %8\n"
1206 		"%47 = OpAccessChain %46 %color_in %45\n"
1207 		"%48 = OpLoad %36 %47\n"
1208 		"%50 = OpAccessChain %49 %color_out %40\n"
1209 		"OpStore %50 %48\n"
1210 		"%52 = OpLoad %6 %8\n"
1211 		"%56 = OpLoad %6 %8\n"
1212 		"%58 = OpAccessChain %57 %r_float_in %56\n"
1213 		"%59 = OpLoad %15 %58\n"
1214 		"%60 = OpAccessChain %22 %r_float_out %52\n"
1215 		"OpStore %60 %59\n"
1216 		"%65 = OpLoad %6 %8\n"
1217 		"%69 = OpLoad %6 %8\n"
1218 		"%71 = OpAccessChain %70 %rg_float_in %69\n"
1219 		"%72 = OpLoad %61 %71\n"
1220 		"%74 = OpAccessChain %73 %rg_float_out %65\n"
1221 		"OpStore %74 %72\n"
1222 		"%79 = OpLoad %6 %8\n"
1223 		"%83 = OpLoad %6 %8\n"
1224 		"%85 = OpAccessChain %84 %rgb_float_in %83\n"
1225 		"%86 = OpLoad %75 %85\n"
1226 		"%88 = OpAccessChain %87 %rgb_float_out %79\n"
1227 		"OpStore %88 %86\n"
1228 		"%90 = OpLoad %6 %8\n"
1229 		"%92 = OpLoad %6 %8\n"
1230 		"%93 = OpAccessChain %46 %rgba_float_in %92\n"
1231 		"%94 = OpLoad %36 %93\n"
1232 		"%95 = OpAccessChain %49 %rgba_float_out %90\n"
1233 		"OpStore %95 %94\n"
1234 		"%102 = OpLoad %6 %8\n"
1235 		"%107 = OpLoad %6 %8\n"
1236 		"%108 = OpAccessChain %46 %106 %107 %10\n"
1237 		"%109 = OpLoad %36 %108\n"
1238 		"%110 = OpAccessChain %49 %101 %102 %10\n"
1239 		"OpStore %110 %109\n"
1240 		"OpReturn\n"
1241 		"OpFunctionEnd\n";
1242 
1243 		/*#version 450
1244 		#extension GL_EXT_tessellation_shader : require
1245 		layout( quads, equal_spacing, ccw ) in;
1246 		layout(location = 0) in vec4		in_color[];
1247 		layout(location = 1) in float		r_float_in[];
1248 		layout(location = 2) in vec2		rg_float_in[];
1249 		layout(location = 3) in vec3		rgb_float_in[];
1250 		layout(location = 4) in vec4		rgba_float_in[];
1251 		layout(location = 0) out vec4		out_color;
1252 		layout(location = 1) out float		r_float_out;
1253 		layout(location = 2) out vec2		rg_float_out;
1254 		layout(location = 3) out vec3		rgb_float_out;
1255 		layout(location = 4) out vec4		rgba_float_out;
1256 		void main (void)
1257 		{
1258 			const float u = gl_TessCoord.x;
1259 			const float v = gl_TessCoord.y;
1260 			const float w = gl_TessCoord.z;
1261 			out_color = (1 - u) * (1 - v) * in_color[0] +(1 - u) * v * in_color[1] + u * (1 - v) * in_color[2] + u * v * in_color[3];
1262 			r_float_out = (1 - u) * (1 - v) * r_float_in[0] +(1 - u) * v * r_float_in[1] + u * (1 - v) * r_float_in[2] + u * v * r_float_in[3];
1263 			rg_float_out = (1 - u) * (1 - v) * rg_float_in[0] +(1 - u) * v * rg_float_in[1] + u * (1 - v) * rg_float_in[2] + u * v * rg_float_in[3];
1264 			rgb_float_out = (1 - u) * (1 - v) * rgb_float_in[0] +(1 - u) * v * rgb_float_in[1] + u * (1 - v) * rgb_float_in[2] + u * v * rgb_float_in[3];
1265 			rgba_float_out = (1 - u) * (1 - v) * rgba_float_in[0] +(1 - u) * v * rgba_float_in[1] + u * (1 - v) * rgba_float_in[2] + u * v * rgba_float_in[3];
1266 			gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;
1267 		}*/
1268 
1269 		const string tessellationEvaluationSource =
1270 		"; SPIR-V\n"
1271 		"; Version: 1.3\n"
1272 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1273 		"; Bound: 253\n"
1274 		"; Schema: 0\n"
1275 		"OpCapability Tessellation\n"
1276 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1277 		"OpMemoryModel Logical GLSL450\n"
1278 		"OpEntryPoint TessellationEvaluation %4 \"main\" %11 %color_out %color_in %r_float_out %r_float_in %rg_float_out %rg_float_in %rgb_float_out %rgb_float_in %rgba_float_out %rgba_float_in %216 %225\n"
1279 		"OpExecutionMode %4 Quads\n"
1280 		"OpExecutionMode %4 SpacingEqual\n"
1281 		"OpExecutionMode %4 VertexOrderCcw\n"
1282 		"OpDecorate %11 BuiltIn TessCoord\n"
1283 		"OpDecorate %color_out Location 0\n"
1284 		"OpDecorate %color_in Location 0\n"
1285 		"OpDecorate %r_float_out Location 1\n"
1286 		"OpDecorate %r_float_in Location 1\n"
1287 		"OpDecorate %rg_float_out Location 2\n"
1288 		"OpDecorate %rg_float_in Location 2\n"
1289 		"OpDecorate %rgb_float_out Location 3\n"
1290 		"OpDecorate %rgb_float_in Location 3\n"
1291 		"OpDecorate %rgba_float_out Location 4\n"
1292 		"OpDecorate %rgba_float_in Location 4\n"
1293 		+decorations[0].others+
1294 		"OpMemberDecorate %214 0 BuiltIn Position\n"
1295 		"OpMemberDecorate %214 1 BuiltIn PointSize\n"
1296 		"OpMemberDecorate %214 2 BuiltIn ClipDistance\n"
1297 		"OpMemberDecorate %214 3 BuiltIn CullDistance\n"
1298 		"OpDecorate %214 Block\n"
1299 		"OpMemberDecorate %222 0 BuiltIn Position\n"
1300 		"OpMemberDecorate %222 1 BuiltIn PointSize\n"
1301 		"OpMemberDecorate %222 2 BuiltIn ClipDistance\n"
1302 		"OpMemberDecorate %222 3 BuiltIn CullDistance\n"
1303 		"OpDecorate %222 Block\n"
1304 		"%2 = OpTypeVoid\n"
1305 		"%3 = OpTypeFunction %2\n"
1306 		"%6 = OpTypeFloat 32\n"
1307 		"%7 = OpTypePointer Function %6\n"
1308 		"%9 = OpTypeVector %6 3\n"
1309 		"%10 = OpTypePointer Input %9\n"
1310 		"%11 = OpVariable %10 Input\n"
1311 		"%12 = OpTypeInt 32 0\n"
1312 		"%13 = OpConstant %12 0\n"
1313 		"%14 = OpTypePointer Input %6\n"
1314 		"%18 = OpConstant %12 1\n"
1315 		"%22 = OpConstant %12 2\n"
1316 		"%25 = OpTypeVector %6 4\n"
1317 		"%26 = OpTypePointer Output %25\n"
1318 		"%color_out = OpVariable %26 Output\n"
1319 		"%28 = OpConstant %6 1\n"
1320 		"%34 = OpConstant %12 32\n"
1321 		"%35 = OpTypeArray %25 %34\n"
1322 		"%36 = OpTypePointer Input %35\n"
1323 		"%color_in = OpVariable %36 Input\n"
1324 		"%38 = OpTypeInt 32 1\n"
1325 		"%39 = OpConstant %38 0\n"
1326 		"%40 = OpTypePointer Input %25\n"
1327 		"%48 = OpConstant %38 1\n"
1328 		"%57 = OpConstant %38 2\n"
1329 		"%65 = OpConstant %38 3\n"
1330 		"%70 = OpTypePointer Output %6\n"
1331 		"%r_float_out = OpVariable %70 Output\n"
1332 		"%77 = OpTypeArray %6 %34\n"
1333 		"%78 = OpTypePointer Input %77\n"
1334 		"%r_float_in = OpVariable %78 Input\n"
1335 		"%106 = OpTypeVector %6 2\n"
1336 		"%107 = OpTypePointer Output %106\n"
1337 		"%rg_float_out = OpVariable %107 Output\n"
1338 		"%114 = OpTypeArray %106 %34\n"
1339 		"%115 = OpTypePointer Input %114\n"
1340 		"%rg_float_in = OpVariable %115 Input\n"
1341 		"%117 = OpTypePointer Input %106\n"
1342 		"%144 = OpTypePointer Output %9\n"
1343 		"%rgb_float_out = OpVariable %144 Output\n"
1344 		"%151 = OpTypeArray %9 %34\n"
1345 		"%152 = OpTypePointer Input %151\n"
1346 		"%rgb_float_in = OpVariable %152 Input\n"
1347 		"%rgba_float_out = OpVariable %26 Output\n"
1348 		"%rgba_float_in = OpVariable %36 Input\n"
1349 		"%213 = OpTypeArray %6 %18\n"
1350 		"%214 = OpTypeStruct %25 %6 %213 %213\n"
1351 		"%215 = OpTypePointer Output %214\n"
1352 		"%216 = OpVariable %215 Output\n"
1353 		"%222 = OpTypeStruct %25 %6 %213 %213\n"
1354 		"%223 = OpTypeArray %222 %34\n"
1355 		"%224 = OpTypePointer Input %223\n"
1356 		"%225 = OpVariable %224 Input\n"
1357 		"%4 = OpFunction %2 None %3\n"
1358 		"%5 = OpLabel\n"
1359 		"%8 = OpVariable %7 Function\n"
1360 		"%17 = OpVariable %7 Function\n"
1361 		"%21 = OpVariable %7 Function\n"
1362 		"%15 = OpAccessChain %14 %11 %13\n"
1363 		"%16 = OpLoad %6 %15\n"
1364 		"OpStore %8 %16\n"
1365 		"%19 = OpAccessChain %14 %11 %18\n"
1366 		"%20 = OpLoad %6 %19\n"
1367 		"OpStore %17 %20\n"
1368 		"%23 = OpAccessChain %14 %11 %22\n"
1369 		"%24 = OpLoad %6 %23\n"
1370 		"OpStore %21 %24\n"
1371 		"%29 = OpLoad %6 %8\n"
1372 		"%30 = OpFSub %6 %28 %29\n"
1373 		"%31 = OpLoad %6 %17\n"
1374 		"%32 = OpFSub %6 %28 %31\n"
1375 		"%33 = OpFMul %6 %30 %32\n"
1376 		"%41 = OpAccessChain %40 %color_in %39\n"
1377 		"%42 = OpLoad %25 %41\n"
1378 		"%43 = OpVectorTimesScalar %25 %42 %33\n"
1379 		"%44 = OpLoad %6 %8\n"
1380 		"%45 = OpFSub %6 %28 %44\n"
1381 		"%46 = OpLoad %6 %17\n"
1382 		"%47 = OpFMul %6 %45 %46\n"
1383 		"%49 = OpAccessChain %40 %color_in %48\n"
1384 		"%50 = OpLoad %25 %49\n"
1385 		"%51 = OpVectorTimesScalar %25 %50 %47\n"
1386 		"%52 = OpFAdd %25 %43 %51\n"
1387 		"%53 = OpLoad %6 %8\n"
1388 		"%54 = OpLoad %6 %17\n"
1389 		"%55 = OpFSub %6 %28 %54\n"
1390 		"%56 = OpFMul %6 %53 %55\n"
1391 		"%58 = OpAccessChain %40 %color_in %57\n"
1392 		"%59 = OpLoad %25 %58\n"
1393 		"%60 = OpVectorTimesScalar %25 %59 %56\n"
1394 		"%61 = OpFAdd %25 %52 %60\n"
1395 		"%62 = OpLoad %6 %8\n"
1396 		"%63 = OpLoad %6 %17\n"
1397 		"%64 = OpFMul %6 %62 %63\n"
1398 		"%66 = OpAccessChain %40 %color_in %65\n"
1399 		"%67 = OpLoad %25 %66\n"
1400 		"%68 = OpVectorTimesScalar %25 %67 %64\n"
1401 		"%69 = OpFAdd %25 %61 %68\n"
1402 		"OpStore %color_out %69\n"
1403 		"%72 = OpLoad %6 %8\n"
1404 		"%73 = OpFSub %6 %28 %72\n"
1405 		"%74 = OpLoad %6 %17\n"
1406 		"%75 = OpFSub %6 %28 %74\n"
1407 		"%76 = OpFMul %6 %73 %75\n"
1408 		"%80 = OpAccessChain %14 %r_float_in %39\n"
1409 		"%81 = OpLoad %6 %80\n"
1410 		"%82 = OpFMul %6 %76 %81\n"
1411 		"%83 = OpLoad %6 %8\n"
1412 		"%84 = OpFSub %6 %28 %83\n"
1413 		"%85 = OpLoad %6 %17\n"
1414 		"%86 = OpFMul %6 %84 %85\n"
1415 		"%87 = OpAccessChain %14 %r_float_in %48\n"
1416 		"%88 = OpLoad %6 %87\n"
1417 		"%89 = OpFMul %6 %86 %88\n"
1418 		"%90 = OpFAdd %6 %82 %89\n"
1419 		"%91 = OpLoad %6 %8\n"
1420 		"%92 = OpLoad %6 %17\n"
1421 		"%93 = OpFSub %6 %28 %92\n"
1422 		"%94 = OpFMul %6 %91 %93\n"
1423 		"%95 = OpAccessChain %14 %r_float_in %57\n"
1424 		"%96 = OpLoad %6 %95\n"
1425 		"%97 = OpFMul %6 %94 %96\n"
1426 		"%98 = OpFAdd %6 %90 %97\n"
1427 		"%99 = OpLoad %6 %8\n"
1428 		"%100 = OpLoad %6 %17\n"
1429 		"%101 = OpFMul %6 %99 %100\n"
1430 		"%102 = OpAccessChain %14 %r_float_in %65\n"
1431 		"%103 = OpLoad %6 %102\n"
1432 		"%104 = OpFMul %6 %101 %103\n"
1433 		"%105 = OpFAdd %6 %98 %104\n"
1434 		"OpStore %r_float_out %105\n"
1435 		"%109 = OpLoad %6 %8\n"
1436 		"%110 = OpFSub %6 %28 %109\n"
1437 		"%111 = OpLoad %6 %17\n"
1438 		"%112 = OpFSub %6 %28 %111\n"
1439 		"%113 = OpFMul %6 %110 %112\n"
1440 		"%118 = OpAccessChain %117 %rg_float_in %39\n"
1441 		"%119 = OpLoad %106 %118\n"
1442 		"%120 = OpVectorTimesScalar %106 %119 %113\n"
1443 		"%121 = OpLoad %6 %8\n"
1444 		"%122 = OpFSub %6 %28 %121\n"
1445 		"%123 = OpLoad %6 %17\n"
1446 		"%124 = OpFMul %6 %122 %123\n"
1447 		"%125 = OpAccessChain %117 %rg_float_in %48\n"
1448 		"%126 = OpLoad %106 %125\n"
1449 		"%127 = OpVectorTimesScalar %106 %126 %124\n"
1450 		"%128 = OpFAdd %106 %120 %127\n"
1451 		"%129 = OpLoad %6 %8\n"
1452 		"%130 = OpLoad %6 %17\n"
1453 		"%131 = OpFSub %6 %28 %130\n"
1454 		"%132 = OpFMul %6 %129 %131\n"
1455 		"%133 = OpAccessChain %117 %rg_float_in %57\n"
1456 		"%134 = OpLoad %106 %133\n"
1457 		"%135 = OpVectorTimesScalar %106 %134 %132\n"
1458 		"%136 = OpFAdd %106 %128 %135\n"
1459 		"%137 = OpLoad %6 %8\n"
1460 		"%138 = OpLoad %6 %17\n"
1461 		"%139 = OpFMul %6 %137 %138\n"
1462 		"%140 = OpAccessChain %117 %rg_float_in %65\n"
1463 		"%141 = OpLoad %106 %140\n"
1464 		"%142 = OpVectorTimesScalar %106 %141 %139\n"
1465 		"%143 = OpFAdd %106 %136 %142\n"
1466 		"OpStore %rg_float_out %143\n"
1467 		"%146 = OpLoad %6 %8\n"
1468 		"%147 = OpFSub %6 %28 %146\n"
1469 		"%148 = OpLoad %6 %17\n"
1470 		"%149 = OpFSub %6 %28 %148\n"
1471 		"%150 = OpFMul %6 %147 %149\n"
1472 		"%154 = OpAccessChain %10 %rgb_float_in %39\n"
1473 		"%155 = OpLoad %9 %154\n"
1474 		"%156 = OpVectorTimesScalar %9 %155 %150\n"
1475 		"%157 = OpLoad %6 %8\n"
1476 		"%158 = OpFSub %6 %28 %157\n"
1477 		"%159 = OpLoad %6 %17\n"
1478 		"%160 = OpFMul %6 %158 %159\n"
1479 		"%161 = OpAccessChain %10 %rgb_float_in %48\n"
1480 		"%162 = OpLoad %9 %161\n"
1481 		"%163 = OpVectorTimesScalar %9 %162 %160\n"
1482 		"%164 = OpFAdd %9 %156 %163\n"
1483 		"%165 = OpLoad %6 %8\n"
1484 		"%166 = OpLoad %6 %17\n"
1485 		"%167 = OpFSub %6 %28 %166\n"
1486 		"%168 = OpFMul %6 %165 %167\n"
1487 		"%169 = OpAccessChain %10 %rgb_float_in %57\n"
1488 		"%170 = OpLoad %9 %169\n"
1489 		"%171 = OpVectorTimesScalar %9 %170 %168\n"
1490 		"%172 = OpFAdd %9 %164 %171\n"
1491 		"%173 = OpLoad %6 %8\n"
1492 		"%174 = OpLoad %6 %17\n"
1493 		"%175 = OpFMul %6 %173 %174\n"
1494 		"%176 = OpAccessChain %10 %rgb_float_in %65\n"
1495 		"%177 = OpLoad %9 %176\n"
1496 		"%178 = OpVectorTimesScalar %9 %177 %175\n"
1497 		"%179 = OpFAdd %9 %172 %178\n"
1498 		"OpStore %rgb_float_out %179\n"
1499 		"%181 = OpLoad %6 %8\n"
1500 		"%182 = OpFSub %6 %28 %181\n"
1501 		"%183 = OpLoad %6 %17\n"
1502 		"%184 = OpFSub %6 %28 %183\n"
1503 		"%185 = OpFMul %6 %182 %184\n"
1504 		"%187 = OpAccessChain %40 %rgba_float_in %39\n"
1505 		"%188 = OpLoad %25 %187\n"
1506 		"%189 = OpVectorTimesScalar %25 %188 %185\n"
1507 		"%190 = OpLoad %6 %8\n"
1508 		"%191 = OpFSub %6 %28 %190\n"
1509 		"%192 = OpLoad %6 %17\n"
1510 		"%193 = OpFMul %6 %191 %192\n"
1511 		"%194 = OpAccessChain %40 %rgba_float_in %48\n"
1512 		"%195 = OpLoad %25 %194\n"
1513 		"%196 = OpVectorTimesScalar %25 %195 %193\n"
1514 		"%197 = OpFAdd %25 %189 %196\n"
1515 		"%198 = OpLoad %6 %8\n"
1516 		"%199 = OpLoad %6 %17\n"
1517 		"%200 = OpFSub %6 %28 %199\n"
1518 		"%201 = OpFMul %6 %198 %200\n"
1519 		"%202 = OpAccessChain %40 %rgba_float_in %57\n"
1520 		"%203 = OpLoad %25 %202\n"
1521 		"%204 = OpVectorTimesScalar %25 %203 %201\n"
1522 		"%205 = OpFAdd %25 %197 %204\n"
1523 		"%206 = OpLoad %6 %8\n"
1524 		"%207 = OpLoad %6 %17\n"
1525 		"%208 = OpFMul %6 %206 %207\n"
1526 		"%209 = OpAccessChain %40 %rgba_float_in %65\n"
1527 		"%210 = OpLoad %25 %209\n"
1528 		"%211 = OpVectorTimesScalar %25 %210 %208\n"
1529 		"%212 = OpFAdd %25 %205 %211\n"
1530 		"OpStore %rgba_float_out %212\n"
1531 		"%217 = OpLoad %6 %8\n"
1532 		"%218 = OpFSub %6 %28 %217\n"
1533 		"%219 = OpLoad %6 %17\n"
1534 		"%220 = OpFSub %6 %28 %219\n"
1535 		"%221 = OpFMul %6 %218 %220\n"
1536 		"%226 = OpAccessChain %40 %225 %39 %39\n"
1537 		"%227 = OpLoad %25 %226\n"
1538 		"%228 = OpVectorTimesScalar %25 %227 %221\n"
1539 		"%229 = OpLoad %6 %8\n"
1540 		"%230 = OpFSub %6 %28 %229\n"
1541 		"%231 = OpLoad %6 %17\n"
1542 		"%232 = OpFMul %6 %230 %231\n"
1543 		"%233 = OpAccessChain %40 %225 %48 %39\n"
1544 		"%234 = OpLoad %25 %233\n"
1545 		"%235 = OpVectorTimesScalar %25 %234 %232\n"
1546 		"%236 = OpFAdd %25 %228 %235\n"
1547 		"%237 = OpLoad %6 %8\n"
1548 		"%238 = OpLoad %6 %17\n"
1549 		"%239 = OpFSub %6 %28 %238\n"
1550 		"%240 = OpFMul %6 %237 %239\n"
1551 		"%241 = OpAccessChain %40 %225 %57 %39\n"
1552 		"%242 = OpLoad %25 %241\n"
1553 		"%243 = OpVectorTimesScalar %25 %242 %240\n"
1554 		"%244 = OpFAdd %25 %236 %243\n"
1555 		"%245 = OpLoad %6 %8\n"
1556 		"%246 = OpLoad %6 %17\n"
1557 		"%247 = OpFMul %6 %245 %246\n"
1558 		"%248 = OpAccessChain %40 %225 %65 %39\n"
1559 		"%249 = OpLoad %25 %248\n"
1560 		"%250 = OpVectorTimesScalar %25 %249 %247\n"
1561 		"%251 = OpFAdd %25 %244 %250\n"
1562 		"%252 = OpAccessChain %26 %216 %39\n"
1563 		"OpStore %252 %251\n"
1564 		"OpReturn\n"
1565 		"OpFunctionEnd\n";
1566 		programCollection.spirvAsmSources.add("tessellation_control") << tessellationControlSource;
1567 		programCollection.spirvAsmSources.add("tessellation_evaluation") << tessellationEvaluationSource;
1568 	}
1569 	{
1570 
1571 		/*#version 450
1572 		layout(triangles) in;
1573 		layout(triangle_strip, max_vertices = 3) out;
1574 		layout(location = 0) in vec4    in_color[];
1575 		layout(location = 1) in float   r_float_in[];
1576 		layout(location = 2) in vec2    rg_float_in[];
1577 		layout(location = 3) in vec3    rgb_float_in[];
1578 		layout(location = 4) in vec4    rgba_float_in[];
1579 		layout(location = 0) out vec4   out_color;
1580 		layout(location = 1) out float  r_float_out;
1581 		layout(location = 2) out vec2   rg_float_out;
1582 		layout(location = 3) out vec3   rgb_float_out;
1583 		layout(location = 4) out vec4   rgba_float_out;
1584 		void main (void)
1585 		{
1586 			out_color = in_color[0];
1587 			r_float_out = r_float_in[0];
1588 			rg_float_out = rg_float_in[0];
1589 			rgb_float_out = rgb_float_in[0];
1590 			rgba_float_out = rgba_float_in[0];
1591 			gl_Position = gl_in[0].gl_Position;
1592 			EmitVertex();
1593 			out_color = in_color[1];
1594 			r_float_out = r_float_in[1];
1595 			rg_float_out = rg_float_in[1];
1596 			rgb_float_out = rgb_float_in[1];
1597 			rgba_float_out = rgba_float_in[1];
1598 			gl_Position = gl_in[1].gl_Position;
1599 			EmitVertex();
1600 			out_color = in_color[2];
1601 			r_float_out = r_float_in[2];
1602 			rg_float_out = rg_float_in[2];
1603 			rgb_float_out = rgb_float_in[2];
1604 			rgba_float_out = rgba_float_in[2];
1605 			gl_Position = gl_in[2].gl_Position;
1606 			EmitVertex();
1607 			EndPrimitive();
1608 		}
1609 		*/
1610 		const string geometrySource =
1611 		"; SPIR-V\n"
1612 		"; Version: 1.3\n"
1613 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1614 		"; Bound: 90\n"
1615 		"; Schema: 0\n"
1616 		"OpCapability Geometry\n"
1617 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1618 		"OpMemoryModel Logical GLSL450\n"
1619 		"OpEntryPoint Geometry %4 \"main\" %color_out %color_in %r_float_out %r_float_in %rg_float_out %rg_float_in %rgb_float_out %rgb_float_in %rgba_float_out %rgba_float_in %54 %58\n"
1620 		"OpExecutionMode %4 Triangles\n"
1621 		"OpExecutionMode %4 Invocations 1\n"
1622 		"OpExecutionMode %4 OutputTriangleStrip\n"
1623 		"OpExecutionMode %4 OutputVertices 3\n"
1624 		"OpDecorate %color_out Location 0\n"
1625 		"OpDecorate %color_in Location 0\n"
1626 		"OpDecorate %r_float_out Location 1\n"
1627 		"OpDecorate %r_float_in Location 1\n"
1628 		"OpDecorate %rg_float_out Location 2\n"
1629 		"OpDecorate %rg_float_in Location 2\n"
1630 		"OpDecorate %rgb_float_out Location 3\n"
1631 		"OpDecorate %rgb_float_in Location 3\n"
1632 		"OpDecorate %rgba_float_out Location 4\n"
1633 		"OpDecorate %rgba_float_in Location 4\n"
1634 		+decorations[0].others+
1635 		"OpMemberDecorate %52 0 BuiltIn Position\n"
1636 		"OpMemberDecorate %52 1 BuiltIn PointSize\n"
1637 		"OpMemberDecorate %52 2 BuiltIn ClipDistance\n"
1638 		"OpMemberDecorate %52 3 BuiltIn CullDistance\n"
1639 		"OpDecorate %52 Block\n"
1640 		"OpMemberDecorate %55 0 BuiltIn Position\n"
1641 		"OpMemberDecorate %55 1 BuiltIn PointSize\n"
1642 		"OpMemberDecorate %55 2 BuiltIn ClipDistance\n"
1643 		"OpMemberDecorate %55 3 BuiltIn CullDistance\n"
1644 		"OpDecorate %55 Block\n"
1645 		"%2 = OpTypeVoid\n"
1646 		"%3 = OpTypeFunction %2\n"
1647 		"%6 = OpTypeFloat 32\n"
1648 		"%7 = OpTypeVector %6 4\n"
1649 		"%8 = OpTypePointer Output %7\n"
1650 		"%color_out = OpVariable %8 Output\n"
1651 		"%10 = OpTypeInt 32 0\n"
1652 		"%11 = OpConstant %10 3\n"
1653 		"%12 = OpTypeArray %7 %11\n"
1654 		"%13 = OpTypePointer Input %12\n"
1655 		"%color_in = OpVariable %13 Input\n"
1656 		"%15 = OpTypeInt 32 1\n"
1657 		"%16 = OpConstant %15 0\n"
1658 		"%17 = OpTypePointer Input %7\n"
1659 		"%20 = OpTypePointer Output %6\n"
1660 		"%r_float_out = OpVariable %20 Output\n"
1661 		"%22 = OpTypeArray %6 %11\n"
1662 		"%23 = OpTypePointer Input %22\n"
1663 		"%r_float_in = OpVariable %23 Input\n"
1664 		"%25 = OpTypePointer Input %6\n"
1665 		"%28 = OpTypeVector %6 2\n"
1666 		"%29 = OpTypePointer Output %28\n"
1667 		"%rg_float_out = OpVariable %29 Output\n"
1668 		"%31 = OpTypeArray %28 %11\n"
1669 		"%32 = OpTypePointer Input %31\n"
1670 		"%rg_float_in = OpVariable %32 Input\n"
1671 		"%34 = OpTypePointer Input %28\n"
1672 		"%37 = OpTypeVector %6 3\n"
1673 		"%38 = OpTypePointer Output %37\n"
1674 		"%rgb_float_out = OpVariable %38 Output\n"
1675 		"%40 = OpTypeArray %37 %11\n"
1676 		"%41 = OpTypePointer Input %40\n"
1677 		"%rgb_float_in = OpVariable %41 Input\n"
1678 		"%43 = OpTypePointer Input %37\n"
1679 		"%rgba_float_out = OpVariable %8 Output\n"
1680 		"%rgba_float_in = OpVariable %13 Input\n"
1681 		"%50 = OpConstant %10 1\n"
1682 		"%51 = OpTypeArray %6 %50\n"
1683 		"%52 = OpTypeStruct %7 %6 %51 %51\n"
1684 		"%53 = OpTypePointer Output %52\n"
1685 		"%54 = OpVariable %53 Output\n"
1686 		"%55 = OpTypeStruct %7 %6 %51 %51\n"
1687 		"%56 = OpTypeArray %55 %11\n"
1688 		"%57 = OpTypePointer Input %56\n"
1689 		"%58 = OpVariable %57 Input\n"
1690 		"%62 = OpConstant %15 1\n"
1691 		"%76 = OpConstant %15 2\n"
1692 		"%4 = OpFunction %2 None %3\n"
1693 		"%5 = OpLabel\n"
1694 		"%18 = OpAccessChain %17 %color_in %16\n"
1695 		"%19 = OpLoad %7 %18\n"
1696 		"OpStore %color_out %19\n"
1697 		"%26 = OpAccessChain %25 %r_float_in %16\n"
1698 		"%27 = OpLoad %6 %26\n"
1699 		"OpStore %r_float_out %27\n"
1700 		"%35 = OpAccessChain %34 %rg_float_in %16\n"
1701 		"%36 = OpLoad %28 %35\n"
1702 		"OpStore %rg_float_out %36\n"
1703 		"%44 = OpAccessChain %43 %rgb_float_in %16\n"
1704 		"%45 = OpLoad %37 %44\n"
1705 		"OpStore %rgb_float_out %45\n"
1706 		"%48 = OpAccessChain %17 %rgba_float_in %16\n"
1707 		"%49 = OpLoad %7 %48\n"
1708 		"OpStore %rgba_float_out %49\n"
1709 		"%59 = OpAccessChain %17 %58 %16 %16\n"
1710 		"%60 = OpLoad %7 %59\n"
1711 		"%61 = OpAccessChain %8 %54 %16\n"
1712 		"OpStore %61 %60\n"
1713 		"OpEmitVertex\n"
1714 		"%63 = OpAccessChain %17 %color_in %62\n"
1715 		"%64 = OpLoad %7 %63\n"
1716 		"OpStore %color_out %64\n"
1717 		"%65 = OpAccessChain %25 %r_float_in %62\n"
1718 		"%66 = OpLoad %6 %65\n"
1719 		"OpStore %r_float_out %66\n"
1720 		"%67 = OpAccessChain %34 %rg_float_in %62\n"
1721 		"%68 = OpLoad %28 %67\n"
1722 		"OpStore %rg_float_out %68\n"
1723 		"%69 = OpAccessChain %43 %rgb_float_in %62\n"
1724 		"%70 = OpLoad %37 %69\n"
1725 		"OpStore %rgb_float_out %70\n"
1726 		"%71 = OpAccessChain %17 %rgba_float_in %62\n"
1727 		"%72 = OpLoad %7 %71\n"
1728 		"OpStore %rgba_float_out %72\n"
1729 		"%73 = OpAccessChain %17 %58 %62 %16\n"
1730 		"%74 = OpLoad %7 %73\n"
1731 		"%75 = OpAccessChain %8 %54 %16\n"
1732 		"OpStore %75 %74\n"
1733 		"OpEmitVertex\n"
1734 		"%77 = OpAccessChain %17 %color_in %76\n"
1735 		"%78 = OpLoad %7 %77\n"
1736 		"OpStore %color_out %78\n"
1737 		"%79 = OpAccessChain %25 %r_float_in %76\n"
1738 		"%80 = OpLoad %6 %79\n"
1739 		"OpStore %r_float_out %80\n"
1740 		"%81 = OpAccessChain %34 %rg_float_in %76\n"
1741 		"%82 = OpLoad %28 %81\n"
1742 		"OpStore %rg_float_out %82\n"
1743 		"%83 = OpAccessChain %43 %rgb_float_in %76\n"
1744 		"%84 = OpLoad %37 %83\n"
1745 		"OpStore %rgb_float_out %84\n"
1746 		"%85 = OpAccessChain %17 %rgba_float_in %76\n"
1747 		"%86 = OpLoad %7 %85\n"
1748 		"OpStore %rgba_float_out %86\n"
1749 		"%87 = OpAccessChain %17 %58 %76 %16\n"
1750 		"%88 = OpLoad %7 %87\n"
1751 		"%89 = OpAccessChain %8 %54 %16\n"
1752 		"OpStore %89 %88\n"
1753 		"OpEmitVertex\n"
1754 		"OpEndPrimitive\n"
1755 		"OpReturn\n"
1756 		"OpFunctionEnd\n";
1757 		programCollection.spirvAsmSources.add("geometry") << geometrySource;
1758 	}
1759 }
1760 
1761 class CrossStageInterfaceTestsCase : public vkt::TestCase
1762 {
1763 public:
CrossStageInterfaceTestsCase(tcu::TestContext & context,const char * name,const char * description,const TestParameters & parameters)1764 	CrossStageInterfaceTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
1765 		: TestCase			(context, name, description)
1766 		, m_parameters		(parameters)
1767 	{
1768 	}
1769 private:
1770 	vkt::TestInstance*	createInstance		(vkt::Context& context) const;
1771 	void				initPrograms		(SourceCollections& programCollection) const;
1772 
1773 	const TestParameters	m_parameters;
1774 
1775 };
1776 
createInstance(vkt::Context & context) const1777 vkt::TestInstance* CrossStageInterfaceTestsCase::createInstance (vkt::Context& context) const
1778 {
1779 	return new CrossStageTestInstance(context, m_parameters);
1780 }
1781 
initPrograms(SourceCollections & programCollection) const1782 void CrossStageInterfaceTestsCase::initPrograms (SourceCollections& programCollection) const
1783 {
1784 	vector<Decorations> decorations;
1785 	string epsilon = "3e-7";
1786 	switch(m_parameters.qualifier)
1787 	{
1788 	case TEST_TYPE_FLAT:
1789 		decorations.push_back(Decorations("",
1790 								//Vertex
1791 								"OpDecorate %color_out Flat\n"
1792 								"OpMemberDecorate %block_out 0 Flat\n"
1793 								"OpMemberDecorate %block_out 1 Flat\n",
1794 								""));
1795 		decorations.push_back(Decorations(//Fragment
1796 								"OpDecorate %color_in Flat\n"
1797 								"OpMemberDecorate %block_in 0 Flat\n"
1798 								"OpMemberDecorate %block_in 1 Flat\n",
1799 								"",
1800 								""));
1801 
1802 		decorations.push_back(Decorations(//Fragment
1803 								"OpDecorate %color_in Flat\n"
1804 								"OpMemberDecorate %block_in 0 Flat\n"
1805 								"OpMemberDecorate %block_in 1 Flat\n",
1806 								//Vertex
1807 								"OpDecorate %color_out Flat\n"
1808 								"OpMemberDecorate %block_out 0 Flat\n"
1809 								"OpMemberDecorate %block_out 1 Flat\n",
1810 								""));
1811 		epsilon = "0.0";
1812 		break;
1813 	case TEST_TYPE_NOPERSPECTIVE:
1814 		decorations.push_back(Decorations("",
1815 								//Vertex
1816 								"OpDecorate %color_out NoPerspective\n"
1817 								"OpMemberDecorate %block_out 0 NoPerspective\n"
1818 								"OpMemberDecorate %block_out 1 NoPerspective\n",
1819 								""));
1820 
1821 		decorations.push_back(Decorations(//Fragment
1822 								"OpDecorate %color_in NoPerspective\n"
1823 								"OpMemberDecorate %block_in 0 NoPerspective\n"
1824 								"OpMemberDecorate %block_in 1 NoPerspective\n",
1825 								"",
1826 								""));
1827 
1828 		decorations.push_back(Decorations(//Fragment
1829 								"OpDecorate %color_in NoPerspective\n"
1830 								"OpMemberDecorate %block_in 0 NoPerspective\n"
1831 								"OpMemberDecorate %block_in 1 NoPerspective\n",
1832 								//Vertex
1833 								"OpDecorate %color_out NoPerspective\n"
1834 								"OpMemberDecorate %block_out 0 NoPerspective\n"
1835 								"OpMemberDecorate %block_out 1 NoPerspective\n",
1836 								""));
1837 		break;
1838 	case TEST_TYPE_RELAXEDPRECISION:
1839 		decorations.push_back(Decorations(//Fragment
1840 								"OpDecorate %color_in RelaxedPrecision\n"
1841 								"OpDecorate %color_out RelaxedPrecision\n"
1842 								"OpMemberDecorate %block_in 0 RelaxedPrecision\n"
1843 								"OpMemberDecorate %block_in 1 RelaxedPrecision\n",
1844 								//Vertex
1845 								"OpDecorate %color_out RelaxedPrecision\n"
1846 								"OpDecorate %color_in RelaxedPrecision\n"
1847 								"OpMemberDecorate %block_out 0 RelaxedPrecision\n"
1848 								"OpMemberDecorate %block_out 1 RelaxedPrecision\n",
1849 								//Others
1850 								"OpDecorate %color_out RelaxedPrecision\n"
1851 								"OpDecorate %color_in RelaxedPrecision\n"
1852 								"OpMemberDecorate %block_out 0 RelaxedPrecision\n"
1853 								"OpMemberDecorate %block_out 1 RelaxedPrecision\n"
1854 								"OpMemberDecorate %block_in 0 RelaxedPrecision\n"
1855 								"OpMemberDecorate %block_in 1 RelaxedPrecision\n"));
1856 		epsilon = "2e-3";
1857 		break;
1858 	default:
1859 		DE_ASSERT(0);
1860 	}
1861 
1862 	//Spir-v spec: decoration flat can be used only in Shader (fragment or vertex)
1863 	for (deUint32 ndx = 0; ndx < decorations.size(); ++ndx)
1864 	{
1865 
1866 		/*#version 450
1867 		layout(location = 0) in highp vec4 in_position;
1868 		layout(location = 1) in vec4 in_color;
1869 		layout(location = 0) out vec4 out_color;
1870 		layout(location = 1) out ColorData
1871 		{
1872 		  vec4 colorVec;
1873 		  mat2 colorMat;
1874 		} outData;
1875 		void main (void)
1876 		{
1877 		  gl_Position = in_position;
1878 		  out_color = in_color;
1879 		  outData.colorVec = in_color;
1880 		  outData.colorMat = mat2(in_color.r, in_color.g, in_color.b, in_color.a);
1881 		}
1882 		*/
1883 		const string vertexShaderSource =
1884 		"; SPIR-V\n"
1885 		"; Version: 1.3\n"
1886 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1887 		"; Bound: 51\n"
1888 		"; Schema: 0\n"
1889 		"OpCapability Shader\n"
1890 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1891 		"OpMemoryModel Logical GLSL450\n"
1892 		"OpEntryPoint Vertex %4 \"main\" %13 %17 %color_out %color_in %28\n"
1893 		"OpMemberDecorate %11 0 BuiltIn Position\n"
1894 		"OpMemberDecorate %11 1 BuiltIn PointSize\n"
1895 		"OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
1896 		"OpMemberDecorate %11 3 BuiltIn CullDistance\n"
1897 		"OpDecorate %11 Block\n"
1898 		"OpDecorate %17 Location 0\n"
1899 		"OpDecorate %color_out Location 0\n"
1900 		"OpDecorate %color_in Location 1\n"
1901 		"OpDecorate %block_out Block\n"
1902 		"OpDecorate %28 Location 1\n"
1903 		+decorations[ndx].vertex+
1904 		"%2 = OpTypeVoid\n"
1905 		"%3 = OpTypeFunction %2\n"
1906 		"%6 = OpTypeFloat 32\n"
1907 		"%7 = OpTypeVector %6 4\n"
1908 		"%8 = OpTypeInt 32 0\n"
1909 		"%9 = OpConstant %8 1\n"
1910 		"%10 = OpTypeArray %6 %9\n"
1911 		"%11 = OpTypeStruct %7 %6 %10 %10\n"
1912 		"%12 = OpTypePointer Output %11\n"
1913 		"%13 = OpVariable %12 Output\n"
1914 		"%14 = OpTypeInt 32 1\n"
1915 		"%15 = OpConstant %14 0\n"
1916 		"%16 = OpTypePointer Input %7\n"
1917 		"%17 = OpVariable %16 Input\n"
1918 		"%19 = OpTypePointer Output %7\n"
1919 		"%color_out = OpVariable %19 Output\n"
1920 		"%color_in = OpVariable %16 Input\n"
1921 		"%24 = OpTypeVector %6 2\n"
1922 		"%25 = OpTypeMatrix %24 2\n"
1923 		"%block_out = OpTypeStruct %7 %25\n"
1924 		"%27 = OpTypePointer Output %block_out\n"
1925 		"%28 = OpVariable %27 Output\n"
1926 		"%31 = OpConstant %14 1\n"
1927 		"%32 = OpConstant %8 0\n"
1928 		"%33 = OpTypePointer Input %6\n"
1929 		"%38 = OpConstant %8 2\n"
1930 		"%41 = OpConstant %8 3\n"
1931 		"%44 = OpConstant %6 1\n"
1932 		"%45 = OpConstant %6 0\n"
1933 		"%49 = OpTypePointer Output %25\n"
1934 		"%4 = OpFunction %2 None %3\n"
1935 		"%5 = OpLabel\n"
1936 		"%18 = OpLoad %7 %17\n"
1937 		"%20 = OpAccessChain %19 %13 %15\n"
1938 		"OpStore %20 %18\n"
1939 		"%23 = OpLoad %7 %color_in\n"
1940 		"OpStore %color_out %23\n"
1941 		"%29 = OpLoad %7 %color_in\n"
1942 		"%30 = OpAccessChain %19 %28 %15\n"
1943 		"OpStore %30 %29\n"
1944 		"%34 = OpAccessChain %33 %color_in %32\n"
1945 		"%35 = OpLoad %6 %34\n"
1946 		"%36 = OpAccessChain %33 %color_in %9\n"
1947 		"%37 = OpLoad %6 %36\n"
1948 		"%39 = OpAccessChain %33 %color_in %38\n"
1949 		"%40 = OpLoad %6 %39\n"
1950 		"%42 = OpAccessChain %33 %color_in %41\n"
1951 		"%43 = OpLoad %6 %42\n"
1952 		"%46 = OpCompositeConstruct %24 %35 %37\n"
1953 		"%47 = OpCompositeConstruct %24 %40 %43\n"
1954 		"%48 = OpCompositeConstruct %25 %46 %47\n"
1955 		"%50 = OpAccessChain %49 %28 %31\n"
1956 		"OpStore %50 %48\n"
1957 		"OpReturn\n"
1958 		"OpFunctionEnd\n";
1959 
1960 		/* #version 450
1961 		layout(location = 0) in vec4 in_color;
1962 		layout(location = 0) out vec4 out_color;
1963 		layout(location = 1) in ColorData
1964 		{
1965 		  vec4 colorVec;
1966 		  mat2 colorMat;
1967 		} inData;
1968 		void main()
1969 		{
1970 		  float epsilon = 3e-7; // or 0.0 for flat, or 2e-3 for RelaxedPrecision (mediump)
1971 		  out_color = in_color;
1972 		  vec4 epsilon_vec4 = max(abs(inData.colorVec), abs(in_color)) * epsilon;
1973 		  if(any(greaterThan(abs(inData.colorVec - in_color), epsilon_vec4)))
1974 		    out_color.rgba = vec4(1.0f);
1975 		  epsilon_vec4.r = max(abs(inData.colorMat[0][0]), abs(in_color.r)) * epsilon;
1976 		  if(abs(inData.colorMat[0][0] - in_color.r) > epsilon_vec4.r)
1977 		    out_color.rgba = vec4(1.0f);
1978 		  epsilon_vec4.a = max(abs(inData.colorMat[1][1]), abs(in_color.a)) * epsilon;
1979 		  if(abs(inData.colorMat[1][1] - in_color.a) > epsilon_vec4.a)
1980 		    out_color.rgba = vec4(1.0f);
1981 		}
1982 		*/
1983 		const string fragmentShaderSource =
1984 		"; SPIR-V\n"
1985 		"; Version: 1.3\n"
1986 		"; Generator: Khronos Glslang Reference Front End; 2\n"
1987 		"; Bound: 51\n"
1988 		"; Schema: 0\n"
1989 		"OpCapability Shader\n"
1990 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
1991 		"OpMemoryModel Logical GLSL450\n"
1992 		"OpEntryPoint Fragment %4 \"main\" %color_out %color_in %17\n"
1993 		"OpExecutionMode %4 OriginUpperLeft\n"
1994 		"OpDecorate %color_out Location 0\n"
1995 		"OpDecorate %color_in Location 0\n"
1996 		"OpDecorate %block_in Block\n"
1997 		"OpDecorate %17 Location 1\n"
1998 		+decorations[ndx].fragment+
1999 		"%2 = OpTypeVoid\n"
2000 		"%3 = OpTypeFunction %2\n"
2001 		"%6 = OpTypeFloat 32\n"
2002 		"%7 = OpTypeVector %6 4\n"
2003 		"%8 = OpTypePointer Output %7\n"
2004 		"%color_out = OpVariable %8 Output\n"
2005 		"%10 = OpTypePointer Input %7\n"
2006 		"%color_in = OpVariable %10 Input\n"
2007 		"%13 = OpTypeVector %6 2\n"
2008 		"%14 = OpTypeMatrix %13 2\n"
2009 		"%block_in = OpTypeStruct %7 %14\n"
2010 		"%16 = OpTypePointer Input %block_in\n"
2011 		"%17 = OpVariable %16 Input\n"
2012 		"%18 = OpTypeInt 32 1\n"
2013 		"%19 = OpConstant %18 0\n"
2014 		"%23 = OpTypeBool\n"
2015 		"%24 = OpTypeVector %23 4\n"
2016 		"%ep = OpConstant %6 " + epsilon + "\n"
2017 		"%ep4 = OpConstantComposite %7 %ep %ep %ep %ep\n"
2018 		"%29 = OpConstant %6 1\n"
2019 		"%30 = OpConstantComposite %7 %29 %29 %29 %29\n"
2020 		"%31 = OpConstant %18 1\n"
2021 		"%32 = OpTypeInt 32 0\n"
2022 		"%33 = OpConstant %32 0\n"
2023 		"%34 = OpTypePointer Input %6\n"
2024 		"%42 = OpConstant %32 1\n"
2025 		"%45 = OpConstant %32 3\n"
2026 		"%4 = OpFunction %2 None %3\n"
2027 		"%5 = OpLabel\n"
2028 		"%12 = OpLoad %7 %color_in\n"
2029 		"OpStore %color_out %12\n"
2030 		"%20 = OpAccessChain %10 %17 %19\n"
2031 		"%21 = OpLoad %7 %20\n"
2032 		"%22 = OpLoad %7 %color_in\n"
2033 		"%sub4 = OpFSub %7 %21 %22\n"
2034 		"%abs4 = OpExtInst %7 %1 FAbs %sub4\n"
2035 		"%ep4abs0 = OpExtInst %7 %1 FAbs %21\n"
2036 		"%ep4abs1 = OpExtInst %7 %1 FAbs %22\n"
2037 		"%ep4gt = OpFOrdGreaterThan %24 %ep4abs0 %ep4abs1\n"
2038 		"%ep4max = OpSelect %7 %ep4gt %ep4abs0 %ep4abs1\n"
2039 		"%ep4rel = OpFMul %7 %ep4max %ep4\n"
2040 		"%cmp4 = OpFOrdGreaterThan %24 %abs4 %ep4rel\n"
2041 		"%26 = OpAny %23 %cmp4\n"
2042 		"OpSelectionMerge %28 None\n"
2043 		"OpBranchConditional %26 %27 %28\n"
2044 		"%27 = OpLabel\n"
2045 		"OpStore %color_out %30\n"
2046 		"OpBranch %28\n"
2047 		"%28 = OpLabel\n"
2048 		"%35 = OpAccessChain %34 %17 %31 %19 %33\n"
2049 		"%36 = OpLoad %6 %35\n"
2050 		"%37 = OpAccessChain %34 %color_in %33\n"
2051 		"%38 = OpLoad %6 %37\n"
2052 		"%subr = OpFSub %6 %36 %38\n"
2053 		"%absr = OpExtInst %6 %1 FAbs %subr\n"
2054 		"%ep1abs0 = OpExtInst %6 %1 FAbs %36\n"
2055 		"%ep1abs1 = OpExtInst %6 %1 FAbs %38\n"
2056 		"%ep1gt = OpFOrdGreaterThan %23 %ep1abs0 %ep1abs1\n"
2057 		"%ep1max = OpSelect %6 %ep1gt %ep1abs0 %ep1abs1\n"
2058 		"%ep1rel = OpFMul %6 %ep1max %ep\n"
2059 		"%cmpr = OpFOrdGreaterThan %23 %absr %ep1rel\n"
2060 		"OpSelectionMerge %41 None\n"
2061 		"OpBranchConditional %cmpr %40 %41\n"
2062 		"%40 = OpLabel\n"
2063 		"OpStore %color_out %30\n"
2064 		"OpBranch %41\n"
2065 		"%41 = OpLabel\n"
2066 		"%43 = OpAccessChain %34 %17 %31 %31 %42\n"
2067 		"%44 = OpLoad %6 %43\n"
2068 		"%46 = OpAccessChain %34 %color_in %45\n"
2069 		"%47 = OpLoad %6 %46\n"
2070 		"%suba = OpFSub %6 %44 %47\n"
2071 		"%absa = OpExtInst %6 %1 FAbs %suba\n"
2072 		"%ep1babs0 = OpExtInst %6 %1 FAbs %44\n"
2073 		"%ep1babs1 = OpExtInst %6 %1 FAbs %47\n"
2074 		"%ep1bgt = OpFOrdGreaterThan %23 %ep1babs0 %ep1babs1\n"
2075 		"%ep1bmax = OpSelect %6 %ep1bgt %ep1babs0 %ep1babs1\n"
2076 		"%ep1brel = OpFMul %6 %ep1bmax %ep\n"
2077 		"%cmpa = OpFOrdGreaterThan %23 %absa %ep1brel\n"
2078 		"OpSelectionMerge %50 None\n"
2079 		"OpBranchConditional %cmpa %49 %50\n"
2080 		"%49 = OpLabel\n"
2081 		"OpStore %color_out %30\n"
2082 		"OpBranch %50\n"
2083 		"%50 = OpLabel\n"
2084 		"OpReturn\n"
2085 		"OpFunctionEnd\n";
2086 
2087 		std::ostringstream vertex;
2088 		vertex << "vertex" << ndx;
2089 		std::ostringstream fragment;
2090 		fragment << "fragment" << ndx;
2091 
2092 		programCollection.spirvAsmSources.add(vertex.str()) << vertexShaderSource;
2093 		programCollection.spirvAsmSources.add(fragment.str()) << fragmentShaderSource;
2094 	}
2095 	{
2096 		/*#version 450
2097 		#extension GL_EXT_tessellation_shader : require
2098 		layout(vertices = 4) out;
2099 		layout(location = 0) in vec4		in_color[];
2100 		layout(location = 1) in ColorData
2101 		{
2102 		  vec4 colorVec;
2103 		  mat2 colorMat;
2104 		} inData[];
2105 		layout(location = 0) out vec4		out_color[];
2106 		layout(location = 1) out ColorData
2107 		{
2108 		  vec4 colorVec;
2109 		  mat2 colorMat;
2110 		} outData[];
2111 		void main (void)
2112 		{
2113 			if ( gl_InvocationID == 0 )
2114 			{
2115 				gl_TessLevelInner[0] = 4.0f;
2116 				gl_TessLevelInner[1] = 4.0f;
2117 				gl_TessLevelOuter[0] = 4.0f;
2118 				gl_TessLevelOuter[1] = 4.0f;
2119 				gl_TessLevelOuter[2] = 4.0f;
2120 				gl_TessLevelOuter[3] = 4.0f;
2121 			}
2122 			out_color[gl_InvocationID] = in_color[gl_InvocationID];
2123 			outData[gl_InvocationID].colorVec = inData[gl_InvocationID].colorVec;
2124 			outData[gl_InvocationID].colorMat = inData[gl_InvocationID].colorMat;
2125 			gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
2126 		}*/
2127 
2128 		const string tessellationControlSource =
2129 		"; SPIR-V\n"
2130 		"; Version: 1.3\n"
2131 		"; Generator: Khronos Glslang Reference Front End; 2\n"
2132 		"; Bound: 88\n"
2133 		"; Schema: 0\n"
2134 		"OpCapability Tessellation\n"
2135 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2136 		"OpMemoryModel Logical GLSL450\n"
2137 		"OpEntryPoint TessellationControl %4 \"main\" %8 %20 %29 %color_out %color_in %56 %61 %78 %83\n"
2138 		"OpExecutionMode %4 OutputVertices 4\n"
2139 		"OpDecorate %8 BuiltIn InvocationId\n"
2140 		"OpDecorate %20 Patch\n"
2141 		"OpDecorate %20 BuiltIn TessLevelInner\n"
2142 		"OpDecorate %29 Patch\n"
2143 		"OpDecorate %29 BuiltIn TessLevelOuter\n"
2144 		"OpDecorate %color_out Location 0\n"
2145 		"OpDecorate %color_in Location 0\n"
2146 		"OpDecorate %block_out Block\n"
2147 		"OpDecorate %56 Location 1\n"
2148 		"OpDecorate %block_in Block\n"
2149 		"OpDecorate %61 Location 1\n"
2150 		+decorations[0].others+
2151 		"OpMemberDecorate %75 0 BuiltIn Position\n"
2152 		"OpMemberDecorate %75 1 BuiltIn PointSize\n"
2153 		"OpMemberDecorate %75 2 BuiltIn ClipDistance\n"
2154 		"OpMemberDecorate %75 3 BuiltIn CullDistance\n"
2155 		"OpDecorate %75 Block\n"
2156 		"OpMemberDecorate %80 0 BuiltIn Position\n"
2157 		"OpMemberDecorate %80 1 BuiltIn PointSize\n"
2158 		"OpMemberDecorate %80 2 BuiltIn ClipDistance\n"
2159 		"OpMemberDecorate %80 3 BuiltIn CullDistance\n"
2160 		"OpDecorate %80 Block\n"
2161 		"%2 = OpTypeVoid\n"
2162 		"%3 = OpTypeFunction %2\n"
2163 		"%6 = OpTypeInt 32 1\n"
2164 		"%7 = OpTypePointer Input %6\n"
2165 		"%8 = OpVariable %7 Input\n"
2166 		"%10 = OpConstant %6 0\n"
2167 		"%11 = OpTypeBool\n"
2168 		"%15 = OpTypeFloat 32\n"
2169 		"%16 = OpTypeInt 32 0\n"
2170 		"%17 = OpConstant %16 2\n"
2171 		"%18 = OpTypeArray %15 %17\n"
2172 		"%19 = OpTypePointer Output %18\n"
2173 		"%20 = OpVariable %19 Output\n"
2174 		"%21 = OpConstant %15 4\n"
2175 		"%22 = OpTypePointer Output %15\n"
2176 		"%24 = OpConstant %6 1\n"
2177 		"%26 = OpConstant %16 4\n"
2178 		"%27 = OpTypeArray %15 %26\n"
2179 		"%28 = OpTypePointer Output %27\n"
2180 		"%29 = OpVariable %28 Output\n"
2181 		"%32 = OpConstant %6 2\n"
2182 		"%34 = OpConstant %6 3\n"
2183 		"%36 = OpTypeVector %15 4\n"
2184 		"%37 = OpTypeArray %36 %26\n"
2185 		"%38 = OpTypePointer Output %37\n"
2186 		"%color_out = OpVariable %38 Output\n"
2187 		"%41 = OpConstant %16 32\n"
2188 		"%42 = OpTypeArray %36 %41\n"
2189 		"%43 = OpTypePointer Input %42\n"
2190 		"%color_in = OpVariable %43 Input\n"
2191 		"%46 = OpTypePointer Input %36\n"
2192 		"%49 = OpTypePointer Output %36\n"
2193 		"%51 = OpTypeVector %15 2\n"
2194 		"%52 = OpTypeMatrix %51 2\n"
2195 		"%block_out = OpTypeStruct %36 %52\n"
2196 		"%54 = OpTypeArray %block_out %26\n"
2197 		"%55 = OpTypePointer Output %54\n"
2198 		"%56 = OpVariable %55 Output\n"
2199 		"%block_in = OpTypeStruct %36 %52\n"
2200 		"%59 = OpTypeArray %block_in %41\n"
2201 		"%60 = OpTypePointer Input %59\n"
2202 		"%61 = OpVariable %60 Input\n"
2203 		"%68 = OpTypePointer Input %52\n"
2204 		"%71 = OpTypePointer Output %52\n"
2205 		"%73 = OpConstant %16 1\n"
2206 		"%74 = OpTypeArray %15 %73\n"
2207 		"%75 = OpTypeStruct %36 %15 %74 %74\n"
2208 		"%76 = OpTypeArray %75 %26\n"
2209 		"%77 = OpTypePointer Output %76\n"
2210 		"%78 = OpVariable %77 Output\n"
2211 		"%80 = OpTypeStruct %36 %15 %74 %74\n"
2212 		"%81 = OpTypeArray %80 %41\n"
2213 		"%82 = OpTypePointer Input %81\n"
2214 		"%83 = OpVariable %82 Input\n"
2215 		"%4 = OpFunction %2 None %3\n"
2216 		"%5 = OpLabel\n"
2217 		"%9 = OpLoad %6 %8\n"
2218 		"%12 = OpIEqual %11 %9 %10\n"
2219 		"OpSelectionMerge %14 None\n"
2220 		"OpBranchConditional %12 %13 %14\n"
2221 		"%13 = OpLabel\n"
2222 		"%23 = OpAccessChain %22 %20 %10\n"
2223 		"OpStore %23 %21\n"
2224 		"%25 = OpAccessChain %22 %20 %24\n"
2225 		"OpStore %25 %21\n"
2226 		"%30 = OpAccessChain %22 %29 %10\n"
2227 		"OpStore %30 %21\n"
2228 		"%31 = OpAccessChain %22 %29 %24\n"
2229 		"OpStore %31 %21\n"
2230 		"%33 = OpAccessChain %22 %29 %32\n"
2231 		"OpStore %33 %21\n"
2232 		"%35 = OpAccessChain %22 %29 %34\n"
2233 		"OpStore %35 %21\n"
2234 		"OpBranch %14\n"
2235 		"%14 = OpLabel\n"
2236 		"%40 = OpLoad %6 %8\n"
2237 		"%45 = OpLoad %6 %8\n"
2238 		"%47 = OpAccessChain %46 %color_in %45\n"
2239 		"%48 = OpLoad %36 %47\n"
2240 		"%50 = OpAccessChain %49 %color_out %40\n"
2241 		"OpStore %50 %48\n"
2242 		"%57 = OpLoad %6 %8\n"
2243 		"%62 = OpLoad %6 %8\n"
2244 		"%63 = OpAccessChain %46 %61 %62 %10\n"
2245 		"%64 = OpLoad %36 %63\n"
2246 		"%65 = OpAccessChain %49 %56 %57 %10\n"
2247 		"OpStore %65 %64\n"
2248 		"%66 = OpLoad %6 %8\n"
2249 		"%67 = OpLoad %6 %8\n"
2250 		"%69 = OpAccessChain %68 %61 %67 %24\n"
2251 		"%70 = OpLoad %52 %69\n"
2252 		"%72 = OpAccessChain %71 %56 %66 %24\n"
2253 		"OpStore %72 %70\n"
2254 		"%79 = OpLoad %6 %8\n"
2255 		"%84 = OpLoad %6 %8\n"
2256 		"%85 = OpAccessChain %46 %83 %84 %10\n"
2257 		"%86 = OpLoad %36 %85\n"
2258 		"%87 = OpAccessChain %49 %78 %79 %10\n"
2259 		"OpStore %87 %86\n"
2260 		"OpReturn\n"
2261 		"OpFunctionEnd\n";
2262 
2263 		/*#version 450
2264 		#extension GL_EXT_tessellation_shader : require
2265 		layout( quads, equal_spacing, ccw ) in;
2266 		layout(location = 0) in vec4		in_color[];
2267 		layout(location = 1) in ColorData
2268 		{
2269 		  vec4 colorVec;
2270 		  mat2 colorMat;
2271 		} inData[];
2272 		layout(location = 0) out vec4		out_color;
2273 		layout(location = 1) out ColorData
2274 		{
2275 		  vec4 colorVec;
2276 		  mat2 colorMat;
2277 		} outData;
2278 		void main (void)
2279 		{
2280 			const float u = gl_TessCoord.x;
2281 			const float v = gl_TessCoord.y;
2282 			const float w = gl_TessCoord.z;
2283 			out_color = (1 - u) * (1 - v) * in_color[0] +(1 - u) * v * in_color[1] + u * (1 - v) * in_color[2] + u * v * in_color[3];
2284 			outData.colorVec = (1 - u) * (1 - v) * inData[0].colorVec +(1 - u) * v * inData[1].colorVec + u * (1 - v) * inData[2].colorVec + u * v * inData[3].colorVec;
2285 			outData.colorMat = (1 - u) * (1 - v) * inData[0].colorMat +(1 - u) * v * inData[1].colorMat + u * (1 - v) * inData[2].colorMat + u * v * inData[3].colorMat;
2286 			gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;
2287 		}*/
2288 
2289 		const string tessellationEvaluationSource =
2290 		"; SPIR-V\n"
2291 		"; Version: 1.3\n"
2292 		"; Generator: Khronos Glslang Reference Front End; 2\n"
2293 		"; Bound: 203\n"
2294 		"; Schema: 0\n"
2295 		"OpCapability Tessellation\n"
2296 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2297 		"OpMemoryModel Logical GLSL450\n"
2298 		"OpEntryPoint TessellationEvaluation %4 \"main\" %11 %color_out %color_in %74 %83 %166 %175\n"
2299 		"OpExecutionMode %4 Quads\n"
2300 		"OpExecutionMode %4 SpacingEqual\n"
2301 		"OpExecutionMode %4 VertexOrderCcw\n"
2302 		"OpDecorate %11 BuiltIn TessCoord\n"
2303 		"OpDecorate %color_out Location 0\n"
2304 		"OpDecorate %color_in Location 0\n"
2305 		"OpDecorate %block_out Block\n"
2306 		"OpDecorate %74 Location 1\n"
2307 		"OpDecorate %block_in Block\n"
2308 		"OpDecorate %83 Location 1\n"
2309 		+decorations[0].others+
2310 		"OpMemberDecorate %164 0 BuiltIn Position\n"
2311 		"OpMemberDecorate %164 1 BuiltIn PointSize\n"
2312 		"OpMemberDecorate %164 2 BuiltIn ClipDistance\n"
2313 		"OpMemberDecorate %164 3 BuiltIn CullDistance\n"
2314 		"OpDecorate %164 Block\n"
2315 		"OpMemberDecorate %172 0 BuiltIn Position\n"
2316 		"OpMemberDecorate %172 1 BuiltIn PointSize\n"
2317 		"OpMemberDecorate %172 2 BuiltIn ClipDistance\n"
2318 		"OpMemberDecorate %172 3 BuiltIn CullDistance\n"
2319 		"OpDecorate %172 Block\n"
2320 		"%2 = OpTypeVoid\n"
2321 		"%3 = OpTypeFunction %2\n"
2322 		"%6 = OpTypeFloat 32\n"
2323 		"%7 = OpTypePointer Function %6\n"
2324 		"%9 = OpTypeVector %6 3\n"
2325 		"%10 = OpTypePointer Input %9\n"
2326 		"%11 = OpVariable %10 Input\n"
2327 		"%12 = OpTypeInt 32 0\n"
2328 		"%13 = OpConstant %12 0\n"
2329 		"%14 = OpTypePointer Input %6\n"
2330 		"%18 = OpConstant %12 1\n"
2331 		"%22 = OpConstant %12 2\n"
2332 		"%25 = OpTypeVector %6 4\n"
2333 		"%26 = OpTypePointer Output %25\n"
2334 		"%color_out = OpVariable %26 Output\n"
2335 		"%28 = OpConstant %6 1\n"
2336 		"%34 = OpConstant %12 32\n"
2337 		"%35 = OpTypeArray %25 %34\n"
2338 		"%36 = OpTypePointer Input %35\n"
2339 		"%color_in = OpVariable %36 Input\n"
2340 		"%38 = OpTypeInt 32 1\n"
2341 		"%39 = OpConstant %38 0\n"
2342 		"%40 = OpTypePointer Input %25\n"
2343 		"%48 = OpConstant %38 1\n"
2344 		"%57 = OpConstant %38 2\n"
2345 		"%65 = OpConstant %38 3\n"
2346 		"%70 = OpTypeVector %6 2\n"
2347 		"%71 = OpTypeMatrix %70 2\n"
2348 		"%block_out = OpTypeStruct %25 %71\n"
2349 		"%73 = OpTypePointer Output %block_out\n"
2350 		"%74 = OpVariable %73 Output\n"
2351 		"%block_in = OpTypeStruct %25 %71\n"
2352 		"%81 = OpTypeArray %block_in %34\n"
2353 		"%82 = OpTypePointer Input %81\n"
2354 		"%83 = OpVariable %82 Input\n"
2355 		"%116 = OpTypePointer Input %71\n"
2356 		"%161 = OpTypePointer Output %71\n"
2357 		"%163 = OpTypeArray %6 %18\n"
2358 		"%164 = OpTypeStruct %25 %6 %163 %163\n"
2359 		"%165 = OpTypePointer Output %164\n"
2360 		"%166 = OpVariable %165 Output\n"
2361 		"%172 = OpTypeStruct %25 %6 %163 %163\n"
2362 		"%173 = OpTypeArray %172 %34\n"
2363 		"%174 = OpTypePointer Input %173\n"
2364 		"%175 = OpVariable %174 Input\n"
2365 		"%4 = OpFunction %2 None %3\n"
2366 		"%5 = OpLabel\n"
2367 		"%8 = OpVariable %7 Function\n"
2368 		"%17 = OpVariable %7 Function\n"
2369 		"%21 = OpVariable %7 Function\n"
2370 		"%15 = OpAccessChain %14 %11 %13\n"
2371 		"%16 = OpLoad %6 %15\n"
2372 		"OpStore %8 %16\n"
2373 		"%19 = OpAccessChain %14 %11 %18\n"
2374 		"%20 = OpLoad %6 %19\n"
2375 		"OpStore %17 %20\n"
2376 		"%23 = OpAccessChain %14 %11 %22\n"
2377 		"%24 = OpLoad %6 %23\n"
2378 		"OpStore %21 %24\n"
2379 		"%29 = OpLoad %6 %8\n"
2380 		"%30 = OpFSub %6 %28 %29\n"
2381 		"%31 = OpLoad %6 %17\n"
2382 		"%32 = OpFSub %6 %28 %31\n"
2383 		"%33 = OpFMul %6 %30 %32\n"
2384 		"%41 = OpAccessChain %40 %color_in %39\n"
2385 		"%42 = OpLoad %25 %41\n"
2386 		"%43 = OpVectorTimesScalar %25 %42 %33\n"
2387 		"%44 = OpLoad %6 %8\n"
2388 		"%45 = OpFSub %6 %28 %44\n"
2389 		"%46 = OpLoad %6 %17\n"
2390 		"%47 = OpFMul %6 %45 %46\n"
2391 		"%49 = OpAccessChain %40 %color_in %48\n"
2392 		"%50 = OpLoad %25 %49\n"
2393 		"%51 = OpVectorTimesScalar %25 %50 %47\n"
2394 		"%52 = OpFAdd %25 %43 %51\n"
2395 		"%53 = OpLoad %6 %8\n"
2396 		"%54 = OpLoad %6 %17\n"
2397 		"%55 = OpFSub %6 %28 %54\n"
2398 		"%56 = OpFMul %6 %53 %55\n"
2399 		"%58 = OpAccessChain %40 %color_in %57\n"
2400 		"%59 = OpLoad %25 %58\n"
2401 		"%60 = OpVectorTimesScalar %25 %59 %56\n"
2402 		"%61 = OpFAdd %25 %52 %60\n"
2403 		"%62 = OpLoad %6 %8\n"
2404 		"%63 = OpLoad %6 %17\n"
2405 		"%64 = OpFMul %6 %62 %63\n"
2406 		"%66 = OpAccessChain %40 %color_in %65\n"
2407 		"%67 = OpLoad %25 %66\n"
2408 		"%68 = OpVectorTimesScalar %25 %67 %64\n"
2409 		"%69 = OpFAdd %25 %61 %68\n"
2410 		"OpStore %color_out %69\n"
2411 		"%75 = OpLoad %6 %8\n"
2412 		"%76 = OpFSub %6 %28 %75\n"
2413 		"%77 = OpLoad %6 %17\n"
2414 		"%78 = OpFSub %6 %28 %77\n"
2415 		"%79 = OpFMul %6 %76 %78\n"
2416 		"%84 = OpAccessChain %40 %83 %39 %39\n"
2417 		"%85 = OpLoad %25 %84\n"
2418 		"%86 = OpVectorTimesScalar %25 %85 %79\n"
2419 		"%87 = OpLoad %6 %8\n"
2420 		"%88 = OpFSub %6 %28 %87\n"
2421 		"%89 = OpLoad %6 %17\n"
2422 		"%90 = OpFMul %6 %88 %89\n"
2423 		"%91 = OpAccessChain %40 %83 %48 %39\n"
2424 		"%92 = OpLoad %25 %91\n"
2425 		"%93 = OpVectorTimesScalar %25 %92 %90\n"
2426 		"%94 = OpFAdd %25 %86 %93\n"
2427 		"%95 = OpLoad %6 %8\n"
2428 		"%96 = OpLoad %6 %17\n"
2429 		"%97 = OpFSub %6 %28 %96\n"
2430 		"%98 = OpFMul %6 %95 %97\n"
2431 		"%99 = OpAccessChain %40 %83 %57 %39\n"
2432 		"%100 = OpLoad %25 %99\n"
2433 		"%101 = OpVectorTimesScalar %25 %100 %98\n"
2434 		"%102 = OpFAdd %25 %94 %101\n"
2435 		"%103 = OpLoad %6 %8\n"
2436 		"%104 = OpLoad %6 %17\n"
2437 		"%105 = OpFMul %6 %103 %104\n"
2438 		"%106 = OpAccessChain %40 %83 %65 %39\n"
2439 		"%107 = OpLoad %25 %106\n"
2440 		"%108 = OpVectorTimesScalar %25 %107 %105\n"
2441 		"%109 = OpFAdd %25 %102 %108\n"
2442 		"%110 = OpAccessChain %26 %74 %39\n"
2443 		"OpStore %110 %109\n"
2444 		"%111 = OpLoad %6 %8\n"
2445 		"%112 = OpFSub %6 %28 %111\n"
2446 		"%113 = OpLoad %6 %17\n"
2447 		"%114 = OpFSub %6 %28 %113\n"
2448 		"%115 = OpFMul %6 %112 %114\n"
2449 		"%117 = OpAccessChain %116 %83 %39 %48\n"
2450 		"%118 = OpLoad %71 %117\n"
2451 		"%119 = OpMatrixTimesScalar %71 %118 %115\n"
2452 		"%120 = OpLoad %6 %8\n"
2453 		"%121 = OpFSub %6 %28 %120\n"
2454 		"%122 = OpLoad %6 %17\n"
2455 		"%123 = OpFMul %6 %121 %122\n"
2456 		"%124 = OpAccessChain %116 %83 %48 %48\n"
2457 		"%125 = OpLoad %71 %124\n"
2458 		"%126 = OpMatrixTimesScalar %71 %125 %123\n"
2459 		"%127 = OpCompositeExtract %70 %119 0\n"
2460 		"%128 = OpCompositeExtract %70 %126 0\n"
2461 		"%129 = OpFAdd %70 %127 %128\n"
2462 		"%130 = OpCompositeExtract %70 %119 1\n"
2463 		"%131 = OpCompositeExtract %70 %126 1\n"
2464 		"%132 = OpFAdd %70 %130 %131\n"
2465 		"%133 = OpCompositeConstruct %71 %129 %132\n"
2466 		"%134 = OpLoad %6 %8\n"
2467 		"%135 = OpLoad %6 %17\n"
2468 		"%136 = OpFSub %6 %28 %135\n"
2469 		"%137 = OpFMul %6 %134 %136\n"
2470 		"%138 = OpAccessChain %116 %83 %57 %48\n"
2471 		"%139 = OpLoad %71 %138\n"
2472 		"%140 = OpMatrixTimesScalar %71 %139 %137\n"
2473 		"%141 = OpCompositeExtract %70 %133 0\n"
2474 		"%142 = OpCompositeExtract %70 %140 0\n"
2475 		"%143 = OpFAdd %70 %141 %142\n"
2476 		"%144 = OpCompositeExtract %70 %133 1\n"
2477 		"%145 = OpCompositeExtract %70 %140 1\n"
2478 		"%146 = OpFAdd %70 %144 %145\n"
2479 		"%147 = OpCompositeConstruct %71 %143 %146\n"
2480 		"%148 = OpLoad %6 %8\n"
2481 		"%149 = OpLoad %6 %17\n"
2482 		"%150 = OpFMul %6 %148 %149\n"
2483 		"%151 = OpAccessChain %116 %83 %65 %48\n"
2484 		"%152 = OpLoad %71 %151\n"
2485 		"%153 = OpMatrixTimesScalar %71 %152 %150\n"
2486 		"%154 = OpCompositeExtract %70 %147 0\n"
2487 		"%155 = OpCompositeExtract %70 %153 0\n"
2488 		"%156 = OpFAdd %70 %154 %155\n"
2489 		"%157 = OpCompositeExtract %70 %147 1\n"
2490 		"%158 = OpCompositeExtract %70 %153 1\n"
2491 		"%159 = OpFAdd %70 %157 %158\n"
2492 		"%160 = OpCompositeConstruct %71 %156 %159\n"
2493 		"%162 = OpAccessChain %161 %74 %48\n"
2494 		"OpStore %162 %160\n"
2495 		"%167 = OpLoad %6 %8\n"
2496 		"%168 = OpFSub %6 %28 %167\n"
2497 		"%169 = OpLoad %6 %17\n"
2498 		"%170 = OpFSub %6 %28 %169\n"
2499 		"%171 = OpFMul %6 %168 %170\n"
2500 		"%176 = OpAccessChain %40 %175 %39 %39\n"
2501 		"%177 = OpLoad %25 %176\n"
2502 		"%178 = OpVectorTimesScalar %25 %177 %171\n"
2503 		"%179 = OpLoad %6 %8\n"
2504 		"%180 = OpFSub %6 %28 %179\n"
2505 		"%181 = OpLoad %6 %17\n"
2506 		"%182 = OpFMul %6 %180 %181\n"
2507 		"%183 = OpAccessChain %40 %175 %48 %39\n"
2508 		"%184 = OpLoad %25 %183\n"
2509 		"%185 = OpVectorTimesScalar %25 %184 %182\n"
2510 		"%186 = OpFAdd %25 %178 %185\n"
2511 		"%187 = OpLoad %6 %8\n"
2512 		"%188 = OpLoad %6 %17\n"
2513 		"%189 = OpFSub %6 %28 %188\n"
2514 		"%190 = OpFMul %6 %187 %189\n"
2515 		"%191 = OpAccessChain %40 %175 %57 %39\n"
2516 		"%192 = OpLoad %25 %191\n"
2517 		"%193 = OpVectorTimesScalar %25 %192 %190\n"
2518 		"%194 = OpFAdd %25 %186 %193\n"
2519 		"%195 = OpLoad %6 %8\n"
2520 		"%196 = OpLoad %6 %17\n"
2521 		"%197 = OpFMul %6 %195 %196\n"
2522 		"%198 = OpAccessChain %40 %175 %65 %39\n"
2523 		"%199 = OpLoad %25 %198\n"
2524 		"%200 = OpVectorTimesScalar %25 %199 %197\n"
2525 		"%201 = OpFAdd %25 %194 %200\n"
2526 		"%202 = OpAccessChain %26 %166 %39\n"
2527 		"OpStore %202 %201\n"
2528 		"OpReturn\n"
2529 		"OpFunctionEnd\n";
2530 		programCollection.spirvAsmSources.add("tessellation_control") << tessellationControlSource;
2531 		programCollection.spirvAsmSources.add("tessellation_evaluation") << tessellationEvaluationSource;
2532 	}
2533 	{
2534 
2535 		/*#version 450
2536 		layout(triangles) in;
2537 		layout(triangle_strip, max_vertices = 3) out;
2538 		layout(location = 0) in vec4		in_color[];
2539 		layout(location = 1) in ColorData
2540 		{
2541 		  vec4 colorVec;
2542 		  mat2 colorMat;
2543 		} inData[];
2544 		layout(location = 0) out vec4		out_color;
2545 		layout(location = 1) out ColorData
2546 		{
2547 		  vec4 colorVec;
2548 		  mat2 colorMat;
2549 		} outData;
2550 		void main (void)
2551 		{
2552 			out_color = in_color[0];
2553 			outData.colorVec = inData[0].colorVec;
2554 			outData.colorMat = inData[0].colorMat;
2555 			gl_Position = gl_in[0].gl_Position;
2556 			EmitVertex();
2557 			out_color = in_color[1];
2558 			outData.colorVec = inData[1].colorVec;
2559 			outData.colorMat = inData[1].colorMat;
2560 			gl_Position = gl_in[1].gl_Position;
2561 			EmitVertex();
2562 			out_color = in_color[2];
2563 			outData.colorVec = inData[2].colorVec;
2564 			outData.colorMat = inData[2].colorMat;
2565 			gl_Position = gl_in[2].gl_Position;
2566 			EmitVertex();
2567 			EndPrimitive();
2568 		}*/
2569 		const string geometrySource =
2570 		"; SPIR-V\n"
2571 		"; Version: 1.3\n"
2572 		"; Generator: Khronos Glslang Reference Front End; 2\n"
2573 		"; Bound: 73\n"
2574 		"; Schema: 0\n"
2575 		"OpCapability Geometry\n"
2576 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2577 		"OpMemoryModel Logical GLSL450\n"
2578 		"OpEntryPoint Geometry %4 \"main\" %color_out %color_in %24 %28 %42 %46\n"
2579 		"OpExecutionMode %4 Triangles\n"
2580 		"OpExecutionMode %4 Invocations 1\n"
2581 		"OpExecutionMode %4 OutputTriangleStrip\n"
2582 		"OpExecutionMode %4 OutputVertices 3\n"
2583 		"OpDecorate %color_out Location 0\n"
2584 		"OpDecorate %color_in Location 0\n"
2585 		"OpDecorate %block_out Block\n"
2586 		"OpDecorate %24 Location 1\n"
2587 		"OpDecorate %block_in Block\n"
2588 		"OpDecorate %28 Location 1\n"
2589 		+decorations[0].others+
2590 		"OpMemberDecorate %40 0 BuiltIn Position\n"
2591 		"OpMemberDecorate %40 1 BuiltIn PointSize\n"
2592 		"OpMemberDecorate %40 2 BuiltIn ClipDistance\n"
2593 		"OpMemberDecorate %40 3 BuiltIn CullDistance\n"
2594 		"OpDecorate %40 Block\n"
2595 		"OpMemberDecorate %43 0 BuiltIn Position\n"
2596 		"OpMemberDecorate %43 1 BuiltIn PointSize\n"
2597 		"OpMemberDecorate %43 2 BuiltIn ClipDistance\n"
2598 		"OpMemberDecorate %43 3 BuiltIn CullDistance\n"
2599 		"OpDecorate %43 Block\n"
2600 		"%2 = OpTypeVoid\n"
2601 		"%3 = OpTypeFunction %2\n"
2602 		"%6 = OpTypeFloat 32\n"
2603 		"%7 = OpTypeVector %6 4\n"
2604 		"%8 = OpTypePointer Output %7\n"
2605 		"%color_out = OpVariable %8 Output\n"
2606 		"%10 = OpTypeInt 32 0\n"
2607 		"%11 = OpConstant %10 3\n"
2608 		"%12 = OpTypeArray %7 %11\n"
2609 		"%13 = OpTypePointer Input %12\n"
2610 		"%color_in = OpVariable %13 Input\n"
2611 		"%15 = OpTypeInt 32 1\n"
2612 		"%16 = OpConstant %15 0\n"
2613 		"%17 = OpTypePointer Input %7\n"
2614 		"%20 = OpTypeVector %6 2\n"
2615 		"%21 = OpTypeMatrix %20 2\n"
2616 		"%block_out = OpTypeStruct %7 %21\n"
2617 		"%23 = OpTypePointer Output %block_out\n"
2618 		"%24 = OpVariable %23 Output\n"
2619 		"%block_in = OpTypeStruct %7 %21\n"
2620 		"%26 = OpTypeArray %block_in %11\n"
2621 		"%27 = OpTypePointer Input %26\n"
2622 		"%28 = OpVariable %27 Input\n"
2623 		"%32 = OpConstant %15 1\n"
2624 		"%33 = OpTypePointer Input %21\n"
2625 		"%36 = OpTypePointer Output %21\n"
2626 		"%38 = OpConstant %10 1\n"
2627 		"%39 = OpTypeArray %6 %38\n"
2628 		"%40 = OpTypeStruct %7 %6 %39 %39\n"
2629 		"%41 = OpTypePointer Output %40\n"
2630 		"%42 = OpVariable %41 Output\n"
2631 		"%43 = OpTypeStruct %7 %6 %39 %39\n"
2632 		"%44 = OpTypeArray %43 %11\n"
2633 		"%45 = OpTypePointer Input %44\n"
2634 		"%46 = OpVariable %45 Input\n"
2635 		"%61 = OpConstant %15 2\n"
2636 		"%4 = OpFunction %2 None %3\n"
2637 		"%5 = OpLabel\n"
2638 		"%18 = OpAccessChain %17 %color_in %16\n"
2639 		"%19 = OpLoad %7 %18\n"
2640 		"OpStore %color_out %19\n"
2641 		"%29 = OpAccessChain %17 %28 %16 %16\n"
2642 		"%30 = OpLoad %7 %29\n"
2643 		"%31 = OpAccessChain %8 %24 %16\n"
2644 		"OpStore %31 %30\n"
2645 		"%34 = OpAccessChain %33 %28 %16 %32\n"
2646 		"%35 = OpLoad %21 %34\n"
2647 		"%37 = OpAccessChain %36 %24 %32\n"
2648 		"OpStore %37 %35\n"
2649 		"%47 = OpAccessChain %17 %46 %16 %16\n"
2650 		"%48 = OpLoad %7 %47\n"
2651 		"%49 = OpAccessChain %8 %42 %16\n"
2652 		"OpStore %49 %48\n"
2653 		"OpEmitVertex\n"
2654 		"%50 = OpAccessChain %17 %color_in %32\n"
2655 		"%51 = OpLoad %7 %50\n"
2656 		"OpStore %color_out %51\n"
2657 		"%52 = OpAccessChain %17 %28 %32 %16\n"
2658 		"%53 = OpLoad %7 %52\n"
2659 		"%54 = OpAccessChain %8 %24 %16\n"
2660 		"OpStore %54 %53\n"
2661 		"%55 = OpAccessChain %33 %28 %32 %32\n"
2662 		"%56 = OpLoad %21 %55\n"
2663 		"%57 = OpAccessChain %36 %24 %32\n"
2664 		"OpStore %57 %56\n"
2665 		"%58 = OpAccessChain %17 %46 %32 %16\n"
2666 		"%59 = OpLoad %7 %58\n"
2667 		"%60 = OpAccessChain %8 %42 %16\n"
2668 		"OpStore %60 %59\n"
2669 		"OpEmitVertex\n"
2670 		"%62 = OpAccessChain %17 %color_in %61\n"
2671 		"%63 = OpLoad %7 %62\n"
2672 		"OpStore %color_out %63\n"
2673 		"%64 = OpAccessChain %17 %28 %61 %16\n"
2674 		"%65 = OpLoad %7 %64\n"
2675 		"%66 = OpAccessChain %8 %24 %16\n"
2676 		"OpStore %66 %65\n"
2677 		"%67 = OpAccessChain %33 %28 %61 %32\n"
2678 		"%68 = OpLoad %21 %67\n"
2679 		"%69 = OpAccessChain %36 %24 %32\n"
2680 		"OpStore %69 %68\n"
2681 		"%70 = OpAccessChain %17 %46 %61 %16\n"
2682 		"%71 = OpLoad %7 %70\n"
2683 		"%72 = OpAccessChain %8 %42 %16\n"
2684 		"OpStore %72 %71\n"
2685 		"OpEmitVertex\n"
2686 		"OpEndPrimitive\n"
2687 		"OpReturn\n"
2688 		"OpFunctionEnd\n";
2689 		programCollection.spirvAsmSources.add("geometry") << geometrySource;
2690 	}
2691 }
2692 } // anonymous
2693 
createCrossStageInterfaceTests(tcu::TestContext & testCtx)2694 tcu::TestCaseGroup* createCrossStageInterfaceTests (tcu::TestContext& testCtx)
2695 {
2696 	de::MovePtr<tcu::TestCaseGroup>		testGroup(new tcu::TestCaseGroup(testCtx, "cross_stage", ""));
2697 	{
2698 		de::MovePtr<tcu::TestCaseGroup>		basicGroup(new tcu::TestCaseGroup(testCtx, "basic_type", ""));
2699 		de::MovePtr<tcu::TestCaseGroup>		interfaceGroup(new tcu::TestCaseGroup(testCtx, "interface_blocks", ""));
2700 		{
2701 			TestParameters parm(TEST_TYPE_FLAT,3);
2702 			for (int ndx = 0; ndx < CrossStageTestInstance::DECORATION_LAST; ++ndx)
2703 				parm.testOptions[ndx] = ndx;
2704 
2705 			basicGroup->addChild(new CrossStageBasicTestsCase(testCtx, "flat", "", parm));
2706 			interfaceGroup->addChild(new CrossStageInterfaceTestsCase(testCtx, "flat", "", parm));
2707 
2708 			parm.qualifier = TEST_TYPE_NOPERSPECTIVE;
2709 			basicGroup->addChild(new CrossStageBasicTestsCase(testCtx, "no_perspective", "", parm));
2710 			interfaceGroup->addChild(new CrossStageInterfaceTestsCase(testCtx, "no_perspective", "", parm));
2711 		}
2712 
2713 		{
2714 			TestParameters parm(TEST_TYPE_RELAXEDPRECISION,1);
2715 			parm.testOptions[0] = CrossStageTestInstance::DECORATION_IN_ALL_SHADERS;
2716 			basicGroup->addChild(new CrossStageBasicTestsCase(testCtx, "relaxedprecision", "", parm));
2717 			interfaceGroup->addChild(new CrossStageInterfaceTestsCase(testCtx, "relaxedprecision", "", parm));
2718 		}
2719 		testGroup->addChild(basicGroup.release());
2720 		testGroup->addChild(interfaceGroup.release());
2721 	}
2722 
2723 	return testGroup.release();
2724 }
2725 
2726 } // SpirVAssembly
2727 } // vkt
2728