1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2023 LunarG, Inc.
6  * Copyright (c) 2023 Nintendo
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Shader Object Misc Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktShaderObjectMiscTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkShaderObjectUtil.hpp"
30 #include "vktShaderObjectCreateUtil.hpp"
31 #include "vkBufferWithMemory.hpp"
32 #include "vkImageWithMemory.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 #include "vkBarrierUtil.hpp"
39 #include "deMath.hpp"
40 #include "vktCustomInstancesDevices.hpp"
41 #include "tcuCommandLine.hpp"
42 #include "tcuTextureUtil.hpp"
43 
44 namespace vkt
45 {
46 namespace ShaderObject
47 {
48 
49 namespace
50 {
51 
52 struct TestParams {
53 	bool blendEnabled[2];
54 	bool vertexInputBefore;
55 	bool vertexBuffersNullStride;
56 	deUint32 stride;
57 	bool destroyDescriptorSetLayout;
58 };
59 
findDSFormat(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physicalDevice)60 vk::VkFormat findDSFormat (const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physicalDevice)
61 {
62 	const vk::VkFormat dsFormats[] = {
63 		vk::VK_FORMAT_D24_UNORM_S8_UINT,
64 		vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
65 		vk::VK_FORMAT_D16_UNORM_S8_UINT,
66 	};
67 
68 	for (deUint32 i = 0; i < 3; ++i) {
69 		const vk::VkFormatProperties	formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, dsFormats[i]);
70 		if ((formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
71 			return dsFormats[i];
72 	}
73 	return vk::VK_FORMAT_UNDEFINED;
74 }
75 
76 class ShaderObjectMiscInstance : public vkt::TestInstance
77 {
78 public:
ShaderObjectMiscInstance(Context& context, const TestParams& params)79 							ShaderObjectMiscInstance	(Context& context, const TestParams& params)
80 														: vkt::TestInstance	(context)
81 														, m_params			(params)
82 														{}
~ShaderObjectMiscInstance(void)83 	virtual					~ShaderObjectMiscInstance	(void) {}
84 
85 	tcu::TestStatus			iterate						(void) override;
86 private:
87 	void					setVertexInput				(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const;
88 	void					bindVertexBuffers			(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize* stride, vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const;
89 	TestParams m_params;
90 };
91 
setVertexInput(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const92 void ShaderObjectMiscInstance::setVertexInput (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const
93 {
94 	vk::VkVertexInputBindingDescription2EXT bindingDescription = vk::initVulkanStructure();
95 	bindingDescription.binding = 0u;
96 	bindingDescription.stride = (deUint32)stride;
97 	bindingDescription.inputRate = vk::VK_VERTEX_INPUT_RATE_VERTEX;
98 	bindingDescription.divisor = 1u;
99 	vk::VkVertexInputAttributeDescription2EXT attributeDescription = vk::initVulkanStructure();
100 	attributeDescription.location = 0u;
101 	attributeDescription.binding = 0u;
102 	attributeDescription.format = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
103 	attributeDescription.offset = 0u;
104 	vk.cmdSetVertexInputEXT(cmdBuffer, 1u, &bindingDescription, 1u, &attributeDescription);
105 }
106 
bindVertexBuffers(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize* stride, vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const107 void ShaderObjectMiscInstance::bindVertexBuffers (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize* stride, vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const
108 {
109 	vk::VkDeviceSize offset = 0u;
110 	vk.cmdBindVertexBuffers2(cmdBuffer, 0u, 1u, &buffer, &offset, &bufferSize, stride);
111 }
112 
iterate(void)113 tcu::TestStatus ShaderObjectMiscInstance::iterate (void)
114 {
115 	const vk::VkInstance				instance					= m_context.getInstance();
116 	const vk::InstanceDriver			instanceDriver				(m_context.getPlatformInterface(), instance);
117 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
118 	const vk::VkDevice					device						= m_context.getDevice();
119 	const vk::VkQueue					queue						= m_context.getUniversalQueue();
120 	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
121 	auto&								alloc						= m_context.getDefaultAllocator();
122 	tcu::TestLog&						log							= m_context.getTestContext().getLog();
123 	const auto							deviceExtensions			= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
124 	const bool							tessellationSupported		= m_context.getDeviceFeatures().tessellationShader;
125 	const bool							geometrySupported			= m_context.getDeviceFeatures().geometryShader;
126 	const bool							taskSupported				= m_context.getMeshShaderFeatures().taskShader;
127 	const bool							meshSupported				= m_context.getMeshShaderFeatures().meshShader;
128 
129 	vk::VkFormat						colorAttachmentFormat		= vk::VK_FORMAT_R8G8B8A8_UNORM;
130 	const auto							subresourceRange			= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
131 	const auto							subresourceLayers			= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
132 	const vk::VkRect2D					renderArea					= vk::makeRect2D(0, 0, 32, 32);
133 	vk::VkExtent3D						extent						= { renderArea.extent.width, renderArea.extent.height, 1};
134 
135 	const vk::VkImageCreateInfo	createInfo =
136 	{
137 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
138 		DE_NULL,									// const void*				pNext
139 		0u,											// VkImageCreateFlags		flags
140 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
141 		colorAttachmentFormat,						// VkFormat					format
142 		{ 32, 32, 1 },								// VkExtent3D				extent
143 		1u,											// uint32_t					mipLevels
144 		1u,											// uint32_t					arrayLayers
145 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
146 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
147 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
148 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
149 		0,											// uint32_t					queueFamilyIndexCount
150 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
151 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
152 	};
153 
154 	const deUint32 colorAttachmentCount = 2;
155 
156 	std::vector<de::MovePtr<vk::ImageWithMemory>>	images		(colorAttachmentCount);
157 	std::vector<vk::Move<vk::VkImageView>>			imageViews	(colorAttachmentCount);
158 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
159 	{
160 		images[i] = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
161 		imageViews[i] = vk::makeImageView(vk, device, **images[i], vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
162 	}
163 
164 	const vk::VkDeviceSize				colorOutputBufferSize	= renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
165 	std::vector<de::MovePtr<vk::BufferWithMemory>>	colorOutputBuffers	(colorAttachmentCount);
166 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
167 	{
168 		colorOutputBuffers[i] = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
169 								vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
170 	}
171 
172 	const vk::Move<vk::VkCommandPool>	cmdPool					(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
173 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer				(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
174 
175 	vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout(
176 		vk::DescriptorSetLayoutBuilder()
177 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT)
178 		.build(vk, device));
179 
180 	const vk::Unique<vk::VkDescriptorPool>	descriptorPool(
181 		vk::DescriptorPoolBuilder()
182 		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
183 		.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
184 
185 	const vk::VkDeviceSize					bufferSizeBytes = sizeof(tcu::Vec4);
186 	const vk::Unique<vk::VkDescriptorSet>	descriptorSet	(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
187 	const vk::BufferWithMemory				inputBuffer		(vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
188 
189 	const vk::VkDescriptorBufferInfo		descriptorInfo = vk::makeDescriptorBufferInfo(*inputBuffer, 0ull, bufferSizeBytes);
190 	vk::DescriptorSetUpdateBuilder()
191 		.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
192 		.update(vk, device);
193 	const auto								pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
194 
195 	float* inputDataPtr = reinterpret_cast<float*>(inputBuffer.getAllocation().getHostPtr());
196 	memset(inputDataPtr, 0, bufferSizeBytes);
197 	for (deUint32 i = 0; i < 4; ++i)
198 		inputDataPtr[i] = 0.5f;
199 	flushAlloc(vk, device, inputBuffer.getAllocation());
200 
201 	const auto&							binaries				= m_context.getBinaryCollection();
202 	const auto							vertShader				= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("inputVert"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
203 	const auto							fragShader				= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("multiFrag"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
204 
205 	const vk::VkClearValue				clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
206 	vk::beginCommandBuffer(vk, *cmdBuffer);
207 
208 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
209 	{
210 		vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
211 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
212 	}
213 
214 	std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachments(colorAttachmentCount);
215 	vk::VkRenderingAttachmentInfoKHR colorAttachment
216 	{
217 		vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
218 		DE_NULL,												// const void*							pNext;
219 		VK_NULL_HANDLE,											// VkImageView							imageView;
220 		vk::VK_IMAGE_LAYOUT_GENERAL,							// VkImageLayout						imageLayout;
221 		vk::VK_RESOLVE_MODE_NONE,								// VkResolveModeFlagBits				resolveMode;
222 		DE_NULL,												// VkImageView							resolveImageView;
223 		vk::VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout						resolveImageLayout;
224 		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp					loadOp;
225 		vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
226 		clearValue												// VkClearValue							clearValue;
227 	};
228 
229 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
230 	{
231 		colorAttachment.imageView = *imageViews[i];
232 		colorAttachments[i] = colorAttachment;
233 	}
234 
235 	vk::VkRenderingInfoKHR renderingInfo
236 	{
237 		vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
238 		DE_NULL,
239 		(vk::VkRenderingFlags)0u,								// VkRenderingFlagsKHR					flags;
240 		renderArea,												// VkRect2D								renderArea;
241 		1u,														// deUint32								layerCount;
242 		0x0,													// deUint32								viewMask;
243 		(deUint32)colorAttachments.size(),						// deUint32								colorAttachmentCount;
244 		colorAttachments.data(),								// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
245 		DE_NULL,												// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
246 		DE_NULL,												// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
247 	};
248 
249 	const vk::VkDeviceSize				bufferSize	= 1024;
250 	de::MovePtr<vk::BufferWithMemory>	buffer		= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
251 		vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), vk::MemoryRequirement::HostVisible));
252 	float* dataPtr = reinterpret_cast<float*>(buffer->getAllocation().getHostPtr());
253 	memset(dataPtr, 0, bufferSize);
254 	for (deUint32 i = 0; i < 4; ++i)
255 	{
256 		dataPtr[i * (m_params.stride / sizeof(float)) + 0] = float(i & 1);
257 		dataPtr[i * (m_params.stride / sizeof(float)) + 1] = float((i >> 1) & 1);
258 		dataPtr[i * (m_params.stride / sizeof(float)) + 2] = 0.0f;
259 		dataPtr[i * (m_params.stride / sizeof(float)) + 3] = 1.0f;
260 	}
261 	flushAlloc(vk, device, buffer->getAllocation());
262 
263 	vk::Move<vk::VkDescriptorSetLayout> null;
264 	if (m_params.destroyDescriptorSetLayout)
265 		descriptorSetLayout = null;
266 
267 	vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
268 	vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, false);
269 
270 	vk::VkColorBlendEquationEXT		colorBlendEquation = {
271 		vk::VK_BLEND_FACTOR_ONE,				// VkBlendFactor	srcColorBlendFactor;
272 		vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor	dstColorBlendFactor;
273 		vk::VK_BLEND_OP_ADD,					// VkBlendOp		colorBlendOp;
274 		vk::VK_BLEND_FACTOR_ONE,				// VkBlendFactor	srcAlphaBlendFactor;
275 		vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor	dstAlphaBlendFactor;
276 		vk::VK_BLEND_OP_ADD,					// VkBlendOp		alphaBlendOp;
277 	};
278 	vk::VkColorComponentFlags		colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
279 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
280 	{
281 		vk::VkBool32 colorBlendEnable = m_params.blendEnabled[i] ? VK_TRUE : VK_FALSE;
282 		vk.cmdSetColorBlendEnableEXT(*cmdBuffer, i, 1u, &colorBlendEnable);
283 		if (m_params.blendEnabled[i])
284 		{
285 			vk.cmdSetColorBlendEquationEXT(*cmdBuffer, i, 1u, &colorBlendEquation);
286 		}
287 		vk.cmdSetColorWriteMaskEXT(*cmdBuffer, i, 1u, &colorWriteMask);
288 	}
289 	const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
290 	std::vector<vk::VkBool32> colorWriteEnables(properties.limits.maxColorAttachments);
291 	for (deUint32 i = 0; i < properties.limits.maxColorAttachments; ++i)
292 	{
293 		colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
294 	}
295 	vk.cmdSetColorWriteEnableEXT(*cmdBuffer, properties.limits.maxColorAttachments, colorWriteEnables.data());
296 
297 	if (m_params.vertexInputBefore)
298 		setVertexInput(vk, *cmdBuffer, m_params.vertexBuffersNullStride ? m_params.stride : 100);
299 
300 	vk::VkDeviceSize stride = m_params.stride;
301 	vk::VkDeviceSize* pStride = m_params.vertexBuffersNullStride ? DE_NULL : &stride;
302 	bindVertexBuffers(vk, *cmdBuffer, pStride, **buffer, bufferSize);
303 
304 	if (!m_params.vertexInputBefore)
305 		setVertexInput(vk, *cmdBuffer, m_params.stride);
306 
307 	vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
308 
309 	vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported);
310 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
311 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
312 
313 	vk::endRendering(vk, *cmdBuffer);
314 
315 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
316 	{
317 		vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
318 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
319 	}
320 
321 	const vk::VkBufferImageCopy	copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
322 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
323 		vk.cmdCopyImageToBuffer(*cmdBuffer, **images[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u, &copyRegion);
324 
325 	vk::endCommandBuffer(vk, *cmdBuffer);
326 
327 	vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
328 
329 	const deInt32			width			= renderArea.extent.width;
330 	const deInt32			height			= renderArea.extent.height;
331 	const float				threshold		= 1.0f / 256.0f;
332 	const deInt32			xOffset			= width / 8;
333 	const deInt32			yOffset			= height / 8;
334 	const tcu::Vec4			refColor1		= tcu::Vec4(0.75f, 0.75f, 0.75f, 0.75f);
335 	const tcu::Vec4			refColor2		= tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
336 	const tcu::Vec4			blackColor		= tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
337 
338 	for (deUint32 k = 0; k < colorAttachmentCount; ++k)
339 	{
340 		tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffers[k]->getAllocation().getHostPtr());
341 		for (deInt32 j = 0; j < height; ++j)
342 		{
343 			for (deInt32 i = 0; i < width; ++i)
344 			{
345 				const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
346 
347 				tcu::Vec4 expectedColor = blackColor;
348 				if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
349 				{
350 					if (m_params.blendEnabled[k])
351 						expectedColor = refColor1;
352 					else
353 						expectedColor = refColor2;
354 				}
355 
356 				if (deFloatAbs(color.x() - expectedColor.x()) > threshold || deFloatAbs(color.y() - expectedColor.y()) > threshold || deFloatAbs(color.z() - expectedColor.z()) > threshold || deFloatAbs(color.w() - expectedColor.w()) > threshold)
357 				{
358 					log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") was " << color << ", but expected color was " << expectedColor << tcu::TestLog::EndMessage;
359 					return tcu::TestStatus::fail("Fail");
360 				}
361 			}
362 		}
363 	}
364 
365 	return tcu::TestStatus::pass("Pass");
366 }
367 
368 class ShaderObjectMiscCase : public vkt::TestCase
369 {
370 public:
371 							ShaderObjectMiscCase	(tcu::TestContext& testCtx, const std::string& name, const TestParams& params)
372 													: vkt::TestCase		(testCtx, name)
373 													, m_params			(params)
374 													{}
375 	virtual					~ShaderObjectMiscCase	(void) {}
376 
377 	void					checkSupport			(vkt::Context& context) const override;
378 	virtual void			initPrograms			(vk::SourceCollections& programCollection) const override;
379 	TestInstance*			createInstance			(Context& context) const override { return new ShaderObjectMiscInstance(context, m_params); }
380 private:
381 	TestParams m_params;
382 };
383 
384 void ShaderObjectMiscCase::checkSupport (Context& context) const
385 {
386 	context.requireDeviceFunctionality("VK_EXT_shader_object");
387 }
388 
389 void ShaderObjectMiscCase::initPrograms (vk::SourceCollections& programCollection) const
390 {
391 	std::stringstream inputVert;
392 	std::stringstream multiFrag;
393 
394 	inputVert
395 		<< "#version 450\n"
396 		<< "layout(location = 0) in vec4 inPos;\n"
397 		<< "void main() {\n"
398 		<< "    gl_Position = vec4((inPos.xy - 0.5f) * 1.5f, inPos.zw);\n"
399 		<< "}\n";
400 
401 	multiFrag
402 		<< "#version 450\n"
403 		<< "layout(set=0, binding=0) readonly buffer inputBuf {\n"
404 		<< "    vec4 color;\n"
405 		<< "};\n"
406 		<< "layout (location=0) out vec4 outColor0;\n"
407 		<< "layout (location=1) out vec4 outColor1;\n"
408 		<< "void main() {\n"
409 		<< "    outColor0 = color;\n"
410 		<< "    outColor1 = color;\n"
411 		<< "}\n";
412 
413 	programCollection.glslSources.add("inputVert") << glu::VertexSource(inputVert.str());
414 	programCollection.glslSources.add("multiFrag") << glu::FragmentSource(multiFrag.str());
415 }
416 
417 de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface&	vk,
418 													vk::VkDevice				device,
419 													vk::VkQueue					queue,
420 													deUint32					queueFamilyIndex,
421 													vk::Allocator&				allocator,
422 													vk::VkImage					image,
423 													vk::VkFormat				format,
424 													const tcu::UVec2&			renderSize,
425 													vk::VkImageLayout			currentLayout)
426 {
427 	vk::Move<vk::VkBuffer>					buffer;
428 	de::MovePtr<vk::Allocation>				bufferAlloc;
429 	vk::Move<vk::VkCommandPool>				cmdPool;
430 	vk::Move<vk::VkCommandBuffer>			cmdBuffer;
431 
432 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
433 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
434 	const vk::VkImageAspectFlags	barrierAspect	= vk::VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT : (vk::VkImageAspectFlagBits)0);
435 
436 	switch (format)
437 	{
438 	case vk::VK_FORMAT_D16_UNORM:
439 	case vk::VK_FORMAT_D16_UNORM_S8_UINT:
440 		bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
441 		break;
442 	case vk::VK_FORMAT_D24_UNORM_S8_UINT:
443 	case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
444 		retFormat.type = tcu::TextureFormat::UNORM_INT24;
445 		// vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
446 		bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
447 		break;
448 	case vk::VK_FORMAT_D32_SFLOAT:
449 	case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
450 		bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
451 		break;
452 	default:
453 		TCU_FAIL("unrecognized format");
454 	}
455 
456 	const vk::VkDeviceSize			pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
457 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
458 
459 	// Create destination buffer
460 	{
461 		const vk::VkBufferCreateInfo bufferParams =
462 		{
463 			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
464 			DE_NULL,									// const void*			pNext;
465 			0u,											// VkBufferCreateFlags	flags;
466 			pixelDataSize,								// VkDeviceSize			size;
467 			vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
468 			vk::VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
469 			0u,											// deUint32				queueFamilyIndexCount;
470 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
471 		};
472 
473 		buffer		= createBuffer(vk, device, &bufferParams);
474 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
475 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
476 	}
477 
478 	// Create command pool and buffer
479 	cmdPool		= createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
480 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
481 
482 	beginCommandBuffer(vk, *cmdBuffer);
483 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, vk::VK_IMAGE_ASPECT_DEPTH_BIT);
484 	endCommandBuffer(vk, *cmdBuffer);
485 
486 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
487 
488 	// Read buffer data
489 	invalidateAlloc(vk, device, *bufferAlloc);
490 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
491 
492 	return resultLevel;
493 }
494 
495 de::MovePtr<tcu::TextureLevel> readStencilAttachment (const vk::DeviceInterface&	vk,
496 													  vk::VkDevice					device,
497 													  vk::VkQueue					queue,
498 													  deUint32						queueFamilyIndex,
499 													  vk::Allocator&				allocator,
500 													  vk::VkImage					image,
501 													  vk::VkFormat					format,
502 													  const tcu::UVec2&				renderSize,
503 													  vk::VkImageLayout				currentLayout)
504 {
505 	vk::Move<vk::VkBuffer>			buffer;
506 	de::MovePtr<vk::Allocation>		bufferAlloc;
507 	vk::Move<vk::VkCommandPool>		cmdPool;
508 	vk::Move<vk::VkCommandBuffer>	cmdBuffer;
509 
510 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
511 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
512 
513 	const vk::VkImageAspectFlags	barrierAspect	= vk::VK_IMAGE_ASPECT_STENCIL_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_DEPTH_BIT : (vk::VkImageAspectFlagBits)0);
514 	const vk::VkDeviceSize			pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
515 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
516 
517 	// Create destination buffer
518 	{
519 		const vk::VkBufferCreateInfo bufferParams =
520 		{
521 			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
522 			DE_NULL,									// const void*			pNext;
523 			0u,											// VkBufferCreateFlags	flags;
524 			pixelDataSize,								// VkDeviceSize			size;
525 			vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
526 			vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
527 			0u,											// deUint32				queueFamilyIndexCount;
528 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
529 		};
530 
531 		buffer		= createBuffer(vk, device, &bufferParams);
532 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
533 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
534 	}
535 
536 	// Create command pool and buffer
537 	cmdPool		= createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
538 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
539 
540 	beginCommandBuffer(vk, *cmdBuffer);
541 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, vk::VK_IMAGE_ASPECT_STENCIL_BIT);
542 	endCommandBuffer(vk, *cmdBuffer);
543 
544 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
545 
546 	// Read buffer data
547 	invalidateAlloc(vk, device, *bufferAlloc);
548 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
549 
550 	return resultLevel;
551 }
552 
553 struct StateTestParams {
554 	bool pipeline;
555 	bool meshShader;
556 	bool vertShader;
557 	bool tessShader;
558 	bool geomShader;
559 	bool fragShader;
560 	bool logicOp;
561 	bool alphaToOne;
562 	bool depthBounds;
563 	bool depthClamp;
564 	bool depthClip;
565 	bool depthClipControl;
566 	bool colorWrite;
567 	bool geometryStreams;
568 	bool discardRectangles;
569 	bool conservativeRasterization;
570 	bool rasterizerDiscardEnable;
571 	bool lines;
572 	bool sampleLocations;
573 	bool provokingVertex;
574 	bool lineRasterization;
575 	bool cull;
576 	bool stencilTestEnable;
577 	bool depthTestEnable;
578 	bool depthBiasEnable;
579 	bool depthBoundsTestEnable;
580 	bool logicOpEnable;
581 	bool colorBlendEnable;
582 	bool discardRectanglesEnable;
583 	bool sampleLocationsEnable;
584 	bool conservativeRasterizationOverestimate;
585 	bool stippledLineEnable;
586 	bool colorWriteEnable;
587 
588 	void reset()
589 	{
590 		logicOp = false;
591 		alphaToOne = false;
592 		depthBounds = false;
593 		depthClamp = false;
594 		depthClip = false;
595 		depthClipControl = false;
596 		colorWrite = true;
597 		geometryStreams = false;
598 		discardRectangles = false;
599 		conservativeRasterization = false;
600 		rasterizerDiscardEnable = false;
601 		lines = false;
602 		sampleLocations = false;
603 		provokingVertex = false;
604 		lineRasterization = false;
605 		cull = false;
606 		stencilTestEnable = false;
607 		depthTestEnable = false;
608 		depthBiasEnable = false;
609 		depthBoundsTestEnable = false;
610 		logicOpEnable = false;
611 		colorBlendEnable = false;
612 		discardRectanglesEnable = false;
613 		sampleLocationsEnable = false;
614 		conservativeRasterizationOverestimate = false;
615 		stippledLineEnable = false;
616 		colorWriteEnable = true;
617 	}
618 };
619 
620 class ShaderObjectStateInstance : public vkt::TestInstance
621 {
622 public:
623 							ShaderObjectStateInstance	(Context& context, const StateTestParams& testParams)
624 														: vkt::TestInstance	(context)
625 														, m_params			(testParams)
626 														{}
627 	virtual					~ShaderObjectStateInstance	(void) {}
628 
629 	tcu::TestStatus			iterate						(void) override;
630 
631 private:
632 	void createDevice									(void);
633 	std::vector<vk::VkDynamicState> getDynamicStates	(void) const;
634 	bool hasDynamicState						(const std::vector<vk::VkDynamicState> dynamicStates, const vk::VkDynamicState dynamicState);
635 	void setDynamicStates								(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer);
636 	bool isInsidePrimitive								(deUint32 i, deUint32 j, deUint32 width, deUint32 height);
637 
638 	vk::Move<vk::VkDevice>								m_customDevice;
639 	de::MovePtr<vk::DeviceDriver>						m_logicalDeviceInterface;
640 	vk::VkQueue											m_logicalDeviceQueue;
641 	const StateTestParams								m_params;
642 };
643 
644 void ShaderObjectStateInstance::createDevice (void)
645 {
646 	vk::VkPhysicalDeviceMeshShaderFeaturesEXT			meshShaderFeatuers			= vk::initVulkanStructure();
647 	vk::VkPhysicalDeviceColorWriteEnableFeaturesEXT		colorWriteEnableFeatures	= vk::initVulkanStructure();
648 	vk::VkPhysicalDeviceDepthClipControlFeaturesEXT		depthClipControlFeatures	= vk::initVulkanStructure();
649 	vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT		depthClipEnableFeatures		= vk::initVulkanStructure();
650 	vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT	transformFeedbackFeatures	= vk::initVulkanStructure();
651 	vk::VkPhysicalDeviceLineRasterizationFeaturesEXT	lineRasterizationFeatures	= vk::initVulkanStructure();
652 
653 	vk::VkPhysicalDeviceDynamicRenderingFeatures		dynamicRenderingFeatures	= m_context.getDynamicRenderingFeatures();
654 	vk::VkPhysicalDeviceShaderObjectFeaturesEXT			shaderObjectFeatures		= m_context.getShaderObjectFeaturesEXT();
655 
656 	vk::VkPhysicalDeviceExtendedDynamicStateFeaturesEXT		edsFeatures		= m_context.getExtendedDynamicStateFeaturesEXT();
657 	vk::VkPhysicalDeviceExtendedDynamicState2FeaturesEXT	eds2Features	= m_context.getExtendedDynamicState2FeaturesEXT();
658 	vk::VkPhysicalDeviceExtendedDynamicState3FeaturesEXT	eds3Features	= m_context.getExtendedDynamicState3FeaturesEXT();
659 	vk::VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT	viFeatures		= m_context.getVertexInputDynamicStateFeaturesEXT();
660 
661 	dynamicRenderingFeatures.pNext = DE_NULL;
662 	shaderObjectFeatures.pNext = DE_NULL;
663 	edsFeatures.pNext = DE_NULL;
664 	eds2Features.pNext = DE_NULL;
665 	eds3Features.pNext = DE_NULL;
666 	viFeatures.pNext = DE_NULL;
667 
668 	vk::VkPhysicalDeviceFeatures2						features2					= vk::initVulkanStructure();
669 	void* pNext = &dynamicRenderingFeatures;
670 
671 	const float										queuePriority					= 1.0f;
672 	std::vector<const char*>						deviceExtensions				= { "VK_KHR_dynamic_rendering" };
673 	if (m_params.pipeline)
674 	{
675 		const auto& deviceExts = m_context.getDeviceExtensions();
676 		if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state") != deviceExts.end())
677 		{
678 			deviceExtensions.push_back("VK_EXT_extended_dynamic_state");
679 			edsFeatures.pNext = pNext;
680 			pNext = &edsFeatures;
681 		}
682 		if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state2") != deviceExts.end())
683 		{
684 			deviceExtensions.push_back("VK_EXT_extended_dynamic_state2");
685 			eds2Features.pNext = pNext;
686 			pNext = &eds2Features;
687 		}
688 		if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state3") != deviceExts.end())
689 		{
690 			deviceExtensions.push_back("VK_EXT_extended_dynamic_state3");
691 			eds3Features.pNext = pNext;
692 			pNext = &eds3Features;
693 		}
694 		if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_vertex_input_dynamic_state") != deviceExts.end())
695 		{
696 			deviceExtensions.push_back("VK_EXT_vertex_input_dynamic_state");
697 			viFeatures.pNext = pNext;
698 			pNext = &viFeatures;
699 		}
700 	}
701 	else
702 	{
703 		deviceExtensions.push_back("VK_EXT_shader_object");
704 		dynamicRenderingFeatures.pNext = &shaderObjectFeatures;
705 	}
706 
707 	if (m_params.tessShader)
708 		features2.features.tessellationShader = VK_TRUE;
709 	if (m_params.geomShader)
710 		features2.features.geometryShader = VK_TRUE;
711 
712 	if (m_params.logicOp)
713 		features2.features.logicOp = VK_TRUE;
714 	if (m_params.alphaToOne)
715 		features2.features.alphaToOne = VK_TRUE;
716 	if (m_params.depthBounds)
717 		features2.features.depthBounds = VK_TRUE;
718 	if (m_params.depthClamp)
719 		features2.features.depthClamp = VK_TRUE;
720 	if (m_params.depthBiasEnable)
721 		features2.features.depthBiasClamp = VK_TRUE;
722 	if (m_params.depthClip)
723 	{
724 		depthClipEnableFeatures.pNext = pNext;
725 		pNext = &depthClipEnableFeatures;
726 		depthClipEnableFeatures.depthClipEnable = VK_TRUE;
727 		deviceExtensions.push_back("VK_EXT_depth_clip_enable");
728 	}
729 	if (m_params.depthClipControl)
730 	{
731 		depthClipControlFeatures.pNext = pNext;
732 		pNext = &depthClipControlFeatures;
733 		depthClipControlFeatures.depthClipControl = VK_TRUE;
734 		deviceExtensions.push_back("VK_EXT_depth_clip_control");
735 	}
736 	if (m_params.colorWrite)
737 	{
738 		colorWriteEnableFeatures.pNext = pNext;
739 		pNext = &colorWriteEnableFeatures;
740 		colorWriteEnableFeatures.colorWriteEnable = VK_TRUE;
741 		deviceExtensions.push_back("VK_EXT_color_write_enable");
742 	}
743 	if (m_params.geometryStreams)
744 	{
745 		transformFeedbackFeatures.pNext = pNext;
746 		pNext = &transformFeedbackFeatures;
747 		transformFeedbackFeatures.transformFeedback = VK_TRUE;
748 		transformFeedbackFeatures.geometryStreams = VK_TRUE;
749 		deviceExtensions.push_back("VK_EXT_transform_feedback");
750 	}
751 	if (m_params.sampleLocations)
752 		deviceExtensions.push_back("VK_EXT_sample_locations");
753 	if (m_params.discardRectangles)
754 		deviceExtensions.push_back("VK_EXT_discard_rectangles");
755 	if (m_params.conservativeRasterization)
756 		deviceExtensions.push_back("VK_EXT_conservative_rasterization");
757 	if (m_params.sampleLocations)
758 		deviceExtensions.push_back("VK_EXT_sample_locations");
759 	if (m_params.provokingVertex)
760 		deviceExtensions.push_back("VK_EXT_provoking_vertex");
761 	if (m_params.lineRasterization)
762 	{
763 		lineRasterizationFeatures.pNext = pNext;
764 		pNext = &lineRasterizationFeatures;
765 		lineRasterizationFeatures.rectangularLines = VK_TRUE;
766 		deviceExtensions.push_back("VK_EXT_line_rasterization");
767 	}
768 	if (m_params.meshShader)
769 	{
770 		meshShaderFeatuers.pNext = pNext;
771 		pNext = &meshShaderFeatuers;
772 		meshShaderFeatuers.meshShader = VK_TRUE;
773 		deviceExtensions.push_back("VK_EXT_mesh_shader");
774 	}
775 
776 	features2.pNext = pNext;
777 
778 	vk::VkDeviceQueueCreateInfo						queueInfo =
779 	{
780 		vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType					sType;
781 		DE_NULL,										// const void*						pNext;
782 		0u,												// VkDeviceQueueCreateFlags			flags;
783 		0u,												// deUint32							queueFamilyIndex;
784 		1u,												// deUint32							queueCount;
785 		&queuePriority									// const float*						pQueuePriorities;
786 	};
787 
788 	const vk::VkDeviceCreateInfo					deviceInfo =
789 	{
790 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// VkStructureType					sType;
791 		&features2,										// const void*						pNext;
792 		(vk::VkDeviceCreateFlags)0,						// VkDeviceCreateFlags				flags;
793 		1u,												// uint32_t							queueCreateInfoCount;
794 		&queueInfo,										// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
795 		0u,												// uint32_t							enabledLayerCount;
796 		DE_NULL,										// const char* const*				ppEnabledLayerNames;
797 		deUint32(deviceExtensions.size()),				// uint32_t							enabledExtensionCount;
798 		deviceExtensions.data(),						// const char* const*				ppEnabledExtensionNames;
799 		DE_NULL											// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
800 	};
801 
802 	m_customDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_context.getInstance(), m_context.getInstanceInterface(), m_context.getPhysicalDevice(), &deviceInfo);
803 	m_logicalDeviceInterface = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_customDevice, m_context.getUsedApiVersion()));
804 	m_logicalDeviceInterface->getDeviceQueue(*m_customDevice, m_context.getUniversalQueueFamilyIndex(), 0, &m_logicalDeviceQueue);
805 }
806 
807 std::vector<vk::VkDynamicState> ShaderObjectStateInstance::getDynamicStates (void) const
808 {
809 	const auto& edsFeatures		= m_context.getExtendedDynamicStateFeaturesEXT();
810 	const auto& eds2Features	= m_context.getExtendedDynamicState2FeaturesEXT();
811 	const auto& eds3Features	= m_context.getExtendedDynamicState3FeaturesEXT();
812 	const auto& viFeatures		= m_context.getVertexInputDynamicStateFeaturesEXT();
813 
814 	std::vector<vk::VkDynamicState> dynamicStates;
815 
816 	if (edsFeatures.extendedDynamicState)
817 	{
818 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
819 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
820 	}
821 
822 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_WIDTH);
823 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
824 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS);
825 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS);
826 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
827 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
828 	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE);
829 	if (edsFeatures.extendedDynamicState && !m_params.meshShader && !m_params.pipeline)
830 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE);
831 	if (edsFeatures.extendedDynamicState)
832 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE);
833 	if (edsFeatures.extendedDynamicState)
834 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE);
835 	if (edsFeatures.extendedDynamicState)
836 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP);
837 	if (edsFeatures.extendedDynamicState)
838 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE);
839 	if (edsFeatures.extendedDynamicState)
840 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE);
841 	if (edsFeatures.extendedDynamicState)
842 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE);
843 	if (edsFeatures.extendedDynamicState && !m_params.meshShader)
844 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY);
845 	if (edsFeatures.extendedDynamicState)
846 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP);
847 	if (edsFeatures.extendedDynamicState)
848 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE);
849 	if (eds2Features.extendedDynamicState2)
850 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
851 	if (eds2Features.extendedDynamicState2 && !m_params.meshShader)
852 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
853 	if (eds2Features.extendedDynamicState2)
854 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT);
855 	if (viFeatures.vertexInputDynamicState && !m_params.meshShader && !m_params.pipeline)
856 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
857 	if (eds2Features.extendedDynamicState2LogicOp)
858 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
859 	if (eds2Features.extendedDynamicState2PatchControlPoints && !m_params.meshShader)
860 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
861 	if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
862 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
863 	if (eds3Features.extendedDynamicState3DepthClampEnable)
864 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
865 	if (eds3Features.extendedDynamicState3PolygonMode)
866 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
867 	if (eds3Features.extendedDynamicState3RasterizationSamples)
868 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
869 	if (eds3Features.extendedDynamicState3SampleMask)
870 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
871 	if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
872 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
873 	if (eds3Features.extendedDynamicState3AlphaToOneEnable)
874 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
875 	if (eds3Features.extendedDynamicState3LogicOpEnable)
876 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
877 	if (eds3Features.extendedDynamicState3ColorBlendEnable)
878 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
879 	if (eds3Features.extendedDynamicState3ColorBlendEquation)
880 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
881 	if (eds3Features.extendedDynamicState3ColorWriteMask)
882 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
883 	if (eds3Features.extendedDynamicState3RasterizationStream && m_params.geometryStreams)
884 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
885 	if (m_params.discardRectangles)
886 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
887 	if (m_params.discardRectangles)
888 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
889 	if (m_params.discardRectangles)
890 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
891 	if (eds3Features.extendedDynamicState3ConservativeRasterizationMode && m_params.conservativeRasterization)
892 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
893 	if (eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize && m_params.conservativeRasterization)
894 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
895 	if (eds3Features.extendedDynamicState3DepthClipEnable && m_params.depthClip)
896 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
897 	if (eds3Features.extendedDynamicState3SampleLocationsEnable && m_params.sampleLocations)
898 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
899 	if (m_params.sampleLocations)
900 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
901 	if (eds3Features.extendedDynamicState3ProvokingVertexMode && m_params.provokingVertex)
902 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
903 	if (eds3Features.extendedDynamicState3LineRasterizationMode && m_params.lineRasterization)
904 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
905 	if (eds3Features.extendedDynamicState3LineStippleEnable && m_params.lineRasterization)
906 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
907 	if (m_params.lineRasterization)
908 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
909 	if (eds3Features.extendedDynamicState3DepthClipNegativeOneToOne && m_params.depthClipControl)
910 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
911 	if (m_params.colorWrite)
912 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
913 	return dynamicStates;
914 }
915 
916 bool ShaderObjectStateInstance::hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates, const vk::VkDynamicState dynamicState)
917 {
918 	if (!m_params.pipeline)
919 		return false;
920 	return std::find(dynamicStates.begin(), dynamicStates.end(), dynamicState) != dynamicStates.end();
921 }
922 
923 bool extensionEnabled (const std::vector<std::string>& deviceExtensions, const std::string& ext)
924 {
925 	return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
926 }
927 
928 void ShaderObjectStateInstance::setDynamicStates (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer)
929 {
930 	const auto dynamicStates		= getDynamicStates();
931 	const auto deviceExtensions		= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
932 
933 	vk::VkViewport viewport = { 0, 0, 32, 32, 0.0f, 1.0f, };
934 	if (m_params.depthClamp)
935 		viewport.maxDepth = 0.5f;
936 	if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT))
937 		vk.cmdSetViewportWithCount(cmdBuffer, 1u, &viewport);
938 	vk::VkRect2D scissor = { { 0, 0, }, { 32, 32, }, };
939 	if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT))
940 		vk.cmdSetScissorWithCount(cmdBuffer, 1u, &scissor);
941 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.lines) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_WIDTH))
942 		vk.cmdSetLineWidth(cmdBuffer, 1.0f);
943 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBiasEnable))
944 		vk.cmdSetDepthBias(cmdBuffer, 4.0f, 1.0f, 4.0f);
945 	else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS))
946 		vk.cmdSetDepthBias(cmdBuffer, 1.0f, 0.0f, 1.0f);
947 	float blendConstants[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
948 	if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.colorBlendEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS))
949 		vk.cmdSetBlendConstants(cmdBuffer, blendConstants);
950 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBoundsTestEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS))
951 		vk.cmdSetDepthBounds(cmdBuffer, 0.2f, 0.3f);
952 	vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
953 	vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
954 	vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
955 	if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
956 		vk.cmdBindVertexBuffers2(cmdBuffer, 0, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL);
957 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CULL_MODE))
958 		vk.cmdSetCullMode(cmdBuffer, m_params.cull ? vk::VK_CULL_MODE_FRONT_AND_BACK : vk::VK_CULL_MODE_NONE);
959 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBounds) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS))
960 		vk.cmdSetDepthBoundsTestEnable(cmdBuffer, m_params.depthBoundsTestEnable ? VK_TRUE : VK_FALSE);
961 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP))
962 		vk.cmdSetDepthCompareOp(cmdBuffer, vk::VK_COMPARE_OP_LESS);
963 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE))
964 		vk.cmdSetDepthTestEnable(cmdBuffer, VK_TRUE);
965 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE))
966 		vk.cmdSetDepthWriteEnable(cmdBuffer, VK_TRUE);
967 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && (m_params.cull || m_params.stencilTestEnable)) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_FRONT_FACE))
968 		vk.cmdSetFrontFace(cmdBuffer, vk::VK_FRONT_FACE_CLOCKWISE);
969 	if ((!m_params.pipeline && m_params.vertShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY))
970 	{
971 		if (m_params.tessShader)
972 			vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
973 		else if (m_params.lines)
974 			vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
975 		else
976 			vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
977 	}
978 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.stencilTestEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_OP))
979 		vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_GREATER);
980 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE))
981 		vk.cmdSetStencilTestEnable(cmdBuffer, m_params.stencilTestEnable ? VK_TRUE : VK_FALSE);
982 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE))
983 		vk.cmdSetDepthBiasEnable(cmdBuffer, m_params.depthBiasEnable ? VK_TRUE : VK_FALSE);
984 	if ((!m_params.pipeline && m_params.vertShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE))
985 		vk.cmdSetPrimitiveRestartEnable(cmdBuffer, VK_FALSE);
986 	if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE))
987 		vk.cmdSetRasterizerDiscardEnable(cmdBuffer, m_params.rasterizerDiscardEnable ? VK_TRUE : VK_FALSE);
988 	if ((!m_params.pipeline && m_params.vertShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
989 		if (extensionEnabled(deviceExtensions, "VK_EXT_shader_object") || extensionEnabled(deviceExtensions, "VK_EXT_vertex_input_dynamic_state"))
990 			vk.cmdSetVertexInputEXT(cmdBuffer, 0u, DE_NULL, 0u, DE_NULL);
991 	if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOpEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT))
992 		vk.cmdSetLogicOpEXT(cmdBuffer, vk::VK_LOGIC_OP_COPY);
993 	if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT))
994 		vk.cmdSetPatchControlPointsEXT(cmdBuffer, 4u);
995 	if ((!m_params.pipeline && m_params.tessShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT))
996 		vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, vk::VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT);
997 	if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthClamp)
998 		vk.cmdSetDepthClampEnableEXT(cmdBuffer, VK_TRUE);
999 	else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT))
1000 		vk.cmdSetDepthClampEnableEXT(cmdBuffer, m_params.depthClamp ? VK_TRUE : VK_FALSE);
1001 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT))
1002 		vk.cmdSetPolygonModeEXT(cmdBuffer, vk::VK_POLYGON_MODE_FILL);
1003 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT))
1004 		vk.cmdSetRasterizationSamplesEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT);
1005 	vk::VkSampleMask sampleMask = 0xFFFFFFFF;
1006 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT))
1007 		vk.cmdSetSampleMaskEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT, &sampleMask);
1008 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT))
1009 		vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, VK_FALSE);
1010 	if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.alphaToOne)
1011 		vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, VK_TRUE);
1012 	else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT))
1013 		vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, m_params.alphaToOne ? VK_TRUE : VK_FALSE);
1014 	if (!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOp)
1015 		vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1016 	else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT))
1017 		vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1018 	vk::VkBool32 colorBlendEnable = m_params.colorBlendEnable ? VK_TRUE : VK_FALSE;
1019 	if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT))
1020 		vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0u, 1u, &colorBlendEnable);
1021 	vk::VkColorBlendEquationEXT		colorBlendEquation = {
1022 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	srcColorBlendFactor;
1023 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	dstColorBlendFactor;
1024 		vk::VK_BLEND_OP_ADD,			// VkBlendOp		colorBlendOp;
1025 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	srcAlphaBlendFactor;
1026 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	dstAlphaBlendFactor;
1027 		vk::VK_BLEND_OP_ADD,			// VkBlendOp		alphaBlendOp;
1028 	};
1029 	if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT))
1030 		vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0u, 1u, &colorBlendEquation);
1031 	vk::VkColorComponentFlags		colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
1032 	if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT))
1033 		vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0u, 1u, &colorWriteMask);
1034 	if ((!m_params.pipeline && m_params.geomShader && m_params.geometryStreams) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT))
1035 		vk.cmdSetRasterizationStreamEXT(cmdBuffer, 0u);
1036 	if (m_params.discardRectangles)
1037 		vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, m_params.discardRectanglesEnable ? VK_TRUE : VK_FALSE);
1038 	if ((!m_params.pipeline && m_params.discardRectanglesEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT))
1039 		vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, vk::VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT);
1040 	if ((!m_params.pipeline && m_params.discardRectanglesEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT))
1041 		vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, 1u, &scissor);
1042 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT))
1043 		vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer, m_params.conservativeRasterizationOverestimate ? vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT : vk::VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT);
1044 	if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT))
1045 		vk.cmdSetExtraPrimitiveOverestimationSizeEXT(cmdBuffer, de::min(1.0f, m_context.getConservativeRasterizationPropertiesEXT().maxExtraPrimitiveOverestimationSize));
1046 	if ((!m_params.pipeline && m_params.depthClip) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT))
1047 		vk.cmdSetDepthClipEnableEXT(cmdBuffer, VK_TRUE);
1048 	if ((!m_params.pipeline && m_params.sampleLocations) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT))
1049 		vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, m_params.sampleLocationsEnable ? VK_TRUE : VK_FALSE);
1050 	vk::VkSampleLocationEXT sampleLocation = { 0.5f, 0.5f };
1051 	const vk::VkSampleLocationsInfoEXT sampleLocationsInfo =
1052 	{
1053 		vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,	// VkStructureType               sType;
1054 		DE_NULL,											// const void*                   pNext;
1055 		vk::VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits         sampleLocationsPerPixel;
1056 		{ 1u, 1u },											// VkExtent2D                    sampleLocationGridSize;
1057 		1,													// uint32_t                      sampleLocationsCount;
1058 		&sampleLocation,									// const VkSampleLocationEXT*    pSampleLocations;
1059 	};
1060 	if ((!m_params.pipeline && m_params.sampleLocations && m_params.sampleLocationsEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT))
1061 		vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocationsInfo);
1062 	if ((!m_params.pipeline && m_params.provokingVertex) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT))
1063 		vk.cmdSetProvokingVertexModeEXT(cmdBuffer, vk::VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
1064 	if (m_params.pipeline || (!m_params.rasterizerDiscardEnable && m_params.lineRasterization && m_params.lines))
1065 	{
1066 		if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT))
1067 			vk.cmdSetLineRasterizationModeEXT(cmdBuffer, vk::VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT);
1068 		if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT))
1069 			vk.cmdSetLineStippleEnableEXT(cmdBuffer, m_params.stippledLineEnable ? VK_TRUE : VK_FALSE);
1070 		if ((!m_params.pipeline && m_params.stippledLineEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT))
1071 			vk.cmdSetLineStippleEXT(cmdBuffer, 1u, 0x1);
1072 	}
1073 	if ((!m_params.pipeline && m_params.depthClipControl) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT))
1074 		vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, VK_TRUE);
1075 	vk::VkBool32 colorWriteEnable = m_params.colorWriteEnable ? VK_TRUE : VK_FALSE;
1076 	if ((!m_params.pipeline && m_params.colorWrite) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT))
1077 		vk.cmdSetColorWriteEnableEXT(cmdBuffer, 1u, &colorWriteEnable);
1078 }
1079 
1080 bool ShaderObjectStateInstance::isInsidePrimitive (deUint32 i, deUint32 j, deUint32 width, deUint32 height)
1081 {
1082 	deUint32	xOffset		= width / 4;
1083 	deUint32	yOffset		= height / 4;
1084 	if (m_params.tessShader)
1085 		xOffset /= 2;
1086 	if (m_params.geomShader)
1087 		yOffset /= 2;
1088 
1089 	bool inside = false;
1090 	if (m_params.lines)
1091 	{
1092 		if (m_params.stippledLineEnable)
1093 		{
1094 			if (m_params.tessShader && m_params.geomShader)
1095 				inside = (j == 4 && i == 3) || (j == 20 && i == 3);
1096 			else if (m_params.tessShader)
1097 				inside = (j == 8 && i == 3);
1098 			else if (m_params.geomShader)
1099 				inside = (j == 3 && i == 8) || (j == 27 && i == 8);
1100 			else
1101 				inside = (j == 7 && i == 8) || (j == 23 && i == 8);
1102 		}
1103 		else
1104 		{
1105 			if (m_params.tessShader && m_params.geomShader)
1106 				inside = m_params.lines && (i == 3 && (j >= 4 && j < 28));
1107 			else if (m_params.tessShader)
1108 				inside = m_params.lines && (i == 3 && (j >= 8 && j < 24));
1109 			else if (m_params.geomShader)
1110 				inside = m_params.lines && ((j == 3 || j == 27) && (i >= 8 && i < 24));
1111 			else
1112 				inside = m_params.lines && (i >= 8 && i < 24 && (j == 7 || j == 23));
1113 		}
1114 	}
1115 	else
1116 	{
1117 		inside = !m_params.lines && (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset);
1118 	}
1119 	return inside;
1120 }
1121 
1122 tcu::TestStatus ShaderObjectStateInstance::iterate (void)
1123 {
1124 	const vk::VkInstance				instance						= m_context.getInstance();
1125 	const vk::InstanceDriver			instanceDriver					(m_context.getPlatformInterface(), instance);
1126 	createDevice();
1127 	const vk::DeviceInterface&			vk								= *m_logicalDeviceInterface;
1128 	const vk::VkDevice					device							= *m_customDevice;
1129 	const deUint32						queueFamilyIndex				= m_context.getUniversalQueueFamilyIndex();
1130 	const vk::VkQueue					queue							= m_logicalDeviceQueue;
1131 	auto								alloctor						= de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(instanceDriver, m_context.getPhysicalDevice())));
1132 	auto&								alloc							= *alloctor;
1133 	const auto							deviceExtensions				= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1134 	const bool							tessellationSupported			= m_context.getDeviceFeatures().tessellationShader;
1135 	const bool							geometrySupported				= m_context.getDeviceFeatures().geometryShader;
1136 	tcu::TestLog&						log								= m_context.getTestContext().getLog();
1137 
1138 	vk::VkFormat						colorAttachmentFormat			= vk::VK_FORMAT_R8G8B8A8_UNORM;
1139 	vk::VkFormat						depthStencilAttachmentFormat	= findDSFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
1140 	const auto							subresourceRange				= makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1141 	const auto							subresourceLayers				= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1142 	auto								depthSubresourceRange			= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
1143 	const vk::VkRect2D					renderArea						= vk::makeRect2D(0, 0, 32, 32);
1144 	vk::VkExtent3D						extent							= { renderArea.extent.width, renderArea.extent.height, 1};
1145 
1146 	const bool							taskSupported					= m_context.getMeshShaderFeatures().taskShader;
1147 	const bool							meshSupported					= m_context.getMeshShaderFeatures().meshShader;
1148 
1149 	const vk::VkImageCreateInfo	createInfo =
1150 	{
1151 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
1152 		DE_NULL,									// const void*				pNext
1153 		0u,											// VkImageCreateFlags		flags
1154 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
1155 		colorAttachmentFormat,						// VkFormat					format
1156 		{ 32, 32, 1 },								// VkExtent3D				extent
1157 		1u,											// uint32_t					mipLevels
1158 		1u,											// uint32_t					arrayLayers
1159 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
1160 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
1161 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
1162 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
1163 		0,											// uint32_t					queueFamilyIndexCount
1164 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
1165 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
1166 	};
1167 
1168 	const vk::VkImageCreateInfo	depthCreateInfo =
1169 	{
1170 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
1171 		DE_NULL,									// const void*				pNext
1172 		0u,											// VkImageCreateFlags		flags
1173 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
1174 		depthStencilAttachmentFormat,				// VkFormat					format
1175 		{ 32, 32, 1 },								// VkExtent3D				extent
1176 		1u,											// uint32_t					mipLevels
1177 		1u,											// uint32_t					arrayLayers
1178 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
1179 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
1180 		vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
1181 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
1182 		0,											// uint32_t					queueFamilyIndexCount
1183 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
1184 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
1185 	};
1186 
1187 	de::MovePtr<vk::ImageWithMemory>	image						= de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
1188 	const auto							imageView					= vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
1189 
1190 	de::MovePtr<vk::ImageWithMemory>	depthImage					= de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any));
1191 	const auto							depthImageView				= vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D, depthStencilAttachmentFormat, depthSubresourceRange);
1192 
1193 	const vk::VkDeviceSize				colorOutputBufferSize		= renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
1194 	de::MovePtr<vk::BufferWithMemory>	colorOutputBuffer			= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
1195 		vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
1196 
1197 	const vk::Move<vk::VkCommandPool>	cmdPool						(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
1198 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer					(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1199 
1200 	const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
1201 		vk::DescriptorSetLayoutBuilder()
1202 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_ALL_GRAPHICS | vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1203 		.build(vk, device));
1204 
1205 	const vk::Unique<vk::VkDescriptorPool>	descriptorPool(
1206 		vk::DescriptorPoolBuilder()
1207 		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1208 		.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1209 
1210 	const vk::VkDeviceSize					bufferSizeBytes	= sizeof(deUint32) * 8;
1211 	const vk::Unique<vk::VkDescriptorSet>	descriptorSet	(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1212 	const vk::BufferWithMemory				outputBuffer	(vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
1213 
1214 	const vk::VkDescriptorBufferInfo		descriptorInfo	= vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1215 	vk::DescriptorSetUpdateBuilder()
1216 		.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1217 		.update(vk, device);
1218 
1219 	const auto								pipelineLayout	= makePipelineLayout(vk, device, *descriptorSetLayout);
1220 
1221 	const auto&								binaries		= m_context.getBinaryCollection();
1222 	vk::Move<vk::VkPipeline>				pipeline;
1223 	vk::Move<vk::VkShaderEXT>				meshShader;
1224 	vk::Move<vk::VkShaderEXT>				vertShader;
1225 	vk::Move<vk::VkShaderEXT>				tescShader;
1226 	vk::Move<vk::VkShaderEXT>				teseShader;
1227 	vk::Move<vk::VkShaderEXT>				geomShader;
1228 	vk::Move<vk::VkShaderEXT>				fragShader;
1229 
1230 	if (m_params.pipeline)
1231 	{
1232 		vk::Move<vk::VkShaderModule> meshShaderModule;
1233 		vk::Move<vk::VkShaderModule> vertShaderModule;
1234 		vk::Move<vk::VkShaderModule> tescShaderModule;
1235 		vk::Move<vk::VkShaderModule> teseShaderModule;
1236 		vk::Move<vk::VkShaderModule> geomShaderModule;
1237 		vk::Move<vk::VkShaderModule> fragShaderModule;
1238 		if (m_params.meshShader)
1239 			meshShaderModule = vk::createShaderModule(vk, device, binaries.get("mesh"));
1240 		if (m_params.vertShader)
1241 			vertShaderModule = vk::createShaderModule(vk, device, binaries.get("vert"));
1242 		if (m_params.tessShader)
1243 			tescShaderModule = vk::createShaderModule(vk, device, binaries.get("tesc"));
1244 		if (m_params.tessShader)
1245 			teseShaderModule = vk::createShaderModule(vk, device, binaries.get("tese"));
1246 		if (m_params.geomShader)
1247 			geomShaderModule = vk::createShaderModule(vk, device, binaries.get("geom"));
1248 		if (m_params.fragShader)
1249 			fragShaderModule = vk::createShaderModule(vk, device, binaries.get("frag"));
1250 
1251 		const vk::VkPipelineVertexInputStateCreateInfo		vertexInputState	=
1252 		{
1253 			vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
1254 			DE_NULL,														// const void*								pNext;
1255 			(vk::VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags	flags;
1256 			0u,																// deUint32									vertexBindingDescriptionCount;
1257 			DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
1258 			0u,																// deUint32									vertexAttributeDescriptionCount;
1259 			DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
1260 		};
1261 
1262 		vk::VkPrimitiveTopology topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1263 		if (m_params.tessShader)
1264 			topology = vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
1265 		else if (m_params.lines)
1266 			topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1267 
1268 		const vk::VkPipelineInputAssemblyStateCreateInfo	inputAssemblyState =
1269 		{
1270 			vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
1271 			DE_NULL,															// const void*								pNext;
1272 			(vk::VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags	flags;
1273 			topology,															// VkPrimitiveTopology						topology;
1274 			VK_FALSE															// VkBool32									primitiveRestartEnable;
1275 		};
1276 
1277 		const vk::VkPipelineTessellationStateCreateInfo		tessellationState =
1278 		{
1279 			vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	// VkStructureType									sType;
1280 			DE_NULL,														// const void*										pNext;
1281 			(vk::VkPipelineTessellationStateCreateFlags)0u,					// VkPipelineTessellationStateCreateFlags			flags;
1282 			4u																// deUint32											patchControlPoints;
1283 		};
1284 
1285 		const vk::VkPipelineRasterizationDepthClipStateCreateInfoEXT	depthClipState =
1286 		{
1287 			vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT,	// VkStructureType										sType;
1288 			DE_NULL,																		// const void*											pNext;
1289 			(vk::VkPipelineRasterizationDepthClipStateCreateFlagsEXT)0u,					// VkPipelineRasterizationDepthClipStateCreateFlagsEXT	flags;
1290 			m_params.depthClip																// VkBool32												depthClipEnable;
1291 		};
1292 
1293 		const vk::VkPipelineRasterizationStateCreateInfo	rasterizationState =
1294 		{
1295 			vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,				// VkStructureType							sType;
1296 			m_params.depthClip ? &depthClipState : DE_NULL,								// const void*								pNext;
1297 			(vk::VkPipelineRasterizationStateCreateFlags)0,								// VkPipelineRasterizationStateCreateFlags	flags;
1298 			m_params.depthClamp,														// VkBool32									depthClampEnable;
1299 			m_params.rasterizerDiscardEnable,											// VkBool32									rasterizerDiscardEnable;
1300 			vk::VK_POLYGON_MODE_FILL,													// VkPolygonMode							polygonMode;
1301 			m_params.cull ? (vk::VkCullModeFlags)vk::VK_CULL_MODE_FRONT_AND_BACK : (vk::VkCullModeFlags)vk::VK_CULL_MODE_NONE,	// VkCullModeFlags							cullMode;
1302 			vk::VK_FRONT_FACE_CLOCKWISE,												// VkFrontFace								frontFace;
1303 			m_params.depthBiasEnable ? VK_TRUE : VK_FALSE,								// VkBool32									depthBiasEnable;
1304 			0.0f,																		// float									depthBiasConstantFactor;
1305 			0.0f,																		// float									depthBiasClamp;
1306 			0.0f,																		// float									depthBiasSlopeFactor;
1307 			1.0f																		// float									lineWidth;
1308 		};
1309 
1310 		const vk::VkPipelineMultisampleStateCreateInfo		multisampleState =
1311 		{
1312 			vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType
1313 			DE_NULL,														// const void*								pNext
1314 			(vk::VkPipelineMultisampleStateCreateFlags)0u,					// VkPipelineMultisampleStateCreateFlags	flags
1315 			vk::VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples
1316 			VK_FALSE,														// VkBool32									sampleShadingEnable
1317 			1.0f,															// float									minSampleShading
1318 			DE_NULL,														// const VkSampleMask*						pSampleMask
1319 			VK_FALSE,														// VkBool32									alphaToCoverageEnable
1320 			m_params.alphaToOne ? VK_TRUE : VK_FALSE						// VkBool32									alphaToOneEnable
1321 		};
1322 
1323 
1324 		const vk::VkStencilOpState stencilOpState = vk::makeStencilOpState(
1325 			vk::VK_STENCIL_OP_KEEP,				// stencil fail
1326 			vk::VK_STENCIL_OP_KEEP,				// depth & stencil pass
1327 			vk::VK_STENCIL_OP_KEEP,				// depth only fail
1328 			vk::VK_COMPARE_OP_ALWAYS,			// compare op
1329 			0u,									// compare mask
1330 			0u,									// write mask
1331 			0u);								// reference
1332 
1333 		const vk::VkPipelineDepthStencilStateCreateInfo			depthStencilState
1334 		{
1335 			vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType                          sType
1336 			DE_NULL,														// const void*                              pNext
1337 			(vk::VkPipelineDepthStencilStateCreateFlags)0u,					// VkPipelineDepthStencilStateCreateFlags   flags
1338 			m_params.depthTestEnable ? VK_TRUE : VK_FALSE,					// VkBool32                                 depthTestEnable
1339 			VK_TRUE,														// VkBool32                                 depthWriteEnable
1340 			vk::VK_COMPARE_OP_LESS,											// VkCompareOp                              depthCompareOp
1341 			m_params.depthBoundsTestEnable ? VK_TRUE : VK_FALSE,			// VkBool32                                 depthBoundsTestEnable
1342 			m_params.stencilTestEnable ? VK_TRUE : VK_FALSE,				// VkBool32                                 stencilTestEnable
1343 			stencilOpState,													// VkStencilOpState                         front
1344 			stencilOpState,													// VkStencilOpState                         back
1345 			0.0f,															// float                                    minDepthBounds
1346 			1.0f,															// float                                    maxDepthBounds
1347 		};
1348 
1349 		const vk::VkPipelineColorBlendAttachmentState		colorBlendAttState =
1350 		{
1351 			m_params.colorBlendEnable ? VK_TRUE : VK_FALSE,					// VkBool32											blendEnable;
1352 			vk::VK_BLEND_FACTOR_ONE,										// VkBlendFactor									srcColorBlendFactor;
1353 			vk::VK_BLEND_FACTOR_ZERO,										// VkBlendFactor									dstColorBlendFactor;
1354 			vk::VK_BLEND_OP_ADD,											// VkBlendOp										colorBlendOp;
1355 			vk::VK_BLEND_FACTOR_ONE,										// VkBlendFactor									srcAlphaBlendFactor;
1356 			vk::VK_BLEND_FACTOR_ZERO,										// VkBlendFactor									dstAlphaBlendFactor;
1357 			vk::VK_BLEND_OP_ADD,											// VkBlendOp										alphaBlendOp;
1358 			vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
1359 			vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT,	// VkColorComponentFlags							colorWriteMask;
1360 		};
1361 
1362 		const deUint32							colorAttachmentCount	= 2;
1363 		const vk::VkPhysicalDeviceProperties	properties				= vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
1364 		std::vector<vk::VkBool32>				colorWriteEnables		(properties.limits.maxColorAttachments);
1365 		for (deUint32 i = 0; i < properties.limits.maxColorAttachments; ++i)
1366 		{
1367 			colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
1368 		}
1369 		const vk::VkPipelineColorWriteCreateInfoEXT			colorWriteState =
1370 		{
1371 			vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT,	// VkStructureType	sType;
1372 			DE_NULL,													// const void*		pNext;
1373 			(deUint32)colorWriteEnables.size(),							// uint32_t			attachmentCount;
1374 			colorWriteEnables.data()									// const VkBool32*	pColorWriteEnables;
1375 		};
1376 
1377 		const vk::VkPipelineColorBlendStateCreateInfo		colorBlendState =
1378 		{
1379 			vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType									sType;
1380 			m_params.colorWrite ? &colorWriteState : DE_NULL,				// const void*										pNext;
1381 			(vk::VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags				flags;
1382 			m_params.logicOpEnable ? VK_TRUE : VK_FALSE,					// VkBool32											logicOpEnable;
1383 			vk::VK_LOGIC_OP_COPY,											// VkLogicOp										logicOp;
1384 			1u,																// uint32_t											attachmentCount;
1385 			&colorBlendAttState,											// const VkPipelineColorBlendAttachmentState*		pAttachments;
1386 			{ 0.0f, 0.0f, 0.0f, 0.0f },										// float											blendConstants[4];
1387 		};
1388 
1389 		vk::VkViewport	viewport	= { 0, 0, 32, 32, 0.0f, 1.0f, };
1390 		vk::VkRect2D	scissor		= { { 0, 0, }, { 32, 32, }, };
1391 
1392 		const auto&		edsFeatures				= m_context.getExtendedDynamicStateFeaturesEXT();
1393 		deUint32		viewportAndScissorCount = edsFeatures.extendedDynamicState ? 0u : 1u;
1394 
1395 		const vk::VkPipelineViewportDepthClipControlCreateInfoEXT		depthClipControlState =
1396 		{
1397 			vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,	// VkStructureType	sType;
1398 			DE_NULL,																	// const void*		pNext;
1399 			VK_TRUE,																	// VkBool32			negativeOneToOne;
1400 		};
1401 
1402 		const vk::VkPipelineViewportStateCreateInfo						viewportState =
1403 		{
1404 			vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,		// VkStructureType									sType
1405 			m_params.depthClipControl ? &depthClipControlState : DE_NULL,	// const void*										pNext
1406 			(vk::VkPipelineViewportStateCreateFlags)0,						// VkPipelineViewportStateCreateFlags				flags
1407 			viewportAndScissorCount,										// deUint32											viewportCount
1408 			&viewport,														// const VkViewport*								pViewports
1409 			viewportAndScissorCount,										// deUint32											scissorCount
1410 			&scissor														// const VkRect2D*									pScissors
1411 		};
1412 
1413 		const auto											dynamicStates	= getDynamicStates();
1414 
1415 		const vk::VkPipelineDynamicStateCreateInfo			dynamicState	=
1416 		{
1417 			vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,		// VkStructureType								sType
1418 			DE_NULL,														// const void*									pNext
1419 			0u,																// VkPipelineDynamicStateCreateFlags			flags
1420 			(deUint32)dynamicStates.size(),									// deUint32										dynamicStateCount
1421 			dynamicStates.data(),											// const VkDynamicState*						pDynamicStates
1422 		};
1423 
1424 		const vk::VkPipelineRenderingCreateInfo					pipelineRenderingCreateInfo =
1425 		{
1426 			vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,	// VkStructureType	sType
1427 			DE_NULL,												// const void*		pNext
1428 			0u,														// uint32_t			viewMask
1429 			1u,														// uint32_t			colorAttachmentCount
1430 			&colorAttachmentFormat,									// const VkFormat*	pColorAttachmentFormats
1431 			depthStencilAttachmentFormat,							// VkFormat			depthAttachmentFormat
1432 			depthStencilAttachmentFormat,							// VkFormat			stencilAttachmentFormat
1433 		};
1434 
1435 		if (m_params.meshShader)
1436 			pipeline = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, VK_NULL_HANDLE, *meshShaderModule, *fragShaderModule, VK_NULL_HANDLE, {}, {}, 0u, &rasterizationState, &multisampleState, &depthStencilState, &colorBlendState, &dynamicState, 0u, &pipelineRenderingCreateInfo);
1437 		else
1438 			pipeline = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, *vertShaderModule, *tescShaderModule, *teseShaderModule, *geomShaderModule, *fragShaderModule, VK_NULL_HANDLE, 0u, &vertexInputState, &inputAssemblyState, &tessellationState, &viewportState, &rasterizationState, &multisampleState, &depthStencilState, &colorBlendState, &dynamicState, &pipelineRenderingCreateInfo);
1439 	}
1440 	else
1441 	{
1442 		if (m_params.meshShader)
1443 		{
1444 			auto meshShaderCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh"), tessellationSupported, geometrySupported, &*descriptorSetLayout);
1445 			meshShaderCreateInfo.flags = vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
1446 			meshShader = vk::createShader(vk, device, meshShaderCreateInfo);
1447 		}
1448 		if (m_params.vertShader)
1449 			vertShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1450 		if (m_params.tessShader)
1451 			tescShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1452 		if (m_params.tessShader)
1453 			teseShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1454 		if (m_params.geomShader)
1455 			geomShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1456 		if (m_params.fragShader)
1457 			fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1458 	}
1459 
1460 	const vk::VkDeviceSize				tfBufSize		= 4 * sizeof(tcu::Vec4);
1461 	const vk::VkBufferCreateInfo		tfBufCreateInfo = vk::makeBufferCreateInfo(tfBufSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vk::VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1462 	const vk::Move<vk::VkBuffer>		tfBuf			= createBuffer(vk, device, &tfBufCreateInfo);
1463 	const de::MovePtr<vk::Allocation>	tfBufAllocation	= alloc.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), vk::MemoryRequirement::HostVisible);
1464 	const vk::VkMemoryBarrier			tfMemoryBarrier	= vk::makeMemoryBarrier(vk::VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, vk::VK_ACCESS_HOST_READ_BIT);
1465 	vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset());
1466 
1467 	const vk::VkClearValue				clearValue		= vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
1468 	const vk::VkClearValue				clearDepthValue = vk::makeClearValueDepthStencil(1.0f, 0u);
1469 	vk::beginCommandBuffer(vk, *cmdBuffer);
1470 
1471 	vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
1472 
1473 	vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1474 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
1475 
1476 	vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1477 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preDepthImageBarrier);
1478 
1479 	vk::beginRendering(vk, *cmdBuffer, *imageView, *depthImageView, true, renderArea, clearValue, clearDepthValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1480 
1481 	if (m_params.pipeline)
1482 	{
1483 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1484 	}
1485 	else
1486 	{
1487 		if (m_params.meshShader)
1488 		{
1489 			vk::VkShaderStageFlagBits stages[] = {
1490 				vk::VK_SHADER_STAGE_MESH_BIT_EXT,
1491 				vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1492 			};
1493 			vk::VkShaderEXT shaders[] = {
1494 				*meshShader,
1495 				*fragShader,
1496 			};
1497 			vk::bindNullRasterizationShaders(vk, *cmdBuffer, m_context.getDeviceFeatures());
1498 			vk.cmdBindShadersEXT(*cmdBuffer, 2, stages, shaders);
1499 		}
1500 		else
1501 		{
1502 			vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
1503 		}
1504 	}
1505 	setDynamicStates(vk, *cmdBuffer);
1506 
1507 	if (m_params.geometryStreams)
1508 	{
1509 		vk::VkDeviceSize offset = 0u;
1510 		vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &offset, &tfBufSize);
1511 		vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1512 	}
1513 
1514 	bool secondDraw = !m_params.depthClamp && !m_params.depthClip;
1515 	if (m_params.meshShader)
1516 	{
1517 		if (secondDraw)
1518 			vk.cmdDrawMeshTasksEXT(*cmdBuffer, 2, 1, 1);
1519 		else
1520 			vk.cmdDrawMeshTasksEXT(*cmdBuffer, 1, 1, 1);
1521 	}
1522 	else
1523 	{
1524 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1525 		if (secondDraw)
1526 			vk.cmdDraw(*cmdBuffer, 4, 1, 0, 1);
1527 	}
1528 	if (m_params.geometryStreams)
1529 		vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1530 	vk::endRendering(vk, *cmdBuffer);
1531 
1532 	vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1533 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
1534 
1535 	vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1536 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postDepthImageBarrier);
1537 
1538 	vk::VkBufferMemoryBarrier bufferBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0u, bufferSizeBytes);
1539 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, &bufferBarrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
1540 
1541 	if (m_params.geometryStreams)
1542 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
1543 
1544 
1545 	const vk::VkBufferImageCopy	copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
1546 	vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
1547 
1548 	vk::endCommandBuffer(vk, *cmdBuffer);
1549 	vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1550 
1551 	tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
1552 
1553 	const deInt32			width		= resultBuffer.getWidth();
1554 	const deInt32			height		= resultBuffer.getHeight();
1555 	const float				threshold	= 1.0f / 256.0f;
1556 	tcu::Vec4				whiteColor	= tcu::Vec4(0.75f);
1557 	tcu::Vec4				blackColor	= tcu::Vec4(0.0f);
1558 
1559 	const vk::Allocation& outputBufferAllocation = outputBuffer.getAllocation();
1560 	invalidateAlloc(vk, device, outputBufferAllocation);
1561 
1562 	const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
1563 
1564 	if (m_params.geometryStreams)
1565 	{
1566 		invalidateAlloc(vk, device, *tfBufAllocation);
1567 		const float* tfData = static_cast<float*>(tfBufAllocation->getHostPtr());
1568 		deUint32 count = m_params.lines ? 2 : 3;
1569 		for (deUint32 i = 0; i < count; ++i)
1570 		{
1571 			for (deUint32 j = 0; j < 4; ++j)
1572 			{
1573 				if (tfData[i * 4 + j] != float(i + 1))
1574 				{
1575 					return tcu::TestStatus::fail("Fail");
1576 				}
1577 			}
1578 		}
1579 		return tcu::TestStatus::pass("Pass");
1580 	}
1581 
1582 	if (m_params.vertShader)
1583 	{
1584 		if (bufferPtr[0] != 1u)
1585 		{
1586 			log << tcu::TestLog::Message << "Buffer value at index 0 was expected to be 1, but was[" << bufferPtr[0] << tcu::TestLog::EndMessage;
1587 			return tcu::TestStatus::fail("Fail");
1588 		}
1589 	}
1590 
1591 	if (m_params.tessShader)
1592 	{
1593 		if (bufferPtr[1] != 2u)
1594 		{
1595 			log << tcu::TestLog::Message << "Buffer value at index 1 was expected to be 2, but was[" << bufferPtr[1] << tcu::TestLog::EndMessage;
1596 			return tcu::TestStatus::fail("Fail");
1597 		}
1598 		if (bufferPtr[2] != 3u)
1599 		{
1600 			log << tcu::TestLog::Message << "Buffer value at index 2 was expected to be 3, but was[" << bufferPtr[2] << tcu::TestLog::EndMessage;
1601 			return tcu::TestStatus::fail("Fail");
1602 		}
1603 	}
1604 
1605 	if (m_params.geomShader)
1606 	{
1607 		if (bufferPtr[3] != 4u)
1608 		{
1609 			log << tcu::TestLog::Message << "Buffer value at index 3 was expected to be 4, but was[" << bufferPtr[3] << tcu::TestLog::EndMessage;
1610 			return tcu::TestStatus::fail("Fail");
1611 		}
1612 	}
1613 
1614 	if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1615 	{
1616 		for (deInt32 j = 0; j < height; ++j)
1617 		{
1618 			for (deInt32 i = 0; i < width; ++i)
1619 			{
1620 				const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1621 
1622 				tcu::Vec4 expectedColor = blackColor;
1623 				bool inside = isInsidePrimitive(i, j, width, height);
1624 				if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1625 					continue;
1626 				if (inside && (!m_params.cull || m_params.lines) && (!m_params.colorWrite || m_params.colorWriteEnable))
1627 				{
1628 					if (!m_params.depthBoundsTestEnable && (!m_params.depthClip || i < 16) && !m_params.discardRectanglesEnable)
1629 					{
1630 						expectedColor = whiteColor;
1631 						if (m_params.alphaToOne)
1632 							expectedColor.w() = 1.0f;
1633 						if (m_params.colorBlendEnable && secondDraw && !m_params.logicOpEnable && !m_params.stencilTestEnable)
1634 							expectedColor = tcu::Vec4(1.0f);
1635 					}
1636 				}
1637 
1638 				if (deFloatAbs(color.x() - expectedColor.x()) > threshold || deFloatAbs(color.y() - expectedColor.y()) > threshold || deFloatAbs(color.z() - expectedColor.z()) > threshold || deFloatAbs(color.w() - expectedColor.w()) > threshold)
1639 				{
1640 					log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (" << expectedColor << "), but was (" << color << ")" << tcu::TestLog::EndMessage;
1641 					return tcu::TestStatus::fail("Fail");
1642 				}
1643 			}
1644 		}
1645 	}
1646 
1647 	if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1648 	{
1649 		const auto	depthBuffer = readDepthAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, depthStencilAttachmentFormat, tcu::UVec2(width, height), vk::VK_IMAGE_LAYOUT_GENERAL);
1650 		const auto	depthAccess = depthBuffer->getAccess();
1651 		const auto	stencilBuffer = readStencilAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, depthStencilAttachmentFormat, tcu::UVec2(width, height), vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1652 		const auto	stencilAccess = stencilBuffer->getAccess();
1653 		const float depthEpsilon = 0.02f;
1654 
1655 		for (deInt32 j = 0; j < height; ++j)
1656 		{
1657 			for (deInt32 i = 0; i < width; ++i)
1658 			{
1659 				const float depth = depthAccess.getPixDepth(i, j);
1660 				const int stencil = stencilAccess.getPixStencil(i, j);
1661 				bool inside = isInsidePrimitive(i, j, width, height);
1662 				if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1663 					continue;
1664 				if (inside && !m_params.depthBoundsTestEnable && !m_params.discardRectanglesEnable && (!m_params.cull || m_params.lines))
1665 				{
1666 					float depthMin = 0.4f - depthEpsilon;
1667 					float depthMax = 0.6f + depthEpsilon;
1668 					if (m_params.stencilTestEnable)
1669 					{
1670 						depthMin = 0.7f - depthEpsilon;
1671 						depthMax = 0.9f + depthEpsilon;
1672 					}
1673 					if (m_params.depthClamp)
1674 					{
1675 						depthMin = 0.35f - depthEpsilon;
1676 						depthMax = 0.45f + depthEpsilon;
1677 					}
1678 					if (m_params.depthClip)
1679 					{
1680 						depthMin = 0.9f - depthEpsilon;
1681 						depthMax = 1.0f + depthEpsilon;
1682 					}
1683 					if (m_params.depthClipControl)
1684 					{
1685 						depthMin = 0.7f - depthEpsilon;
1686 						depthMax = 1.0f + depthEpsilon;
1687 					}
1688 					if (m_params.depthBiasEnable)
1689 					{
1690 						if (m_params.lines)
1691 						{
1692 							depthMin += 0.004f;
1693 							depthMax += 0.004f;
1694 						}
1695 						else
1696 						{
1697 							depthMin += 0.03f;
1698 							depthMax += 0.03f;
1699 						}
1700 					}
1701 
1702 					if (depth < depthMin || depth > depthMax)
1703 					{
1704 						log << tcu::TestLog::Message << "Depth at (" << i << ", " << j << ") is expected to be between 0.4f and 0.6f, but was (" << depth << ")" << tcu::TestLog::EndMessage;
1705 						return tcu::TestStatus::fail("Fail");
1706 					}
1707 					if (m_params.stencilTestEnable && (!m_params.depthClip || i < 16))
1708 					{
1709 						if (stencil != 255)
1710 						{
1711 							log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j << ") is expected to be 0, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1712 							return tcu::TestStatus::fail("Fail");
1713 						}
1714 					}
1715 				}
1716 				else
1717 				{
1718 					if (deFloatAbs(depth - 1.0f) > depthEpsilon)
1719 					{
1720 						log << tcu::TestLog::Message << "Depth at (" << i << ", " << j << ") is expected to be 1.0f, but was (" << depth << ")" << tcu::TestLog::EndMessage;
1721 						return tcu::TestStatus::fail("Fail");
1722 					}
1723 					if (m_params.stencilTestEnable)
1724 					{
1725 						if (stencil != 0)
1726 						{
1727 							log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j << ") is expected to be 1, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1728 							return tcu::TestStatus::fail("Fail");
1729 						}
1730 					}
1731 				}
1732 			}
1733 		}
1734 	}
1735 
1736 	if (m_params.meshShader)
1737 	{
1738 		if (bufferPtr[4] != 5u)
1739 		{
1740 			log << tcu::TestLog::Message << "Buffer value at index 5 was expected to be 6, but was[" << bufferPtr[5] << tcu::TestLog::EndMessage;
1741 			return tcu::TestStatus::fail("Fail");
1742 		}
1743 	}
1744 
1745 	return tcu::TestStatus::pass("Pass");
1746 }
1747 
1748 class ShaderObjectStateCase : public vkt::TestCase
1749 {
1750 public:
1751 							ShaderObjectStateCase	(tcu::TestContext& testCtx, const std::string& name, const StateTestParams& testParams)
1752 													: vkt::TestCase		(testCtx, name)
1753 													, m_params			(testParams)
1754 													{}
1755 	virtual					~ShaderObjectStateCase	(void) {}
1756 
1757 	void					checkSupport			(vkt::Context& context) const override;
1758 	virtual void			initPrograms			(vk::SourceCollections& programCollection) const override;
1759 	TestInstance*			createInstance			(Context& context) const override { return new ShaderObjectStateInstance(context, m_params); }
1760 
1761 	const StateTestParams	m_params;
1762 };
1763 
1764 void ShaderObjectStateCase::checkSupport (Context& context) const
1765 {
1766 	const auto& edsFeatures = context.getExtendedDynamicStateFeaturesEXT();
1767 	const auto& eds2Features = context.getExtendedDynamicState2FeaturesEXT();
1768 	const auto& eds3Features = context.getExtendedDynamicState3FeaturesEXT();
1769 
1770 	const auto&						vki					= context.getInstanceInterface();
1771 	const auto						physicalDevice		= context.getPhysicalDevice();
1772 	if (findDSFormat(vki, physicalDevice) == vk::VK_FORMAT_UNDEFINED)
1773 		TCU_THROW(NotSupportedError, "Required depth/stencil format not supported");
1774 
1775 	if (!m_params.pipeline)
1776 		context.requireDeviceFunctionality("VK_EXT_shader_object");
1777 	else
1778 		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1779 
1780 	if (m_params.logicOp)
1781 	{
1782 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LOGIC_OP);
1783 		if (m_params.pipeline && !eds2Features.extendedDynamicState2LogicOp)
1784 			TCU_THROW(NotSupportedError, "extendedDynamicState2LogicOp not supported");
1785 	}
1786 	if (m_params.alphaToOne)
1787 	{
1788 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
1789 		if (m_params.pipeline && !eds3Features.extendedDynamicState3AlphaToOneEnable)
1790 			TCU_THROW(NotSupportedError, "extendedDynamicState3AlphaToOneEnable not supported");
1791 	}
1792 	if (m_params.depthBounds)
1793 	{
1794 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
1795 		if (m_params.pipeline && !edsFeatures.extendedDynamicState)
1796 			TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
1797 	}
1798 	if (m_params.depthClamp)
1799 	{
1800 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
1801 		if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClampEnable)
1802 			TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClampEnable not supported");
1803 	}
1804 	if (m_params.depthClip)
1805 	{
1806 		context.requireDeviceFunctionality("VK_EXT_depth_clip_enable");
1807 		if (!context.getDepthClipEnableFeaturesEXT().depthClipEnable)
1808 			TCU_THROW(NotSupportedError, "depthClipEnable not supported");
1809 		if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipEnable)
1810 			TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipEnable not supported");
1811 	}
1812 	if (m_params.depthClipControl)
1813 	{
1814 		context.requireDeviceFunctionality("VK_EXT_depth_clip_control");
1815 		if (!context.getDepthClipControlFeaturesEXT().depthClipControl)
1816 			TCU_THROW(NotSupportedError, "depthClipControl not supported");
1817 		if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
1818 			TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipNegativeOneToOne not supported");
1819 	}
1820 	if (m_params.colorWrite)
1821 	{
1822 		context.requireDeviceFunctionality("VK_EXT_color_write_enable");
1823 		if (!context.getColorWriteEnableFeaturesEXT().colorWriteEnable)
1824 			TCU_THROW(NotSupportedError, "colorWriteEnable not supported");
1825 	}
1826 	if (m_params.geometryStreams)
1827 	{
1828 		context.requireDeviceFunctionality("VK_EXT_transform_feedback");
1829 		if (!context.getTransformFeedbackFeaturesEXT().geometryStreams)
1830 			TCU_THROW(NotSupportedError, "geometryStreams not supported");
1831 		if (m_params.pipeline && !eds3Features.extendedDynamicState3RasterizationStream)
1832 			TCU_THROW(NotSupportedError, "extendedDynamicState3RasterizationStream not supported");
1833 	}
1834 	if (m_params.discardRectangles)
1835 	{
1836 		context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
1837 
1838 		deUint32									propertyCount = 0u;
1839 		std::vector<vk::VkExtensionProperties>		extensionsProperties;
1840 		context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL, &propertyCount, DE_NULL);
1841 		extensionsProperties.resize(propertyCount);
1842 		context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL, &propertyCount, extensionsProperties.data());
1843 
1844 		for (const auto& extProp : extensionsProperties)
1845 		{
1846 			if (strcmp(extProp.extensionName, "VK_EXT_discard_rectangles") == 0)
1847 			{
1848 				if (extProp.specVersion < 2)
1849 					TCU_THROW(NotSupportedError, "VK_EXT_discard_rectangles is version 1. Needs version 2 or higher");
1850 			}
1851 		}
1852 	}
1853 	if (m_params.conservativeRasterization)
1854 	{
1855 		context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
1856 		if (m_params.pipeline && !eds3Features.extendedDynamicState3ConservativeRasterizationMode)
1857 			TCU_THROW(NotSupportedError, "extendedDynamicState3ConservativeRasterizationMode not supported");
1858 	}
1859 	if (m_params.sampleLocations)
1860 	{
1861 		context.requireDeviceFunctionality("VK_EXT_sample_locations");
1862 		if (m_params.sampleLocationsEnable && (context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) == 0)
1863 			TCU_THROW(NotSupportedError, "VK_SAMPLE_COUNT_1_BIT not supported in sampleLocationSampleCounts");
1864 	}
1865 	if (m_params.provokingVertex)
1866 	{
1867 		context.requireDeviceFunctionality("VK_EXT_provoking_vertex");
1868 		if (m_params.pipeline && !eds3Features.extendedDynamicState3ProvokingVertexMode)
1869 			TCU_THROW(NotSupportedError, "extendedDynamicState3ProvokingVertexMode not supported");
1870 	}
1871 	if (m_params.lineRasterization)
1872 	{
1873 		context.requireDeviceFunctionality("VK_EXT_line_rasterization");
1874 		if (!context.getLineRasterizationFeaturesEXT().rectangularLines)
1875 			TCU_THROW(NotSupportedError, "rectangularLines not supported");
1876 		if (m_params.pipeline && !eds3Features.extendedDynamicState3LineRasterizationMode)
1877 			TCU_THROW(NotSupportedError, "extendedDynamicState3LineRasterizationMode not supported");
1878 		if (m_params.pipeline && !eds3Features.extendedDynamicState3LineStippleEnable)
1879 			TCU_THROW(NotSupportedError, "extendedDynamicState3LineStippleEnable not supported");
1880 		if (m_params.stippledLineEnable && !context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
1881 			TCU_THROW(NotSupportedError, "stippledRectangularLines not supported");
1882 	}
1883 	if (m_params.geomShader)
1884 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1885 	if (m_params.tessShader)
1886 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1887 	if (m_params.meshShader)
1888 	{
1889 		context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1890 		if (!context.getMeshShaderFeaturesEXT().meshShader)
1891 			TCU_THROW(NotSupportedError, "Mesh shaders not supported");
1892 	}
1893 	if (m_params.lines)
1894 	{
1895 		if (m_params.pipeline && !edsFeatures.extendedDynamicState)
1896 			TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
1897 	}
1898 	if (m_params.colorBlendEnable && m_params.pipeline)
1899 	{
1900 		context.requireDeviceFunctionality("VK_EXT_extended_dynamic_state3");
1901 		if (!eds3Features.extendedDynamicState3ColorBlendEnable)
1902 			TCU_THROW(NotSupportedError, "extendedDynamicState3ColorBlendEnable not supported");
1903 	}
1904 }
1905 
1906 void ShaderObjectStateCase::initPrograms (vk::SourceCollections& programCollection) const
1907 {
1908 	std::stringstream vert;
1909 	std::stringstream geom;
1910 	std::stringstream tesc;
1911 	std::stringstream tese;
1912 	std::stringstream frag;
1913 
1914 	vert
1915 		<< "#version 450\n"
1916 		<< "layout(binding = 0) buffer Output {\n"
1917 		<< "    uint values[8];\n"
1918 		<< "} buffer_out;\n\n"
1919 		<< "void main() {\n"
1920 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1)) - vec2(0.0001f);\n";
1921 	if (m_params.depthClip)
1922 		vert << "    float z = 0.9f;\n";
1923 	else
1924 		vert << "    float z = 0.7f;\n";
1925 	vert << "    if ((gl_VertexIndex & 1) > 0)\n"
1926 		<< "        z += 0.2f;\n"
1927 		<< "    if ((gl_InstanceIndex & 1) > 0)\n"
1928 		<< "        z -= 0.3f;\n"
1929 		<< "    gl_Position = vec4(pos - 0.5f, z, 1.0f);\n"
1930 		<< "	if (gl_VertexIndex == 0)\n"
1931 		<< "        buffer_out.values[0] = 1u;\n"
1932 		<< "}\n";
1933 
1934 	tesc
1935 		<< "#version 450\n"
1936 		<< "layout(vertices = 4) out;\n"
1937 		<< "layout(binding = 0) buffer Output {\n"
1938 		<< "    uint values[8];\n"
1939 		<< "} buffer_out;\n\n"
1940 		<< "void main (void)\n"
1941 		<< "{\n"
1942 		<< "    if (gl_InvocationID == 0) {\n"
1943 		<< "		gl_TessLevelInner[0] = 1.0;\n"
1944 		<< "		gl_TessLevelInner[1] = 1.0;\n"
1945 		<< "		gl_TessLevelOuter[0] = 1.0;\n"
1946 		<< "		gl_TessLevelOuter[1] = 1.0;\n"
1947 		<< "		gl_TessLevelOuter[2] = 1.0;\n"
1948 		<< "		gl_TessLevelOuter[3] = 1.0;\n"
1949 		<< "        buffer_out.values[1] = 2u;\n"
1950 		<< "	}\n"
1951 		<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1952 		<< "}\n";
1953 
1954 	tese
1955 		<< "#version 450\n";
1956 	if (m_params.lines)
1957 		tese << "layout(isolines, equal_spacing) in;\n";
1958 	else
1959 		tese << "layout(quads, equal_spacing) in;\n";
1960 	tese << "layout(binding = 0) buffer Output {\n"
1961 		<< "    uint values[8];\n"
1962 		<< "} buffer_out;\n\n"
1963 		<< "void main (void)\n"
1964 		<< "{\n"
1965 		<< "	float u = gl_TessCoord.x;\n"
1966 		<< "	float v = gl_TessCoord.y;\n"
1967 		<< "	float omu = 1.0f - u;\n"
1968 		<< "	float omv = 1.0f - v;\n"
1969 		<< "	gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1970 		<< "	gl_Position.x *= 1.5f;\n"
1971 		<< "    if (gl_PrimitiveID == 0u)\n"
1972 		<< "		buffer_out.values[2] = 3u;\n"
1973 		<< "}\n";
1974 
1975 	geom
1976 		<< "#version 450\n";
1977 	if (m_params.lines)
1978 		geom << "layout(lines) in;\n";
1979 	else
1980 		geom << "layout(triangles) in;\n";
1981 	if (m_params.lines)
1982 		geom << "layout(line_strip, max_vertices = 4) out;\n";
1983 	else
1984 		geom << "layout(triangle_strip, max_vertices = 4) out;\n";
1985 	if (m_params.geometryStreams)
1986 		geom << "layout(stream = 0, xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n";
1987 	geom << "layout(binding = 0) buffer Output {\n"
1988 		<< "    uint values[8];\n"
1989 		<< "} buffer_out;\n\n"
1990 		<< "void main(void)\n"
1991 		<< "{\n"
1992 		<< "    gl_Position = gl_in[0].gl_Position;\n"
1993 		<< "    gl_Position.y *= 1.5f;\n";
1994 	if (m_params.geometryStreams)
1995 		geom << "    out0 = vec4(1.0f);\n"
1996 			 << "    EmitStreamVertex(0);\n";
1997 	else
1998 		geom << "    EmitVertex();\n";
1999 	geom << "    gl_Position = gl_in[1].gl_Position;\n"
2000 		<< "    gl_Position.y *= 1.5f;\n";
2001 	if (m_params.geometryStreams)
2002 		geom << "    out0 = vec4(2.0f);\n"
2003 			 << "    EmitStreamVertex(0);\n";
2004 	else
2005 		geom << "    EmitVertex();\n";
2006 	if (!m_params.lines)
2007 	{
2008 		geom << "    gl_Position = gl_in[2].gl_Position;\n"
2009 			<< "    gl_Position.y *= 1.5f;\n";
2010 		if (m_params.geometryStreams)
2011 			geom << "    out0 = vec4(3.0f);\n"
2012 				 << "    EmitStreamVertex(0);\n";
2013 		else
2014 			geom << "    EmitVertex();\n";
2015 	}
2016 	if (m_params.geometryStreams)
2017 		geom << "    EndStreamPrimitive(0);\n";
2018 	else
2019 		geom << "    EndPrimitive();\n";
2020 	geom << "    buffer_out.values[3] = 4u;\n";
2021 	geom << "}\n";
2022 
2023 	frag
2024 		<< "#version 450\n"
2025 		<< "layout (location=0) out vec4 outColor;\n"
2026 		<< "void main() {\n"
2027 		<< "    outColor = vec4(0.75f);\n"
2028 		<< "}\n";
2029 
2030 	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2031 	programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2032 	programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2033 	programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2034 	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2035 
2036 	if (m_params.meshShader)
2037 	{
2038 		std::stringstream mesh;
2039 
2040 		mesh
2041 			<< "#version 460\n"
2042 			<< "#extension GL_EXT_mesh_shader : require\n"
2043 			<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2044 			<< "layout(max_vertices = 4) out;\n"
2045 			<< "layout(max_primitives = 2) out;\n";
2046 		if (m_params.lines)
2047 			mesh << "layout(lines) out;\n";
2048 		else
2049 			mesh << "layout(triangles) out;\n";
2050 		mesh
2051 			<< "layout(binding = 0) buffer Output {\n"
2052 			<< "    uint values[8];\n"
2053 			<< "} buffer_out;\n\n"
2054 			<< "void main() {\n"
2055 			<< "    SetMeshOutputsEXT(4u, 2u);\n";
2056 		if (m_params.depthClip)
2057 			mesh << "    float z = 0.9f;\n";
2058 		else
2059 			mesh << "    float z = 0.7f;\n";
2060 		mesh
2061 			<< "    if (gl_GlobalInvocationID.x == 1) z -= 0.3f;\n"
2062 			<< "    gl_MeshVerticesEXT[0].gl_Position = vec4(-0.5f, -0.5f, z, 1.0f);\n"
2063 			<< "    gl_MeshVerticesEXT[1].gl_Position = vec4(-0.5f, 0.5f, z, 1.0f);\n"
2064 			<< "    gl_MeshVerticesEXT[2].gl_Position = vec4(0.5f, -0.5f, z + 0.2f, 1.0f);\n"
2065 			<< "    gl_MeshVerticesEXT[3].gl_Position = vec4(0.5f, 0.5f, z + 0.2f, 1.0f);\n";
2066 		if (m_params.lines)
2067 			mesh << "    gl_PrimitiveLineIndicesEXT[0] = uvec2(0u, 2u);\n"
2068 				 << "    gl_PrimitiveLineIndicesEXT[1] = uvec2(1u, 3u);\n";
2069 		else
2070 			mesh << "    gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0u, 1u, 2u);\n"
2071 				 << "    gl_PrimitiveTriangleIndicesEXT[1] = uvec3(1u, 3u, 2u);\n";
2072 		mesh
2073 			<< "    buffer_out.values[4] = 5u;\n"
2074 			<< "}\n";
2075 
2076 		programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2077 	}
2078 }
2079 
2080 struct UnusedBuiltinParams
2081 {
2082 	bool linked;
2083 	vk::VkShaderStageFlagBits stage;
2084 	bool builtin;
2085 };
2086 
2087 enum TessellationSpacing
2088 {
2089 	EQUAL,
2090 	EVEN,
2091 	ODD,
2092 };
2093 
2094 struct TessellationModesParams
2095 {
2096 	deUint32 subdivision;
2097 	TessellationSpacing spacing;
2098 };
2099 
2100 class ShaderObjectUnusedBuiltinInstance : public vkt::TestInstance
2101 {
2102 public:
2103 							ShaderObjectUnusedBuiltinInstance	(Context& context, const UnusedBuiltinParams& params)
2104 																: vkt::TestInstance	(context)
2105 																, m_params			(params)
2106 																{}
2107 	virtual					~ShaderObjectUnusedBuiltinInstance	(void) {}
2108 
2109 	tcu::TestStatus			iterate								(void) override;
2110 private:
2111 	UnusedBuiltinParams m_params;
2112 };
2113 
2114 tcu::TestStatus ShaderObjectUnusedBuiltinInstance::iterate (void)
2115 {
2116 	const vk::VkInstance				instance					= m_context.getInstance();
2117 	const vk::InstanceDriver			instanceDriver				(m_context.getPlatformInterface(), instance);
2118 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
2119 	const vk::VkDevice					device						= m_context.getDevice();
2120 	const vk::VkQueue					queue						= m_context.getUniversalQueue();
2121 	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
2122 	auto&								alloc						= m_context.getDefaultAllocator();
2123 	tcu::TestLog&						log							= m_context.getTestContext().getLog();
2124 	const auto							deviceExtensions			= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2125 	const bool							tessellationSupported		= m_context.getDeviceFeatures().tessellationShader;
2126 	const bool							geometrySupported			= m_context.getDeviceFeatures().geometryShader;
2127 	const bool							taskSupported				= m_context.getMeshShaderFeatures().taskShader;
2128 	const bool							meshSupported				= m_context.getMeshShaderFeatures().meshShader;
2129 
2130 	vk::VkFormat						colorAttachmentFormat		= vk::VK_FORMAT_R8G8B8A8_UNORM;
2131 	const auto							subresourceRange			= makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2132 	const auto							subresourceLayers			= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2133 	const vk::VkRect2D					renderArea					= vk::makeRect2D(0, 0, 32, 32);
2134 	vk::VkExtent3D						extent						= { renderArea.extent.width, renderArea.extent.height, 1};
2135 
2136 	const vk::VkImageCreateInfo	createInfo =
2137 	{
2138 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2139 		DE_NULL,									// const void*				pNext
2140 		0u,											// VkImageCreateFlags		flags
2141 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2142 		colorAttachmentFormat,						// VkFormat					format
2143 		{ 32, 32, 1 },								// VkExtent3D				extent
2144 		1u,											// uint32_t					mipLevels
2145 		1u,											// uint32_t					arrayLayers
2146 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2147 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2148 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
2149 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2150 		0,											// uint32_t					queueFamilyIndexCount
2151 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
2152 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2153 	};
2154 
2155 	de::MovePtr<vk::ImageWithMemory>	image					= de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2156 	const auto							imageView				= vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2157 
2158 	const vk::VkDeviceSize				colorOutputBufferSize	= renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2159 	de::MovePtr<vk::BufferWithMemory>	colorOutputBuffer		= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2160 		vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
2161 
2162 	const auto&					binaries			= m_context.getBinaryCollection();
2163 	vk::VkShaderEXT				shaders[5];
2164 
2165 	vk::VkShaderCreateInfoEXT	shaderCreateInfos[5]
2166 	{
2167 		vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported),
2168 		vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported),
2169 		vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported),
2170 		vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported, geometrySupported),
2171 		vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported),
2172 	};
2173 
2174 	vk.createShadersEXT(device, 5u, shaderCreateInfos, DE_NULL, shaders);
2175 
2176 	if (m_params.linked)
2177 		for (auto& ci : shaderCreateInfos)
2178 			ci.flags |= vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT;
2179 
2180 	const vk::Move<vk::VkCommandPool>	cmdPool		(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2181 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer	(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2182 
2183 	vk::beginCommandBuffer(vk, *cmdBuffer);
2184 
2185 	vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2186 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
2187 
2188 	const vk::VkClearValue				clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
2189 	vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2190 
2191 	vk::bindGraphicsShaders(vk, *cmdBuffer, shaders[0], shaders[1], shaders[2], shaders[3], shaders[4], taskSupported, meshSupported);
2192 	vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2193 
2194 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2195 
2196 	vk::endRendering(vk, *cmdBuffer);
2197 
2198 	vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2199 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
2200 
2201 	const vk::VkBufferImageCopy	copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2202 	vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
2203 
2204 	vk::endCommandBuffer(vk, *cmdBuffer);
2205 	vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2206 
2207 	for (deUint32 i = 0u; i < 5u; ++i)
2208 		vk.destroyShaderEXT(device, shaders[i], DE_NULL);
2209 
2210 	tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
2211 
2212 	const tcu::Vec4			black		= tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2213 	const tcu::Vec4			white		= tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2214 	const deUint32			width		= resultBuffer.getWidth();
2215 	const deUint32			height		= resultBuffer.getHeight();
2216 	const deUint32			xOffset		= 4u;
2217 	const deUint32			yOffset		= 4u;
2218 
2219 	for (deUint32 j = 0; j < height; ++j)
2220 	{
2221 		for (deUint32 i = 0; i < width; ++i)
2222 		{
2223 			const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
2224 			if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
2225 			{
2226 				if (color != white)
2227 				{
2228 					log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2229 					return tcu::TestStatus::fail("Fail");
2230 				}
2231 			}
2232 			else
2233 			{
2234 				if (color != black)
2235 				{
2236 					log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2237 					return tcu::TestStatus::fail("Fail");
2238 				}
2239 			}
2240 		}
2241 	}
2242 
2243 	return tcu::TestStatus::pass("Pass");
2244 }
2245 
2246 class ShaderObjectUnusedBuiltinCase : public vkt::TestCase
2247 {
2248 public:
2249 							ShaderObjectUnusedBuiltinCase	(tcu::TestContext& testCtx, const std::string& name, const UnusedBuiltinParams& testParams)
2250 															: vkt::TestCase		(testCtx, name)
2251 															, m_params			(testParams)
2252 															{}
2253 	virtual					~ShaderObjectUnusedBuiltinCase	(void) {}
2254 
2255 	void					checkSupport					(vkt::Context& context) const override;
2256 	virtual void			initPrograms					(vk::SourceCollections& programCollection) const override;
2257 	TestInstance*			createInstance					(Context& context) const override { return new ShaderObjectUnusedBuiltinInstance(context, m_params); }
2258 private:
2259 	const UnusedBuiltinParams m_params;
2260 };
2261 
2262 void ShaderObjectUnusedBuiltinCase::checkSupport (vkt::Context& context) const
2263 {
2264 	context.requireDeviceFunctionality("VK_EXT_shader_object");
2265 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2266 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2267 }
2268 
2269 void ShaderObjectUnusedBuiltinCase::initPrograms (vk::SourceCollections& programCollection) const
2270 {
2271 	std::stringstream vert;
2272 	std::stringstream geom;
2273 	std::stringstream tesc;
2274 	std::stringstream tese;
2275 	std::stringstream frag;
2276 
2277 	vert
2278 		<< "#version 450\n";
2279 	if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT && !m_params.builtin)
2280 		vert << "layout(location = 0) out vec4 unused;\n";
2281 	vert
2282 		<< "void main() {\n"
2283 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
2284 		<< "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n";
2285 	if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT)
2286 	{
2287 		if (m_params.builtin)
2288 		{
2289 			vert << "    gl_PointSize = 16.0f;\n";
2290 			vert << "    gl_ClipDistance[0] = 2.0f;\n";
2291 		}
2292 		else
2293 		{
2294 			vert << "    unused = vec4(1.0f);\n";
2295 		}
2296 	}
2297 	vert << "}\n";
2298 
2299 	tesc
2300 		<< "#version 450\n"
2301 		<< "\n"
2302 		<< "layout(vertices = 4) out;\n";
2303 	if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT && !m_params.builtin)
2304 		tesc << "layout(location = 0) out vec4 unused[];\n";
2305 	tesc << "\n"
2306 		<< "void main (void)\n"
2307 		<< "{\n"
2308 		<< "    if (gl_InvocationID == 0) {\n"
2309 		<< "		gl_TessLevelInner[0] = 1.0;\n"
2310 		<< "		gl_TessLevelInner[1] = 1.0;\n"
2311 		<< "		gl_TessLevelOuter[0] = 1.0;\n"
2312 		<< "		gl_TessLevelOuter[1] = 1.0;\n"
2313 		<< "		gl_TessLevelOuter[2] = 1.0;\n"
2314 		<< "		gl_TessLevelOuter[3] = 1.0;\n"
2315 		<< "	}\n"
2316 		<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
2317 	if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2318 	{
2319 		if (m_params.builtin)
2320 		{
2321 			tesc << "    gl_out[gl_InvocationID].gl_PointSize = 16.0f;\n";
2322 			tesc << "    gl_out[gl_InvocationID].gl_ClipDistance[0] = 2.0f;\n";
2323 		}
2324 		else
2325 		{
2326 			tesc << "    unused[gl_InvocationID] = vec4(1.0f);\n";
2327 		}
2328 	}
2329 	tesc << "}\n";
2330 
2331 	tese
2332 		<< "#version 450\n"
2333 		<< "\n"
2334 		<< "layout(quads, equal_spacing) in;\n";
2335 	if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT && !m_params.builtin)
2336 		tese << "layout(location = 0) out vec4 unused;\n";
2337 	tese << "\n"
2338 		<< "void main (void)\n"
2339 		<< "{\n"
2340 		<< "	float u = gl_TessCoord.x;\n"
2341 		<< "	float v = gl_TessCoord.y;\n"
2342 		<< "	float omu = 1.0f - u;\n"
2343 		<< "	float omv = 1.0f - v;\n"
2344 		<< "	gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2345 		<< "	gl_Position.x *= 1.5f;\n";
2346 	if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2347 	{
2348 		if (m_params.builtin)
2349 		{
2350 			tese << "    gl_PointSize = 16.0f;\n";
2351 			tese << "    gl_ClipDistance[0] = 2.0f;\n";
2352 		}
2353 		else
2354 		{
2355 			tese << "    unused = vec4(1.0f);\n";
2356 		}
2357 	}
2358 	tese << "}\n";
2359 
2360 	geom
2361 		<< "#version 450\n"
2362 		<< "layout(triangles) in;\n"
2363 		<< "layout(triangle_strip, max_vertices = 4) out;\n";
2364 	if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT && !m_params.builtin)
2365 		geom << "layout(location = 0) out vec4 unused;\n";
2366 	geom << "\n"
2367 		<< "void main(void)\n"
2368 		<< "{\n"
2369 		<< "    gl_Position = gl_in[0].gl_Position;\n"
2370 		<< "	gl_Position.y *= 1.5f;\n"
2371 		<< "    gl_Position.z = 0.5f;\n"
2372 		<< "    EmitVertex();\n"
2373 		<< "    gl_Position = gl_in[1].gl_Position;\n"
2374 		<< "	gl_Position.y *= 1.5f;\n"
2375 		<< "    gl_Position.z = 0.5f;\n"
2376 		<< "    EmitVertex();\n"
2377 		<< "    gl_Position = gl_in[2].gl_Position;\n"
2378 		<< "	gl_Position.y *= 1.5f;\n"
2379 		<< "    gl_Position.z = 0.5f;\n"
2380 		<< "    EmitVertex();\n"
2381 		<< "    EndPrimitive();\n";
2382 	if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2383 	{
2384 		if (m_params.builtin)
2385 			geom << "    gl_PointSize = 16.0f;\n";
2386 		else
2387 			geom << "    unused = vec4(1.0f);\n";
2388 	}
2389 	geom << "}\n";
2390 
2391 	frag
2392 		<< "#version 450\n"
2393 		<< "layout (location=0) out vec4 outColor;\n"
2394 		<< "void main() {\n"
2395 		<< "    outColor = vec4(1.0f);\n"
2396 		<< "}\n";
2397 
2398 	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2399 	programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2400 	programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2401 	programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2402 	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2403 }
2404 
2405 class ShaderObjectTessellationModesInstance : public vkt::TestInstance
2406 {
2407 public:
2408 							ShaderObjectTessellationModesInstance	(Context& context, const TessellationModesParams& params)
2409 																	: vkt::TestInstance	(context)
2410 																	, m_params			(params)
2411 																	{}
2412 	virtual					~ShaderObjectTessellationModesInstance	(void) {}
2413 
2414 	tcu::TestStatus			iterate									(void) override;
2415 private:
2416 	TessellationModesParams m_params;
2417 };
2418 
2419 tcu::TestStatus ShaderObjectTessellationModesInstance::iterate (void)
2420 {
2421 	const vk::VkInstance				instance					= m_context.getInstance();
2422 	const vk::InstanceDriver			instanceDriver				(m_context.getPlatformInterface(), instance);
2423 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
2424 	const vk::VkDevice					device						= m_context.getDevice();
2425 	const vk::VkQueue					queue						= m_context.getUniversalQueue();
2426 	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
2427 	auto&								alloc						= m_context.getDefaultAllocator();
2428 	tcu::TestLog&						log							= m_context.getTestContext().getLog();
2429 	const auto							deviceExtensions			= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2430 	const bool							tessellationSupported		= m_context.getDeviceFeatures().tessellationShader;
2431 	const bool							geometrySupported			= m_context.getDeviceFeatures().geometryShader;
2432 	const bool							taskSupported				= m_context.getMeshShaderFeatures().taskShader;
2433 	const bool							meshSupported				= m_context.getMeshShaderFeatures().meshShader;
2434 
2435 	vk::VkFormat						colorAttachmentFormat		= vk::VK_FORMAT_R8G8B8A8_UNORM;
2436 	const auto							subresourceRange			= makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2437 	const auto							subresourceLayers			= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2438 	const vk::VkRect2D					renderArea					= vk::makeRect2D(0, 0, 32, 32);
2439 	vk::VkExtent3D						extent						= { renderArea.extent.width, renderArea.extent.height, 1};
2440 
2441 	const vk::VkImageCreateInfo	createInfo =
2442 	{
2443 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2444 		DE_NULL,									// const void*				pNext
2445 		0u,											// VkImageCreateFlags		flags
2446 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2447 		colorAttachmentFormat,						// VkFormat					format
2448 		{ 32, 32, 1 },								// VkExtent3D				extent
2449 		1u,											// uint32_t					mipLevels
2450 		1u,											// uint32_t					arrayLayers
2451 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2452 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2453 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
2454 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2455 		0,											// uint32_t					queueFamilyIndexCount
2456 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
2457 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2458 	};
2459 
2460 	de::MovePtr<vk::ImageWithMemory>	image					= de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2461 	const auto							imageView				= vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2462 
2463 	const vk::VkDeviceSize				colorOutputBufferSize	= renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2464 	de::MovePtr<vk::BufferWithMemory>	colorOutputBuffer		= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2465 		vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
2466 
2467 	const auto&					binaries			= m_context.getBinaryCollection();
2468 	const auto					vertShader			= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported));
2469 	const auto					tescShader			= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported));
2470 	const auto					teseShader			= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported));
2471 	const auto					fragShader			= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported));
2472 
2473 	const vk::Move<vk::VkCommandPool>	cmdPool		(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2474 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer	(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2475 
2476 	vk::beginCommandBuffer(vk, *cmdBuffer);
2477 
2478 	vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2479 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
2480 
2481 	const vk::VkClearValue				clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
2482 	vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2483 
2484 	vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported);
2485 	vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2486 
2487 	vk.cmdSetPolygonModeEXT(*cmdBuffer, vk::VK_POLYGON_MODE_LINE);
2488 
2489 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2490 
2491 	vk::endRendering(vk, *cmdBuffer);
2492 
2493 	vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2494 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
2495 
2496 	const vk::VkBufferImageCopy	copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2497 	vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
2498 
2499 	vk::endCommandBuffer(vk, *cmdBuffer);
2500 	vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2501 
2502 	tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
2503 
2504 	const tcu::Vec4			black		= tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2505 	const tcu::Vec4			white		= tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2506 	const deUint32			width		= resultBuffer.getWidth();
2507 	const deUint32			height		= resultBuffer.getHeight();
2508 
2509 	const bool equal1[17][17] =
2510 	{
2511 		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2512 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2513 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, },
2514 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2515 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, },
2516 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, },
2517 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, },
2518 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, },
2519 		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, },
2520 		{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
2521 		{ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2522 		{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2523 		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2524 		{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2525 		{ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2526 		{ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2527 		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2528 	};
2529 
2530 	const bool even1[17][17] =
2531 	{
2532 		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2533 		{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
2534 		{ 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, },
2535 		{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, },
2536 		{ 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, },
2537 		{ 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, },
2538 		{ 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, },
2539 		{ 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, },
2540 		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2541 		{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, },
2542 		{ 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, },
2543 		{ 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, },
2544 		{ 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, },
2545 		{ 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, },
2546 		{ 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, },
2547 		{ 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, },
2548 		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2549 	};
2550 
2551 	const bool odd2[17][17] =
2552 	{
2553 		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2554 		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, },
2555 		{ 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, },
2556 		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2557 		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, },
2558 		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, },
2559 		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, },
2560 		{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, },
2561 		{ 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, },
2562 		{ 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, },
2563 		{ 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2564 		{ 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2565 		{ 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2566 		{ 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2567 		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2568 		{ 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, },
2569 		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2570 	};
2571 
2572 	for (deUint32 j = 0; j < height; ++j)
2573 	{
2574 		for (deUint32 i = 0; i < width; ++i)
2575 		{
2576 			const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
2577 
2578 			bool inside = false;
2579 			if (i >= 7 && i < 24 && j >= 7 && j < 24)
2580 			{
2581 				if ((m_params.subdivision == 1 && m_params.spacing == EQUAL) || (m_params.subdivision == 1 && m_params.spacing == ODD))
2582 					inside |= equal1[j - 7][i - 7];
2583 				else if ((m_params.subdivision == 1 && m_params.spacing == EVEN) || (m_params.subdivision == 2 && m_params.spacing == EQUAL) || (m_params.subdivision == 2 && m_params.spacing == EVEN))
2584 					inside |= even1[j - 7][i - 7];
2585 				else if (m_params.subdivision == 2 && m_params.spacing == ODD)
2586 					inside |= odd2[j - 7][i - 7];
2587 			}
2588 
2589 			if (inside)
2590 			{
2591 				if (color != white)
2592 				{
2593 					log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2594 					return tcu::TestStatus::fail("Fail");
2595 				}
2596 			}
2597 			else
2598 			{
2599 				if (color != black)
2600 				{
2601 					log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2602 					return tcu::TestStatus::fail("Fail");
2603 				}
2604 			}
2605 		}
2606 	}
2607 
2608 	return tcu::TestStatus::pass("Pass");
2609 }
2610 
2611 class ShaderObjectTessellationModesCase : public vkt::TestCase
2612 {
2613 public:
2614 							ShaderObjectTessellationModesCase	(tcu::TestContext& testCtx, const std::string& name, const TessellationModesParams& testParams)
2615 																: vkt::TestCase		(testCtx, name)
2616 																, m_params			(testParams)
2617 																{}
2618 	virtual					~ShaderObjectTessellationModesCase	(void) {}
2619 
2620 	void					checkSupport						(vkt::Context& context) const override;
2621 	virtual void			initPrograms						(vk::SourceCollections& programCollection) const override;
2622 	TestInstance*			createInstance						(Context& context) const override { return new ShaderObjectTessellationModesInstance(context, m_params); }
2623 private:
2624 	const TessellationModesParams m_params;
2625 };
2626 
2627 void ShaderObjectTessellationModesCase::checkSupport (vkt::Context& context) const
2628 {
2629 	context.requireDeviceFunctionality("VK_EXT_shader_object");
2630 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2631 }
2632 
2633 void ShaderObjectTessellationModesCase::initPrograms (vk::SourceCollections& programCollection) const
2634 {
2635 	std::stringstream vert;
2636 	std::stringstream tesc;
2637 	std::stringstream tese;
2638 	std::stringstream frag;
2639 
2640 	vert
2641 		<< "#version 450\n"
2642 		<< "void main() {\n"
2643 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
2644 		<< "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
2645 		<< "}\n";
2646 
2647 	tesc
2648 		<< "#version 450\n"
2649 		<< "\n"
2650 		<< "layout(vertices = 4) out;\n"
2651 		<< "\n"
2652 		<< "void main (void)\n"
2653 		<< "{\n"
2654 		<< "    if (gl_InvocationID == 0) {\n";
2655 	if (m_params.subdivision == 1)
2656 		tesc << "    float subdivision = 1.0f;\n";
2657 	else
2658 		tesc << "    float subdivision = 2.0f;\n";
2659 	tesc
2660 		<< "		gl_TessLevelInner[0] = subdivision;\n"
2661 		<< "		gl_TessLevelInner[1] = subdivision;\n"
2662 		<< "		gl_TessLevelOuter[0] = subdivision;\n"
2663 		<< "		gl_TessLevelOuter[1] = subdivision;\n"
2664 		<< "		gl_TessLevelOuter[2] = subdivision;\n"
2665 		<< "		gl_TessLevelOuter[3] = subdivision;\n"
2666 		<< "	}\n"
2667 		<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2668 		<< "}\n";
2669 
2670 	tese
2671 		<< "#version 450\n"
2672 		<< "\n";
2673 	if (m_params.spacing == EQUAL)
2674 		tese << "layout(quads, equal_spacing) in;\n";
2675 	else if (m_params.spacing == EVEN)
2676 		tese << "layout(quads, fractional_even_spacing) in;\n";
2677 	else
2678 		tese << "layout(quads, fractional_odd_spacing) in;\n";
2679 	tese
2680 		<< "\n"
2681 		<< "void main (void)\n"
2682 		<< "{\n"
2683 		<< "	float u = gl_TessCoord.x;\n"
2684 		<< "	float v = gl_TessCoord.y;\n"
2685 		<< "	float omu = 1.0f - u;\n"
2686 		<< "	float omv = 1.0f - v;\n"
2687 		<< "	gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2688 		<< "}\n";
2689 
2690 	frag
2691 		<< "#version 450\n"
2692 		<< "layout (location=0) out vec4 outColor;\n"
2693 		<< "void main() {\n"
2694 		<< "    outColor = vec4(1.0f);\n"
2695 		<< "}\n";
2696 	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2697 	programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2698 	programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2699 	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2700 }
2701 
2702 }
2703 
2704 tcu::TestCaseGroup* createShaderObjectMiscTests(tcu::TestContext& testCtx)
2705 {
2706 	de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc"));
2707 
2708 	const struct
2709 	{
2710 		deUint32	stride;
2711 		const char* name;
2712 	} strideTests[] =
2713 	{
2714 		{ 16,	"16",	},
2715 		{ 32,	"32",	},
2716 		{ 48,	"48",	},
2717 		{ 40,	"40",	},
2718 	};
2719 
2720 	for (deUint32 i = 0; i < 2; ++i)
2721 	{
2722 		bool blend1 = i == 0;
2723 		de::MovePtr<tcu::TestCaseGroup> blend1Group(new tcu::TestCaseGroup(testCtx, blend1 ? "on" : "off"));
2724 		for (deUint32 j = 0; j < 2; ++j)
2725 		{
2726 			bool blend2 = j == 0;
2727 			de::MovePtr<tcu::TestCaseGroup> blend2Group(new tcu::TestCaseGroup(testCtx, blend2 ? "on" : "off"));
2728 			for (deUint32 k = 0; k < 2; ++k)
2729 			{
2730 				bool vertexInputBefore = k == 0;
2731 				de::MovePtr<tcu::TestCaseGroup> vertexInputBeforeGroup(new tcu::TestCaseGroup(testCtx, vertexInputBefore ? "before" : "after"));
2732 				for (deUint32 l = 0; l < 2; ++l)
2733 				{
2734 					bool vertexBuffersNullStride = l == 0;
2735 					de::MovePtr<tcu::TestCaseGroup> vertexBuffersNullStrideGroup(new tcu::TestCaseGroup(testCtx, vertexBuffersNullStride ? "null" : "non_null"));
2736 					for (const auto& strideTest : strideTests)
2737 					{
2738 						de::MovePtr<tcu::TestCaseGroup> strideGroup(new tcu::TestCaseGroup(testCtx, strideTest.name));
2739 						for (deUint32 m = 0; m < 2; ++m)
2740 						{
2741 							bool destroyDescriptorSetLayout = m == 1;
2742 							std::string destroyName = destroyDescriptorSetLayout ? "set" : "destroyed";
2743 
2744 							TestParams params;
2745 							params.blendEnabled[0] = blend1;
2746 							params.blendEnabled[1] = blend2;
2747 							params.vertexInputBefore = vertexInputBefore;
2748 							params.vertexBuffersNullStride = vertexBuffersNullStride;
2749 							params.stride = strideTest.stride;
2750 							params.destroyDescriptorSetLayout = destroyDescriptorSetLayout;
2751 							strideGroup->addChild(new ShaderObjectMiscCase(testCtx, destroyName, params));
2752 						}
2753 						vertexBuffersNullStrideGroup->addChild(strideGroup.release());
2754 					}
2755 					vertexInputBeforeGroup->addChild(vertexBuffersNullStrideGroup.release());
2756 				}
2757 				blend2Group->addChild(vertexInputBeforeGroup.release());
2758 			}
2759 			blend1Group->addChild(blend2Group.release());
2760 		}
2761 		miscGroup->addChild(blend1Group.release());
2762 	}
2763 
2764 	const struct
2765 	{
2766 		bool pipeline;
2767 		const char* name;
2768 	} pipelineTests[] =
2769 	{
2770 		{ false,	"shaders"	},
2771 		{ true,		"pipeline"	},
2772 	};
2773 
2774 	const struct
2775 	{
2776 		bool meshShader;
2777 		bool vertShader;
2778 		bool tessShader;
2779 		bool geomShader;
2780 		bool fragShader;
2781 		const char* name;
2782 	} shadersTests[] =
2783 	{
2784 		{ false, true, false, false, false,		"vert",					},
2785 		{ false, true, false, false, true,		"vert_frag",			},
2786 		{ false, true, true, false, true,		"vert_tess_frag",		},
2787 		{ false, true, false, true, true,		"vert_geom_frag",		},
2788 		{ false, true, true, true, true,		"vert_tess_geom_frag",	},
2789 		{ true, false, false, false, true,		"mesh_frag",			},
2790 	};
2791 
2792 	const struct
2793 	{
2794 		bool alphaToOne;
2795 		const char* name;
2796 	} alphaToOneTests[] =
2797 	{
2798 		{ false,	"disabled"	},
2799 		{ true,		"enabled"	},
2800 	};
2801 
2802 	const struct
2803 	{
2804 		bool depthTestEnable;
2805 		bool depthBounds;
2806 		bool depthBoundsTestEnable;
2807 		bool depthClamp;
2808 		bool depthClip;
2809 		bool depthClipControl;
2810 		bool depthBiasEnable;
2811 		const char* name;
2812 	} depthTests[]
2813 	{
2814 		{ false, false, false, false, false, false, false,	"none"				},
2815 		{ true, true, false, false, false, false, false,	"bounds_disabled"	},
2816 		{ true, true, true, false, false, false, false,		"bounds_enabled"	},
2817 		{ true, false, false, true, false, false, false,	"clamp"				},
2818 		{ true, false, false, false, true, false, false,	"clip"				},
2819 		{ true, false, false, false, false, true, false,	"clip_control"		},
2820 		{ true, false, false, false, false, false, true,	"bias"				},
2821 	};
2822 
2823 	const struct
2824 	{
2825 		bool discardRectangles;
2826 		bool discardRectanglesEnabled;
2827 		const char* name;
2828 	} discardRectanglesTests[] =
2829 	{
2830 		{ false, false, "disabled"	},
2831 		{ true, false,	"enabled"	},
2832 		{ true, true,	"discard"	},
2833 	};
2834 
2835 	const struct
2836 	{
2837 		bool rasterizationDiscardEnable;
2838 		const char* name;
2839 	} rasterizationDiscardEnableTests[] =
2840 	{
2841 		{ false,	"disabled"	},
2842 		{ true,		"enabled"	},
2843 	};
2844 
2845 	const struct
2846 	{
2847 		bool colorBlendEnable;
2848 		const char* name;
2849 	} colorBlendTests[] =
2850 	{
2851 		{ false,	"disabled"	},
2852 		{ true,		"enabled"	},
2853 	};
2854 
2855 	const struct
2856 	{
2857 		bool lines;
2858 		const char* name;
2859 	} primitiveTests[] =
2860 	{
2861 		{ false,	"triangles" },
2862 		{ true,		"lines"		},
2863 	};
2864 
2865 	const struct
2866 	{
2867 		bool stencilEnable;
2868 		const char* name;
2869 	} stencilTests[] =
2870 	{
2871 		{ false,	"disabled"	},
2872 		{ true,		"enabled"	},
2873 	};
2874 
2875 	const struct
2876 	{
2877 		bool logicOp;
2878 		bool logicOpEnable;
2879 		const char* name;
2880 	} logicOpTests[] =
2881 	{
2882 		{ false, false, "disabled"	},
2883 		{ true, false,	"enabled"	},
2884 		{ true, true,	"copy"		},
2885 	};
2886 
2887 	const struct
2888 	{
2889 		bool geometryStreams;
2890 		const char* name;
2891 	} geometryStreamsTests[] =
2892 	{
2893 		{ false,	"disabled"	},
2894 		{ true,		"enabled"	},
2895 	};
2896 
2897 	const struct
2898 	{
2899 		bool provokingVertex;
2900 		const char* name;
2901 	} provokingVertexTests[] =
2902 	{
2903 		{ false,	"disabled"	},
2904 		{ true,		"enabled"	},
2905 	};
2906 
2907 	const struct
2908 	{
2909 		bool sampleLocations;
2910 		bool sampleLocationsEnable;
2911 		const char* name;
2912 	} sampleLocationsTests[] =
2913 	{
2914 		{ false, false, "disabled"	},
2915 		{ true, false,	"enabled"	},
2916 		{ true, true,	"used"		},
2917 	};
2918 
2919 	const struct
2920 	{
2921 		bool lineRasterization;
2922 		bool stippledLineEnable;
2923 		const char* name;
2924 	} linesTests[] =
2925 	{
2926 		{ false, false, "default"				},
2927 		{ true, false,	"rectangular"			},
2928 		{ true, true,	"rectangular_stippled"	},
2929 	};
2930 
2931 	const struct
2932 	{
2933 		bool cull;
2934 		const char* name;
2935 	} cullTests[] =
2936 	{
2937 		{ false,	"none"				},
2938 		{ true,		"front_and_back"	},
2939 	};
2940 
2941 	const struct
2942 	{
2943 		bool conservativeRasterization;
2944 		bool conservativeRasterizationOverestimate;
2945 		const char* name;
2946 	} conservativeRasterizationTests[] =
2947 	{
2948 		{ false, false, "disabled"		},
2949 		{ true, false,	"enabled"		},
2950 		{ true, true,	"overestimate"	},
2951 	};
2952 
2953 	const struct
2954 	{
2955 		bool colorWrite;
2956 		bool colorWriteEnable;
2957 		const char* name;
2958 	} colorWriteEnableTests[] =
2959 	{
2960 		{ false, false, "disabled"	},
2961 		{ true, false,	"false"		},
2962 		{ true, true,	"true"		},
2963 	};
2964 
2965 	de::MovePtr<tcu::TestCaseGroup> stateGroup(new tcu::TestCaseGroup(testCtx, "state"));
2966 	for (const auto& pipelineTest : pipelineTests)
2967 	{
2968 		de::MovePtr<tcu::TestCaseGroup> pipelineGroup(new tcu::TestCaseGroup(testCtx, pipelineTest.name));
2969 		for (const auto shadersTest : shadersTests)
2970 		{
2971 			de::MovePtr<tcu::TestCaseGroup> shadersGroup(new tcu::TestCaseGroup(testCtx, shadersTest.name));
2972 
2973 			StateTestParams params;
2974 			params.pipeline = pipelineTest.pipeline;
2975 			params.meshShader = shadersTest.meshShader;
2976 			params.vertShader = shadersTest.vertShader;
2977 			params.tessShader = shadersTest.tessShader;
2978 			params.geomShader = shadersTest.geomShader;
2979 			params.fragShader = shadersTest.fragShader;
2980 			params.reset();
2981 
2982 			de::MovePtr<tcu::TestCaseGroup> alphaToOneGroup(new tcu::TestCaseGroup(testCtx, "alphaToOne"));
2983 			for (const auto& alphaToOneTest : alphaToOneTests)
2984 			{
2985 				params.alphaToOne = alphaToOneTest.alphaToOne;
2986 				alphaToOneGroup->addChild(new ShaderObjectStateCase(testCtx, alphaToOneTest.name, params));
2987 			}
2988 			shadersGroup->addChild(alphaToOneGroup.release());
2989 			params.reset();
2990 
2991 			de::MovePtr<tcu::TestCaseGroup> depthGroup(new tcu::TestCaseGroup(testCtx, "depth"));
2992 			for (const auto& depthTest : depthTests)
2993 			{
2994 				params.depthTestEnable = depthTest.depthTestEnable;
2995 				params.depthBounds = depthTest.depthBounds;
2996 				params.depthBoundsTestEnable = depthTest.depthBoundsTestEnable;
2997 				params.depthClamp = depthTest.depthClamp;
2998 				params.depthClip = depthTest.depthClip;
2999 				params.depthClipControl = depthTest.depthClipControl;
3000 				params.depthBiasEnable = depthTest.depthBiasEnable;
3001 				depthGroup->addChild(new ShaderObjectStateCase(testCtx, depthTest.name, params));
3002 			}
3003 			shadersGroup->addChild(depthGroup.release());
3004 			params.reset();
3005 
3006 			de::MovePtr<tcu::TestCaseGroup> discardRectanglesGroup(new tcu::TestCaseGroup(testCtx, "discard_rectangles"));
3007 			for (const auto& discardRectangles : discardRectanglesTests)
3008 			{
3009 				params.discardRectangles = discardRectangles.discardRectangles;
3010 				params.discardRectanglesEnable = discardRectangles.discardRectanglesEnabled;
3011 				discardRectanglesGroup->addChild(new ShaderObjectStateCase(testCtx, discardRectangles.name, params));
3012 			}
3013 			shadersGroup->addChild(discardRectanglesGroup.release());
3014 			params.reset();
3015 
3016 			de::MovePtr<tcu::TestCaseGroup> rasterizationDiscardEnableGroup(new tcu::TestCaseGroup(testCtx, "rasterization_discard"));
3017 			for (const auto& rasterizationDiscardTest : rasterizationDiscardEnableTests)
3018 			{
3019 				params.rasterizerDiscardEnable = rasterizationDiscardTest.rasterizationDiscardEnable;
3020 				rasterizationDiscardEnableGroup->addChild(new ShaderObjectStateCase(testCtx, rasterizationDiscardTest.name, params));
3021 			}
3022 			shadersGroup->addChild(rasterizationDiscardEnableGroup.release());
3023 			params.reset();
3024 
3025 			de::MovePtr<tcu::TestCaseGroup> colorBlendGroup(new tcu::TestCaseGroup(testCtx, "color_blend"));
3026 			for (const auto& colorBlendTest : colorBlendTests)
3027 			{
3028 				params.colorBlendEnable = colorBlendTest.colorBlendEnable;
3029 				colorBlendGroup->addChild(new ShaderObjectStateCase(testCtx, colorBlendTest.name, params));
3030 			}
3031 			shadersGroup->addChild(colorBlendGroup.release());
3032 			params.reset();
3033 
3034 			de::MovePtr<tcu::TestCaseGroup> primitivesGroup(new tcu::TestCaseGroup(testCtx, "primitives"));
3035 			for (const auto& primitivesTest : primitiveTests)
3036 			{
3037 				params.lines = primitivesTest.lines;
3038 				primitivesGroup->addChild(new ShaderObjectStateCase(testCtx, primitivesTest.name, params));
3039 			}
3040 			shadersGroup->addChild(primitivesGroup.release());
3041 			params.reset();
3042 
3043 			de::MovePtr<tcu::TestCaseGroup> stencilGroup(new tcu::TestCaseGroup(testCtx, "stencil"));
3044 			for (const auto& stencilTest : stencilTests)
3045 			{
3046 				params.stencilTestEnable = stencilTest.stencilEnable;
3047 				stencilGroup->addChild(new ShaderObjectStateCase(testCtx, stencilTest.name, params));
3048 			}
3049 			shadersGroup->addChild(stencilGroup.release());
3050 			params.reset();
3051 
3052 			de::MovePtr<tcu::TestCaseGroup> logicOpGroup(new tcu::TestCaseGroup(testCtx, "logic_op"));
3053 			for (const auto& logicOpTest : logicOpTests)
3054 			{
3055 				params.logicOp = logicOpTest.logicOp;
3056 				params.logicOpEnable = logicOpTest.logicOpEnable;
3057 				logicOpGroup->addChild(new ShaderObjectStateCase(testCtx, logicOpTest.name, params));
3058 			}
3059 			shadersGroup->addChild(logicOpGroup.release());
3060 			params.reset();
3061 
3062 			if (shadersTest.geomShader)
3063 			{
3064 				de::MovePtr<tcu::TestCaseGroup> geometryStreamsGroup(new tcu::TestCaseGroup(testCtx, "geometry_streams"));
3065 				for (const auto& geometryStreamsTest : geometryStreamsTests)
3066 				{
3067 					params.geometryStreams = geometryStreamsTest.geometryStreams;
3068 					geometryStreamsGroup->addChild(new ShaderObjectStateCase(testCtx, geometryStreamsTest.name, params));
3069 				}
3070 				shadersGroup->addChild(geometryStreamsGroup.release());
3071 				params.reset();
3072 			}
3073 
3074 			de::MovePtr<tcu::TestCaseGroup> provokingVertexGroup(new tcu::TestCaseGroup(testCtx, "provoking_vertex"));
3075 			for (const auto& provokingVertexTest : provokingVertexTests)
3076 			{
3077 				params.provokingVertex = provokingVertexTest.provokingVertex;
3078 				provokingVertexGroup->addChild(new ShaderObjectStateCase(testCtx, provokingVertexTest.name, params));
3079 			}
3080 			shadersGroup->addChild(provokingVertexGroup.release());
3081 			params.reset();
3082 
3083 			de::MovePtr<tcu::TestCaseGroup> sampleLocationsGroup(new tcu::TestCaseGroup(testCtx, "sample_locations"));
3084 			for (const auto& sampleLocationsTest : sampleLocationsTests)
3085 			{
3086 				params.sampleLocations = sampleLocationsTest.sampleLocations;
3087 				params.sampleLocationsEnable = sampleLocationsTest.sampleLocationsEnable;
3088 				sampleLocationsGroup->addChild(new ShaderObjectStateCase(testCtx, sampleLocationsTest.name, params));
3089 			}
3090 			shadersGroup->addChild(sampleLocationsGroup.release());
3091 			params.reset();
3092 
3093 			de::MovePtr<tcu::TestCaseGroup> linesGroup(new tcu::TestCaseGroup(testCtx, "lines"));
3094 			for (const auto& linesTest : linesTests)
3095 			{
3096 				params.lines = true;
3097 				params.stippledLineEnable = linesTest.stippledLineEnable;
3098 				params.lineRasterization = linesTest.lineRasterization;
3099 				linesGroup->addChild(new ShaderObjectStateCase(testCtx, linesTest.name, params));
3100 			}
3101 			shadersGroup->addChild(linesGroup.release());
3102 			params.reset();
3103 
3104 			de::MovePtr<tcu::TestCaseGroup> cullGroup(new tcu::TestCaseGroup(testCtx, "cull"));
3105 			for (const auto& cullTest : cullTests)
3106 			{
3107 				params.cull = cullTest.cull;
3108 				cullGroup->addChild(new ShaderObjectStateCase(testCtx, cullTest.name, params));
3109 			}
3110 			shadersGroup->addChild(cullGroup.release());
3111 			params.reset();
3112 
3113 			de::MovePtr<tcu::TestCaseGroup> conservativeRasterizationGroup(new tcu::TestCaseGroup(testCtx, "conservative_rasterization"));
3114 			for (const auto& conservativeRasterizationTest : conservativeRasterizationTests)
3115 			{
3116 				params.conservativeRasterization = conservativeRasterizationTest.conservativeRasterization;
3117 				params.conservativeRasterizationOverestimate = conservativeRasterizationTest.conservativeRasterizationOverestimate;
3118 				conservativeRasterizationGroup->addChild(new ShaderObjectStateCase(testCtx, conservativeRasterizationTest.name, params));
3119 			}
3120 			shadersGroup->addChild(conservativeRasterizationGroup.release());
3121 			params.reset();
3122 
3123 			de::MovePtr<tcu::TestCaseGroup> colorWriteGroup(new tcu::TestCaseGroup(testCtx, "color_write"));
3124 			for (const auto& colorWriteEnableTest : colorWriteEnableTests)
3125 			{
3126 				params.colorWrite = colorWriteEnableTest.colorWrite;
3127 				params.colorWriteEnable = colorWriteEnableTest.colorWriteEnable;
3128 				colorWriteGroup->addChild(new ShaderObjectStateCase(testCtx, colorWriteEnableTest.name, params));
3129 			}
3130 			shadersGroup->addChild(colorWriteGroup.release());
3131 			params.reset();
3132 
3133 			pipelineGroup->addChild(shadersGroup.release());
3134 		}
3135 		stateGroup->addChild(pipelineGroup.release());
3136 	}
3137 	miscGroup->addChild(stateGroup.release());
3138 
3139 	const struct
3140 	{
3141 		bool linked;
3142 		const char* name;
3143 	} linkedTests[] =
3144 	{
3145 		{ false,	"unlinked"	},
3146 		{ true,		"linked"	},
3147 	};
3148 
3149 	const struct
3150 	{
3151 		vk::VkShaderStageFlagBits stage;
3152 		const char* name;
3153 	} shaderStageTests[] =
3154 	{
3155 		{ vk::VK_SHADER_STAGE_VERTEX_BIT,					"vert"	},
3156 		{ vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc"	},
3157 		{ vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese"	},
3158 		{ vk::VK_SHADER_STAGE_GEOMETRY_BIT,					"geom"	},
3159 	};
3160 
3161 	const struct
3162 	{
3163 		bool builtin;
3164 		const char* name;
3165 	} typeTests[] =
3166 	{
3167 		{ false,	"output"	},
3168 		{ true,		"builtin"	},
3169 	};
3170 
3171 	de::MovePtr<tcu::TestCaseGroup> unusedVariableGroup(new tcu::TestCaseGroup(testCtx, "unused_variable"));
3172 	for (const auto& linkedTest : linkedTests)
3173 	{
3174 		de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedTest.name));
3175 		for (const auto& typeTest : typeTests)
3176 		{
3177 			de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, typeTest.name));
3178 			for (const auto& shaderStageTest : shaderStageTests)
3179 			{
3180 				UnusedBuiltinParams params;
3181 				params.linked = linkedTest.linked;
3182 				params.stage = shaderStageTest.stage;
3183 				params.builtin = typeTest.builtin;
3184 				typeGroup->addChild(new ShaderObjectUnusedBuiltinCase(testCtx, shaderStageTest.name, params));
3185 			}
3186 			linkedGroup->addChild(typeGroup.release());
3187 		}
3188 		unusedVariableGroup->addChild(linkedGroup.release());
3189 	}
3190 	miscGroup->addChild(unusedVariableGroup.release());
3191 
3192 	const struct
3193 	{
3194 		deUint32 subdivision;
3195 		const char* name;
3196 	} subdivisionTests[] =
3197 	{
3198 		{ 1,	"one"	},
3199 		{ 2,	"two"	},
3200 	};
3201 
3202 	const struct
3203 	{
3204 		TessellationSpacing spacing;
3205 		const char* name;
3206 	} spacingTests[] =
3207 	{
3208 		{ EQUAL,	"equal"	},
3209 		{ EVEN,		"even"	},
3210 		{ ODD,		"odd"	},
3211 	};
3212 
3213 	de::MovePtr<tcu::TestCaseGroup> tessellationModesGroup(new tcu::TestCaseGroup(testCtx, "tessellation_modes"));
3214 	for (const auto& subdivisionTest : subdivisionTests)
3215 	{
3216 		de::MovePtr<tcu::TestCaseGroup> subdivisionGroup(new tcu::TestCaseGroup(testCtx, subdivisionTest.name));
3217 
3218 		for (const auto& spacingTest : spacingTests)
3219 		{
3220 			TessellationModesParams params;
3221 			params.subdivision = subdivisionTest.subdivision;
3222 			params.spacing = spacingTest.spacing;
3223 			subdivisionGroup->addChild(new ShaderObjectTessellationModesCase(testCtx, spacingTest.name, params));
3224 		}
3225 		tessellationModesGroup->addChild(subdivisionGroup.release());
3226 	}
3227 	miscGroup->addChild(tessellationModesGroup.release());
3228 
3229 	return miscGroup.release();
3230 }
3231 
3232 } // ShaderObject
3233 } // vkt
3234