• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Pipeline Interaction Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktShaderObjectCreateTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkBarrierUtil.hpp"
32 #include "vktShaderObjectCreateUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "deRandom.hpp"
35 #include "vkBuilderUtil.hpp"
36 
37 namespace vkt
38 {
39 namespace ShaderObject
40 {
41 
42 namespace
43 {
44 
45 enum TestType {
46 	SHADER_OBJECT = 0,
47 	MAX_PIPELINE,
48 	MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE,
49 	SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT,
50 	MIN_PIPELINE_SHADER_OBJECT,
51 	RENDER_PASS_PIPELINE_SHADER_OBJECT,
52 	RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN,
53 	SHADER_OBJECT_MIN_PIPELINE,
54 	COMPUTE_SHADER_OBJECT_MIN_PIPELINE,
55 	SHADER_OBJECT_COMPUTE_PIPELINE,
56 };
57 
58 struct TestParams {
59 	TestType	testType;
60 };
61 
62 struct StageTestParams {
63 	bool vertShader;
64 	bool tessShader;
65 	bool geomShader;
66 	bool fragShader;
67 };
68 
69 class ShaderObjectPipelineInteractionInstance : public vkt::TestInstance
70 {
71 public:
ShaderObjectPipelineInteractionInstance(Context & context,const TestParams & params)72 							ShaderObjectPipelineInteractionInstance		(Context& context, const TestParams& params)
73 																		: vkt::TestInstance	(context)
74 																		, m_params			(params)
75 																		{}
~ShaderObjectPipelineInteractionInstance(void)76 	virtual					~ShaderObjectPipelineInteractionInstance	(void) {}
77 
78 	tcu::TestStatus			iterate										(void) override;
79 private:
80 	bool					verifyImage									(de::MovePtr<vk::BufferWithMemory>& outputBuffer, deUint32 drawCount);
81 	deUint32				getDrawCount								(void);
82 	TestParams				m_params;
83 
84 	const vk::VkFormat		colorAttachmentFormat		= vk::VK_FORMAT_R8G8B8A8_UNORM;
85 	const vk::VkRect2D		renderArea					= { {0u, 0u, }, {32u, 32u, } };
86 };
87 
getDrawCount(void)88 deUint32 ShaderObjectPipelineInteractionInstance::getDrawCount (void)
89 {
90 	switch (m_params.testType) {
91 		case SHADER_OBJECT:
92 			return 1;
93 		case MAX_PIPELINE:
94 			return 1;
95 		case MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE:
96 			return 3;
97 		case SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT:
98 			return 3;
99 		case MIN_PIPELINE_SHADER_OBJECT:
100 			return 2;
101 		case RENDER_PASS_PIPELINE_SHADER_OBJECT:
102 			return 1;
103 		case RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN:
104 			return 1;
105 		case SHADER_OBJECT_MIN_PIPELINE:
106 			return 2;
107 		case COMPUTE_SHADER_OBJECT_MIN_PIPELINE:
108 			return 1;
109 		case SHADER_OBJECT_COMPUTE_PIPELINE:
110 			return 1;
111 	}
112 	return 0;
113 }
114 
extensionEnabled(const std::vector<std::string> & deviceExtensions,const std::string & ext)115 bool extensionEnabled (const std::vector<std::string>& deviceExtensions, const std::string& ext)
116 {
117 	return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
118 }
119 
iterate(void)120 tcu::TestStatus ShaderObjectPipelineInteractionInstance::iterate (void)
121 {
122 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
123 	const vk::VkDevice					device						= m_context.getDevice();
124 	const vk::VkQueue					queue						= m_context.getUniversalQueue();
125 	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
126 	auto&								alloc						= m_context.getDefaultAllocator();
127 	const auto							deviceExtensions			= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
128 	const bool							tessellationSupported		= m_context.getDeviceFeatures().tessellationShader;
129 	const bool							geometrySupported			= m_context.getDeviceFeatures().geometryShader;
130 	const bool							taskSupported				= m_context.getMeshShaderFeatures().taskShader;
131 	const bool							meshSupported				= m_context.getMeshShaderFeatures().meshShader;
132 
133 	const auto							subresourceRange			= makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
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 		{ renderArea.extent.width, renderArea.extent.height, 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 	de::MovePtr<vk::ImageWithMemory>	image						= de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
155 	const auto							imageView					= vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
156 
157 	const vk::VkDeviceSize				colorOutputBufferSize		= renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
158 	de::MovePtr<vk::BufferWithMemory>	colorOutputBuffer			= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
159 		vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
160 
161 	const vk::VkCommandPoolCreateInfo	cmdPoolInfo =
162 	{
163 		vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// sType
164 		DE_NULL,												// pNext
165 		vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// flags
166 		queueFamilyIndex,										// queuefamilyindex
167 	};
168 
169 	const vk::Move<vk::VkCommandPool>	cmdPool					(createCommandPool(vk, device, &cmdPoolInfo));
170 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
171 	const vk::Move<vk::VkCommandBuffer>	copyCmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
172 
173 	const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
174 		vk::DescriptorSetLayoutBuilder()
175 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
176 		.build(vk, device));
177 
178 	const vk::Unique<vk::VkDescriptorPool> descriptorPool(
179 		vk::DescriptorPoolBuilder()
180 		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
181 		.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
182 
183 	const auto					pipelineLayout			= makePipelineLayout(vk, device);
184 	const auto					computePipelineLayout	= makePipelineLayout(vk, device, descriptorSetLayout.get());
185 
186 	const auto&					binaries			= m_context.getBinaryCollection();
187 	const auto&					vert1				= binaries.get("vert1");
188 	const auto&					vert2				= binaries.get("vert2");
189 	const auto&					vert3				= binaries.get("vert3");
190 	const auto&					tesc				= binaries.get("tesc");
191 	const auto&					tese				= binaries.get("tese");
192 	const auto&					geom				= binaries.get("geom");
193 	const auto&					frag1				= binaries.get("frag1");
194 	const auto&					frag2				= binaries.get("frag2");
195 	const auto&					frag3				= binaries.get("frag3");
196 	const auto&					comp				= binaries.get("comp");
197 
198 	// Todo
199 	vk::VkDescriptorSetLayout	layout				= descriptorSetLayout.get();
200 
201 	vk::VkShaderCreateInfoEXT	vertCreateInfo1		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert1, tessellationSupported, geometrySupported);
202 	vk::VkShaderCreateInfoEXT	vertCreateInfo2		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert2, tessellationSupported, geometrySupported);
203 	vk::VkShaderCreateInfoEXT	vertCreateInfo3		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert3, tessellationSupported, geometrySupported);
204 	vk::VkShaderCreateInfoEXT	tescCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, tesc, tessellationSupported, geometrySupported);
205 	vk::VkShaderCreateInfoEXT	teseCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, tese, tessellationSupported, geometrySupported);
206 	vk::VkShaderCreateInfoEXT	geomCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported);
207 	vk::VkShaderCreateInfoEXT	fragCreateInfo1		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag1, tessellationSupported, geometrySupported);
208 	vk::VkShaderCreateInfoEXT	fragCreateInfo2		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag2, tessellationSupported, geometrySupported);
209 	vk::VkShaderCreateInfoEXT	fragCreateInfo3		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag3, tessellationSupported, geometrySupported);
210 	vk::VkShaderCreateInfoEXT	compCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_COMPUTE_BIT, comp, tessellationSupported, geometrySupported, &layout);
211 
212 	vk::Move<vk::VkShaderEXT>	vertShader1			= vk::createShader(vk, device, vertCreateInfo1);
213 	vk::Move<vk::VkShaderEXT>	vertShader2			= vk::createShader(vk, device, vertCreateInfo2);
214 	vk::Move<vk::VkShaderEXT>	vertShader3			= vk::createShader(vk, device, vertCreateInfo3);
215 	vk::Move<vk::VkShaderEXT>	tescShader			= vk::createShader(vk, device, tescCreateInfo);
216 	vk::Move<vk::VkShaderEXT>	teseShader			= vk::createShader(vk, device, teseCreateInfo);
217 	vk::Move<vk::VkShaderEXT>	geomShader			= vk::createShader(vk, device, geomCreateInfo);
218 	vk::Move<vk::VkShaderEXT>	fragShader1			= vk::createShader(vk, device, fragCreateInfo1);
219 	vk::Move<vk::VkShaderEXT>	fragShader2			= vk::createShader(vk, device, fragCreateInfo2);
220 	vk::Move<vk::VkShaderEXT>	fragShader3			= vk::createShader(vk, device, fragCreateInfo3);
221 	vk::Move<vk::VkShaderEXT>	compShader			= vk::createShader(vk, device, compCreateInfo);
222 
223 	const auto					vertShaderModule1	= createShaderModule(vk, device, vert1);
224 	const auto					vertShaderModule2	= createShaderModule(vk, device, vert2);
225 	const auto					vertShaderModule3	= createShaderModule(vk, device, vert3);
226 	const auto					tescShaderModule	= createShaderModule(vk, device, tesc);
227 	const auto					teseShaderModule	= createShaderModule(vk, device, tese);
228 	const auto					geomShaderModule	= createShaderModule(vk, device, geom);
229 	const auto					fragShaderModule1	= createShaderModule(vk, device, frag1);
230 	const auto					fragShaderModule2	= createShaderModule(vk, device, frag2);
231 	const auto					fragShaderModule3	= createShaderModule(vk, device, frag3);
232 	const auto					compShaderModule	= createShaderModule(vk, device, comp);
233 
234 	const auto					renderPass			= vk::makeRenderPass(vk, device, colorAttachmentFormat, vk::VK_FORMAT_UNDEFINED, vk::VK_ATTACHMENT_LOAD_OP_CLEAR, vk::VK_IMAGE_LAYOUT_GENERAL);
235 	const auto					framebuffer			= vk::makeFramebuffer(vk, device, *renderPass, 1u, &*imageView, renderArea.extent.width, renderArea.extent.height);
236 
237 	const vk::VkPipelineVertexInputStateCreateInfo		vertexInputStateParams			=
238 	{
239 		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
240 		DE_NULL,														// const void*								pNext;
241 		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
242 		0u,																// deUint32									vertexBindingDescriptionCount;
243 		DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
244 		0u,																// deUint32									vertexAttributeDescriptionCount;
245 		DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
246 	};
247 
248 	const vk::VkPipelineTessellationStateCreateInfo		tessStateCreateInfo				=
249 	{
250 		vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
251 		DE_NULL,														//	const void*								pNext;
252 		0u,																//	VkPipelineTessellationStateCreateFlags	flags;
253 		4u,																//	uint32_t								patchControlPoints;
254 	};
255 
256 	const vk::VkPipelineInputAssemblyStateCreateInfo	pipelineInputAssemblyStateInfo	=
257 	{
258 		vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
259 		DE_NULL,															// const void*                                 pNext;
260 		(vk::VkPipelineInputAssemblyStateCreateFlags)0u,					// VkPipelineInputAssemblyStateCreateFlags     flags;
261 		vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,								// VkPrimitiveTopology                         topology;
262 		VK_FALSE,															// VkBool32                                    primitiveRestartEnable;
263 	};
264 
265 	vk::VkPipelineRenderingCreateInfo					pipelineRenderingCreateInfo		=
266 	{
267 		vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,	// VkStructureType	sType
268 		DE_NULL,												// const void*		pNext
269 		0u,														// uint32_t			viewMask
270 		1u,														// uint32_t			colorAttachmentCount
271 		&colorAttachmentFormat,									// const VkFormat*	pColorAttachmentFormats
272 		vk::VK_FORMAT_UNDEFINED,								// VkFormat			depthAttachmentFormat
273 		vk::VK_FORMAT_UNDEFINED,								// VkFormat			stencilAttachmentFormat
274 	};
275 
276 	const vk::VkViewport								viewport						= vk::makeViewport(renderArea.extent);
277 	const vk::VkRect2D									scissor							= vk::makeRect2D(renderArea.extent);
278 
279 	bool createDynamicPipeline = m_params.testType != MIN_PIPELINE_SHADER_OBJECT && m_params.testType != SHADER_OBJECT_MIN_PIPELINE && m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != RENDER_PASS_PIPELINE_SHADER_OBJECT && m_params.testType != RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN;
280 
281 	const vk::VkPipelineViewportStateCreateInfo			viewportStateCreateInfo			=
282 	{
283 		vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType
284 		DE_NULL,													// const void*                                 pNext
285 		(vk::VkPipelineViewportStateCreateFlags)0u,					// VkPipelineViewportStateCreateFlags          flags
286 		createDynamicPipeline ? 0u : 1u,							// deUint32                                    viewportCount
287 		&viewport,													// const VkViewport*                           pViewports
288 		createDynamicPipeline ? 0u : 1u,							// deUint32                                    scissorCount
289 		&scissor,													// const VkRect2D*                             pScissors
290 	};
291 
292 	const auto& edsFeatures		= m_context.getExtendedDynamicStateFeaturesEXT();
293 	const auto& eds2Features	= m_context.getExtendedDynamicState2FeaturesEXT();
294 	const auto& eds3Features	= m_context.getExtendedDynamicState3FeaturesEXT();
295 	const auto& viFeatures		= m_context.getVertexInputDynamicStateFeaturesEXT();
296 
297 	std::vector<vk::VkDynamicState> dynamicStates = {
298 		vk::VK_DYNAMIC_STATE_LINE_WIDTH,
299 		vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
300 		vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS,
301 		vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
302 		vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
303 		vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
304 		vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
305 	};
306 
307 	if (edsFeatures.extendedDynamicState)
308 	{
309 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE_EXT);
310 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT);
311 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT);
312 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
313 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
314 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
315 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT);
316 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT);
317 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT);
318 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
319 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
320 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT);
321 	}
322 	else
323 	{
324 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT);
325 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR);
326 	}
327 	if (eds2Features.extendedDynamicState2)
328 	{
329 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
330 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
331 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE);
332 	}
333 	if (eds2Features.extendedDynamicState2LogicOp)
334 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
335 	if (eds2Features.extendedDynamicState2PatchControlPoints)
336 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
337 
338 	if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
339 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
340 	if (eds3Features.extendedDynamicState3DepthClampEnable)
341 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
342 	if (eds3Features.extendedDynamicState3PolygonMode)
343 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
344 	if (eds3Features.extendedDynamicState3RasterizationSamples)
345 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
346 	if (eds3Features.extendedDynamicState3SampleMask)
347 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
348 	if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
349 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
350 	if (eds3Features.extendedDynamicState3AlphaToOneEnable)
351 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
352 	if (eds3Features.extendedDynamicState3LogicOpEnable)
353 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
354 	if (eds3Features.extendedDynamicState3ColorBlendEnable)
355 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
356 	if (eds3Features.extendedDynamicState3ColorBlendEquation)
357 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
358 	if (eds3Features.extendedDynamicState3ColorWriteMask)
359 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
360 	if (viFeatures.vertexInputDynamicState)
361 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
362 
363 	if (extensionEnabled(deviceExtensions, "VK_EXT_transform_feedback") && eds3Features.extendedDynamicState3RasterizationStream)
364 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
365 	if (extensionEnabled(deviceExtensions, "VK_EXT_blend_operation_advanced") && eds3Features.extendedDynamicState3ColorBlendAdvanced)
366 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
367 	if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") && eds3Features.extendedDynamicState3ConservativeRasterizationMode)
368 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
369 	if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") && eds3Features.extendedDynamicState3CoverageModulationMode)
370 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
371 	if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") && eds3Features.extendedDynamicState3CoverageModulationTableEnable)
372 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
373 	if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") && eds3Features.extendedDynamicState3CoverageModulationTable)
374 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
375 	if (extensionEnabled(deviceExtensions, "VK_NV_coverage_reduction_mode") && eds3Features.extendedDynamicState3CoverageReductionMode)
376 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
377 	if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") && eds3Features.extendedDynamicState3CoverageToColorEnable)
378 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
379 	if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") && eds3Features.extendedDynamicState3CoverageToColorLocation)
380 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
381 	if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_enable") && eds3Features.extendedDynamicState3DepthClipEnable)
382 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
383 	if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_control") && eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
384 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
385 	if (extensionEnabled(deviceExtensions, "VK_EXT_color_write_enable"))
386 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
387 	if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") && eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize)
388 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
389 	if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization") && eds3Features.extendedDynamicState3LineRasterizationMode)
390 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
391 	if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization") && eds3Features.extendedDynamicState3LineStippleEnable)
392 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
393 	if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization"))
394 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
395 	if (extensionEnabled(deviceExtensions, "VK_EXT_provoking_vertex") && eds3Features.extendedDynamicState3ProvokingVertexMode)
396 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
397 	if (extensionEnabled(deviceExtensions, "VK_KHR_fragment_shading_rate"))
398 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
399 	if (extensionEnabled(deviceExtensions, "VK_NV_representative_fragment_test") && eds3Features.extendedDynamicState3RepresentativeFragmentTestEnable)
400 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
401 	if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations") && eds3Features.extendedDynamicState3SampleLocationsEnable)
402 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
403 	if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations"))
404 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
405 	if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image") && eds3Features.extendedDynamicState3ShadingRateImageEnable)
406 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
407 	if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
408 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
409 	if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
410 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);
411 	if (extensionEnabled(deviceExtensions, "VK_NV_viewport_swizzle") && eds3Features.extendedDynamicState3ViewportSwizzle)
412 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
413 	if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling") && eds3Features.extendedDynamicState3ViewportWScalingEnable)
414 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
415 	if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling"))
416 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
417 	if (extensionEnabled(deviceExtensions, "VK_NV_scissor_exclusive"))
418 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
419 	if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
420 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
421 	if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
422 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
423 	if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
424 		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
425 
426 	const vk::VkPipelineDynamicStateCreateInfo			dynamicStateCreateInfo			=
427 	{
428 		vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	//	VkStructureType						sType;
429 		DE_NULL,													//	const void*							pNext;
430 		(vk::VkPipelineDynamicStateCreateFlags)0u,					//	VkPipelineDynamicStateCreateFlags	flags;
431 		static_cast<deUint32>(dynamicStates.size()),				//	deUint32							dynamicStateCount;
432 		dynamicStates.data(),										//	const VkDynamicState*				pDynamicStates;
433 	};
434 	const vk::VkPipelineDynamicStateCreateInfo* pipelineDynamicState = (createDynamicPipeline) ? &dynamicStateCreateInfo : DE_NULL;
435 
436 	const vk::VkDeviceSize					bufferSizeBytes = sizeof(deUint32) * 4;
437 
438 	const vk::Unique<vk::VkDescriptorSet>	descriptorSet	(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
439 	const vk::BufferWithMemory outputBuffer(vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
440 
441 	const vk::VkDescriptorBufferInfo		descriptorInfo	= vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
442 	vk::DescriptorSetUpdateBuilder()
443 		.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
444 		.update(vk, device);
445 
446 	vk::VkPipelineRenderingCreateInfo*		pPipelineRenderingCreateInfo	= &pipelineRenderingCreateInfo;
447 	vk::VkRenderPass						renderPassHandle				= VK_NULL_HANDLE;
448 	if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT || m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
449 	{
450 		pPipelineRenderingCreateInfo = DE_NULL;
451 		renderPassHandle = *renderPass;
452 	}
453 
454 	const auto					pipeline1				= makeGraphicsPipeline(vk, device, pipelineLayout.get(), vertShaderModule1.get(), tescShaderModule.get(), teseShaderModule.get(), geomShaderModule.get(), fragShaderModule1.get(), renderPassHandle, 0u, &vertexInputStateParams, &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL, DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
455 	const auto					pipeline2				= makeGraphicsPipeline(vk, device, pipelineLayout.get(), vertShaderModule2.get(), tescShaderModule.get(), teseShaderModule.get(), geomShaderModule.get(), fragShaderModule2.get(), renderPassHandle, 0u, &vertexInputStateParams, &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL, DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
456 	const auto					pipeline3				= makeGraphicsPipeline(vk, device, pipelineLayout.get(), vertShaderModule3.get(), tescShaderModule.get(), teseShaderModule.get(), geomShaderModule.get(), fragShaderModule3.get(), renderPassHandle, 0u, &vertexInputStateParams, &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL, DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
457 	const auto					computePipeline			= vk::makeComputePipeline(vk, device, computePipelineLayout.get(), compShaderModule.get());
458 
459 	const vk::VkClearValue		clearValue				= vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
460 	vk::VkImageMemoryBarrier	initialBarrier			= vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
461 
462 	const vk::VkDeviceSize				bufferSize		= 64;
463 	de::MovePtr<vk::BufferWithMemory>	buffer			= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
464 		vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), vk::MemoryRequirement::HostVisible));
465 
466 	vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
467 
468 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL,
469 		0, DE_NULL, 1, &initialBarrier);
470 
471 	if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
472 	{
473 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
474 	}
475 
476 	if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
477 		vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
478 
479 	vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, false, !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
480 	vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT());
481 
482 	vk::VkDeviceSize offset = 0u;
483 	vk::VkDeviceSize stride = 16u;
484 	vk.cmdBindVertexBuffers2(*cmdBuffer, 0u, 1u, &**buffer, &offset, &bufferSize, &stride);
485 
486 	if (m_params.testType == SHADER_OBJECT)
487 	{
488 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1, taskSupported, meshSupported);
489 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
490 	}
491 	else if (m_params.testType == MAX_PIPELINE)
492 	{
493 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
494 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
495 	}
496 	else if (m_params.testType == MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE)
497 	{
498 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
499 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
500 
501 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2, taskSupported, meshSupported);
502 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
503 
504 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline3);
505 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
506 	}
507 	else if (m_params.testType == SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT)
508 	{
509 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1, taskSupported, meshSupported);
510 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
511 
512 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
513 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
514 
515 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader3, *tescShader, *teseShader, *geomShader, *fragShader3, taskSupported, meshSupported);
516 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
517 	}
518 	else if (m_params.testType == MIN_PIPELINE_SHADER_OBJECT)
519 	{
520 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
521 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
522 
523 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2, taskSupported, meshSupported);
524 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
525 	}
526 	else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
527 	{
528 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1, taskSupported, meshSupported);
529 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
530 	}
531 	else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
532 	{
533 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
534 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1, taskSupported, meshSupported);
535 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
536 	}
537 	else if (m_params.testType == SHADER_OBJECT_MIN_PIPELINE)
538 	{
539 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1, taskSupported, meshSupported);
540 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
541 
542 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
543 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
544 	}
545 	else if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE)
546 	{
547 		vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
548 
549 		vk::VkShaderStageFlagBits stages[] = { vk::VK_SHADER_STAGE_COMPUTE_BIT  };
550 		vk.cmdBindShadersEXT(*cmdBuffer, 1, stages, &*compShader);
551 		vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
552 
553 		vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
554 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
555 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
556 		vk::endRendering(vk, *cmdBuffer);
557 	}
558 	else if (m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
559 	{
560 		vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
561 
562 		vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
563 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1, taskSupported, meshSupported);
564 		vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
565 		vk::endRendering(vk, *cmdBuffer);
566 
567 		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
568 		vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
569 	}
570 
571 	if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
572 		vk::endRendering(vk, *cmdBuffer);
573 
574 	vk::endCommandBuffer(vk, *cmdBuffer);
575 
576 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
577 
578 	const vk::VkBufferImageCopy	copyRegion =
579 	{
580 		0u,																		// VkDeviceSize				bufferOffset;
581 		0u,																		// deUint32					bufferRowLength;
582 		0u,																		// deUint32					bufferImageHeight;
583 		{
584 			vk::VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags		aspect;
585 			0u,																	// deUint32					mipLevel;
586 			0u,																	// deUint32					baseArrayLayer;
587 			1u,																	// deUint32					layerCount;
588 		},																		// VkImageSubresourceLayers	imageSubresource;
589 		{ 0, 0, 0 },															// VkOffset3D				imageOffset;
590 		{renderArea.extent.width, renderArea.extent.height, 1}					// VkExtent3D				imageExtent;
591 	};
592 
593 	vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
594 	vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
595 	vk::endCommandBuffer(vk, *copyCmdBuffer);
596 	submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
597 
598 	if (!verifyImage(colorOutputBuffer, getDrawCount()))
599 		return tcu::TestStatus::fail("Fail");
600 
601 	if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE || m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
602 	{
603 		const vk::Allocation& outputBufferAllocation = outputBuffer.getAllocation();
604 		invalidateAlloc(vk, device, outputBufferAllocation);
605 
606 		const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
607 
608 		for (deUint32 i = 0; i < 4; ++i)
609 		{
610 			if (bufferPtr[i] != i)
611 				return tcu::TestStatus::fail("Fail");
612 		}
613 	}
614 
615 	return tcu::TestStatus::pass("Pass");
616 }
617 
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer,deUint32 drawCount)618 bool ShaderObjectPipelineInteractionInstance::verifyImage (de::MovePtr<vk::BufferWithMemory>& outputBuffer, deUint32 drawCount)
619 {
620 	tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1, (const void*)outputBuffer->getAllocation().getHostPtr());
621 
622 	const tcu::Vec4			red			= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
623 	const tcu::Vec4			green		= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
624 	const tcu::Vec4			blue		= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
625 	const deInt32			width		= resultBuffer.getWidth();
626 	const deInt32			height		= resultBuffer.getHeight();
627 
628 	for (deInt32 j = 0; j < height; ++j)
629 	{
630 		for (deInt32 i = 0; i < width; ++i)
631 		{
632 			const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
633 			if (i < width / 2 && j < height / 2 && drawCount > 0)
634 			{
635 				if (color != red)
636 					return false;
637 			}
638 			else if (i >= width / 2 && j < height / 2 && drawCount > 1)
639 			{
640 				if (color != green)
641 					return false;
642 			}
643 			else if (i < width / 2 && j >= height / 2 && drawCount > 2)
644 			{
645 				if (color != blue)
646 					return false;
647 			}
648 		}
649 	}
650 
651 	return true;
652 }
653 
654 class ShaderObjectPipelineInteractionCase : public vkt::TestCase
655 {
656 public:
ShaderObjectPipelineInteractionCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)657 					ShaderObjectPipelineInteractionCase		(tcu::TestContext& testCtx, const std::string& name, const TestParams& params)
658 															: vkt::TestCase		(testCtx, name)
659 															, m_params			(params)
660 															{}
~ShaderObjectPipelineInteractionCase(void)661 	virtual			~ShaderObjectPipelineInteractionCase	(void) {}
662 
663 	void			checkSupport				(vkt::Context& context) const override;
664 	virtual void	initPrograms				(vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const665 	TestInstance*	createInstance				(Context& context) const override { return new ShaderObjectPipelineInteractionInstance(context, m_params); }
666 private:
667 	TestParams m_params;
668 };
669 
initPrograms(vk::SourceCollections & programCollection) const670 void ShaderObjectPipelineInteractionCase::initPrograms (vk::SourceCollections& programCollection) const
671 {
672 	std::stringstream vert1, vert2, vert3;
673 	std::stringstream geom;
674 	std::stringstream tesc;
675 	std::stringstream tese;
676 	std::stringstream frag1, frag2, frag3;
677 	std::stringstream comp;
678 
679 	vert1
680 		<< "#version 450\n"
681 		<< "void main() {\n"
682 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
683 		<< "    gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.5f), 0.0f, 1.0f);\n"
684 		<< "}\n";
685 	vert2
686 		<< "#version 450\n"
687 		<< "void main() {\n"
688 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
689 		<< "    gl_Position = vec4(pos * 0.5f - vec2(0.0f, 0.5f), 0.0f, 1.0f);\n"
690 		<< "}\n";
691 	vert3
692 		<< "#version 450\n"
693 		<< "void main() {\n"
694 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
695 		<< "    gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.0f), 0.0f, 1.0f);\n"
696 		<< "}\n";
697 
698 	tesc
699 		<< "#version 450\n"
700 		<< "\n"
701 		<< "layout(vertices = 4) out;\n"
702 		<< "\n"
703 		<< "void main (void)\n"
704 		<< "{\n"
705 		<< "    if (gl_InvocationID == 0) {\n"
706 		<< "		gl_TessLevelInner[0] = 1.0;\n"
707 		<< "		gl_TessLevelInner[1] = 1.0;\n"
708 		<< "		gl_TessLevelOuter[0] = 1.0;\n"
709 		<< "		gl_TessLevelOuter[1] = 1.0;\n"
710 		<< "		gl_TessLevelOuter[2] = 1.0;\n"
711 		<< "		gl_TessLevelOuter[3] = 1.0;\n"
712 		<< "	}\n"
713 		<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
714 		<< "}\n";
715 
716 	tese
717 		<< "#version 450\n"
718 		<< "\n"
719 		<< "layout(quads, equal_spacing) in;\n"
720 		<< "\n"
721 		<< "void main (void)\n"
722 		<< "{\n"
723 		<< "	float u = gl_TessCoord.x;\n"
724 		<< "	float v = gl_TessCoord.y;\n"
725 		<< "	float omu = 1.0f - u;\n"
726 		<< "	float omv = 1.0f - v;\n"
727 		<< "	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"
728 		<< "	gl_Position.x *= 2.0f;\n"
729 		<< "}\n";
730 
731 	geom
732 		<< "#version 450\n"
733 		<< "layout(triangles) in;\n"
734 		<< "layout(triangle_strip, max_vertices = 4) out;\n"
735 		<< "\n"
736 		<< "void main(void)\n"
737 		<< "{\n"
738 		<< "    gl_Position = gl_in[0].gl_Position;\n"
739 		<< "	gl_Position.y *= 2.0f;\n"
740 		<< "    EmitVertex();\n"
741 		<< "    gl_Position = gl_in[1].gl_Position;\n"
742 		<< "	gl_Position.y *= 2.0f;\n"
743 		<< "    EmitVertex();\n"
744 		<< "    gl_Position = gl_in[2].gl_Position;\n"
745 		<< "	gl_Position.y *= 2.0f;\n"
746 		<< "    EmitVertex();\n"
747 		<< "    EndPrimitive();\n"
748 		<< "}\n";
749 
750 	frag1
751 		<< "#version 450\n"
752 		<< "layout (location=0) out vec4 outColor;\n"
753 		<< "void main() {\n"
754 		<< "    outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
755 		<< "}\n";
756 	frag2
757 		<< "#version 450\n"
758 		<< "layout (location=0) out vec4 outColor;\n"
759 		<< "void main() {\n"
760 		<< "    outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
761 		<< "}\n";
762 	frag3
763 		<< "#version 450\n"
764 		<< "layout (location=0) out vec4 outColor;\n"
765 		<< "void main() {\n"
766 		<< "    outColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
767 		<< "}\n";
768 
769 	comp
770 		<< "#version 450\n"
771 		<< "layout(local_size_x=16, local_size_x=1, local_size_x=1) in;\n"
772 		<< "layout(binding = 0) buffer Output {\n"
773 		<< "    uint values[16];\n"
774 		<< "} buffer_out;\n\n"
775 		<< "void main() {\n"
776 		<< "    buffer_out.values[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n"
777 		<< "}\n";
778 
779 	programCollection.glslSources.add("vert1") << glu::VertexSource(vert1.str());
780 	programCollection.glslSources.add("vert2") << glu::VertexSource(vert2.str());
781 	programCollection.glslSources.add("vert3") << glu::VertexSource(vert3.str());
782 	programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
783 	programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
784 	programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
785 	programCollection.glslSources.add("frag1") << glu::FragmentSource(frag1.str());
786 	programCollection.glslSources.add("frag2") << glu::FragmentSource(frag2.str());
787 	programCollection.glslSources.add("frag3") << glu::FragmentSource(frag3.str());
788 	programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
789 }
790 
checkSupport(Context & context) const791 void ShaderObjectPipelineInteractionCase::checkSupport (Context& context) const
792 {
793 	context.requireDeviceFunctionality("VK_EXT_shader_object");
794 
795 	context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
796 	context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
797 }
798 
799 
800 class ShaderObjectStageBindingInstance : public vkt::TestInstance
801 {
802 public:
ShaderObjectStageBindingInstance(Context & context,const StageTestParams & params)803 							ShaderObjectStageBindingInstance			(Context& context, const StageTestParams& params)
804 																		: vkt::TestInstance	(context)
805 																		, m_params			(params)
806 																		{}
~ShaderObjectStageBindingInstance(void)807 	virtual					~ShaderObjectStageBindingInstance			(void) {}
808 
809 	tcu::TestStatus			iterate										(void) override;
810 private:
811 	bool					verifyImage									(de::MovePtr<vk::BufferWithMemory>& outputBuffer);
812 	StageTestParams			m_params;
813 
814 	const vk::VkFormat		colorAttachmentFormat	= vk::VK_FORMAT_R8G8B8A8_UNORM;
815 	const vk::VkRect2D		renderArea				= { {0u, 0u, }, {32u, 32u, } };
816 };
817 
iterate(void)818 tcu::TestStatus ShaderObjectStageBindingInstance::iterate (void)
819 {
820 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
821 	const vk::VkDevice					device						= m_context.getDevice();
822 	const vk::VkQueue					queue						= m_context.getUniversalQueue();
823 	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
824 	auto&								alloc						= m_context.getDefaultAllocator();
825 	const auto							deviceExtensions			= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
826 	const bool							tessellationSupported		= m_context.getDeviceFeatures().tessellationShader;
827 	const bool							geometrySupported			= m_context.getDeviceFeatures().geometryShader;
828 	const bool							taskSupported				= m_context.getMeshShaderFeatures().taskShader;
829 	const bool							meshSupported				= m_context.getMeshShaderFeatures().meshShader;
830 
831 	const auto							subresourceRange			= makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
832 
833 	const vk::VkImageCreateInfo			createInfo					=
834 	{
835 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType
836 		DE_NULL,																		// const void*				pNext
837 		0u,																				// VkImageCreateFlags		flags
838 		vk::VK_IMAGE_TYPE_2D,															// VkImageType				imageType
839 		colorAttachmentFormat,															// VkFormat					format
840 		{ renderArea.extent.width, renderArea.extent.height, 1 },						// VkExtent3D				extent
841 		1u,																				// uint32_t					mipLevels
842 		1u,																				// uint32_t					arrayLayers
843 		vk::VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples
844 		vk::VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling
845 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
846 		vk::VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode
847 		0,																				// uint32_t					queueFamilyIndexCount
848 		DE_NULL,																		// const uint32_t*			pQueueFamilyIndices
849 		vk::VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout
850 	};
851 
852 	de::MovePtr<vk::ImageWithMemory>	image						= de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
853 	const auto							imageView					= vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
854 
855 	const vk::VkDeviceSize				colorOutputBufferSize		= renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
856 	de::MovePtr<vk::BufferWithMemory>	colorOutputBuffer			= de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
857 		vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
858 
859 	const vk::VkCommandPoolCreateInfo	cmdPoolInfo =
860 	{
861 		vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// sType
862 		DE_NULL,												// pNext
863 		vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// flags
864 		queueFamilyIndex,										// queuefamilyindex
865 	};
866 
867 	const vk::Move<vk::VkCommandPool>	cmdPool					(createCommandPool(vk, device, &cmdPoolInfo));
868 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
869 	const vk::Move<vk::VkCommandBuffer>	copyCmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
870 
871 	const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
872 		vk::DescriptorSetLayoutBuilder()
873 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_ALL_GRAPHICS)
874 		.build(vk, device));
875 
876 	const vk::Unique<vk::VkDescriptorPool> descriptorPool(
877 		vk::DescriptorPoolBuilder()
878 		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
879 		.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
880 
881 	const auto					topology			= m_params.tessShader ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
882 
883 	const auto					pipelineLayout		= makePipelineLayout(vk, device, descriptorSetLayout.get());
884 	const auto					emptyPipelineLayout	= makePipelineLayout(vk, device);
885 
886 	const auto&					binaries			= m_context.getBinaryCollection();
887 	const auto&					vert				= binaries.get("vert");
888 	const auto&					tesc				= binaries.get("tesc");
889 	const auto&					tese				= binaries.get("tese");
890 	const auto&					geom				= binaries.get("geom");
891 	const auto&					frag				= binaries.get("frag");
892 
893 	const auto&					pipeline_vert		= binaries.get("pipeline_vert");
894 	const auto&					pipeline_tesc		= binaries.get("pipeline_tesc");
895 	const auto&					pipeline_tese		= binaries.get("pipeline_tese");
896 	const auto&					pipeline_geom		= binaries.get("pipeline_geom");
897 	const auto&					pipeline_frag		= binaries.get("pipeline_frag");
898 
899 	vk::VkDescriptorSetLayout	layout				= descriptorSetLayout.get();
900 
901 	vk::VkShaderCreateInfoEXT	vertCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert, tessellationSupported, geometrySupported, &layout);
902 	vk::VkShaderCreateInfoEXT	tescCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, tesc, tessellationSupported, geometrySupported, &layout);
903 	vk::VkShaderCreateInfoEXT	teseCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, tese, tessellationSupported, geometrySupported, &layout);
904 	vk::VkShaderCreateInfoEXT	geomCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported, &layout);
905 	vk::VkShaderCreateInfoEXT	fragCreateInfo		= vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag, tessellationSupported, geometrySupported, &layout);
906 
907 	vk::Move<vk::VkShaderEXT>	vertShader			= vk::createShader(vk, device, vertCreateInfo);
908 	vk::Move<vk::VkShaderEXT>	tescShader;
909 	vk::Move<vk::VkShaderEXT>	teseShader;
910 	vk::Move<vk::VkShaderEXT>	geomShader;
911 	vk::Move<vk::VkShaderEXT>	fragShader			= vk::createShader(vk, device, fragCreateInfo);
912 
913 	vk::Move<vk::VkShaderModule>	vertShaderModule = createShaderModule(vk, device, pipeline_vert);
914 	vk::Move<vk::VkShaderModule>	tescShaderModule;
915 	vk::Move<vk::VkShaderModule>	teseShaderModule;
916 	vk::Move<vk::VkShaderModule>	geomShaderModule;
917 	vk::Move<vk::VkShaderModule>	fragShaderModule = createShaderModule(vk, device, pipeline_frag);
918 
919 	if (m_params.tessShader)
920 	{
921 		tescShader = vk::createShader(vk, device, tescCreateInfo);
922 		teseShader = vk::createShader(vk, device, teseCreateInfo);
923 
924 		tescShaderModule = createShaderModule(vk, device, pipeline_tesc);
925 		teseShaderModule = createShaderModule(vk, device, pipeline_tese);
926 	}
927 	if (m_params.geomShader)
928 	{
929 		geomShader = vk::createShader(vk, device, geomCreateInfo);
930 
931 		geomShaderModule = createShaderModule(vk, device, pipeline_geom);
932 	}
933 
934 	const vk::VkPipelineVertexInputStateCreateInfo		vertexInputStateParams =
935 	{
936 		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
937 		DE_NULL,														// const void*								pNext;
938 		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
939 		0u,																// deUint32									vertexBindingDescriptionCount;
940 		DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
941 		0u,																// deUint32									vertexAttributeDescriptionCount;
942 		DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
943 	};
944 
945 	const vk::VkPipelineTessellationStateCreateInfo		tessStateCreateInfo =
946 	{
947 		vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
948 		DE_NULL,														//	const void*								pNext;
949 		0u,																//	VkPipelineTessellationStateCreateFlags	flags;
950 		4u,																//	uint32_t								patchControlPoints;
951 	};
952 
953 	const vk::VkPipelineInputAssemblyStateCreateInfo	pipelineInputAssemblyStateInfo =
954 	{
955 		vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
956 		DE_NULL,															// const void*                                 pNext;
957 		(vk::VkPipelineInputAssemblyStateCreateFlags)0u,					// VkPipelineInputAssemblyStateCreateFlags     flags;
958 		topology,															// VkPrimitiveTopology                         topology;
959 		VK_FALSE,															// VkBool32                                    primitiveRestartEnable;
960 	};
961 
962 	vk::VkPipelineRenderingCreateInfo					pipelineRenderingCreateInfo =
963 	{
964 		vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,	// VkStructureType	sType
965 		DE_NULL,												// const void*		pNext
966 		0u,														// uint32_t			viewMask
967 		1u,														// uint32_t			colorAttachmentCount
968 		&colorAttachmentFormat,									// const VkFormat*	pColorAttachmentFormats
969 		vk::VK_FORMAT_UNDEFINED,								// VkFormat			depthAttachmentFormat
970 		vk::VK_FORMAT_UNDEFINED,								// VkFormat			stencilAttachmentFormat
971 	};
972 
973 	const vk::VkViewport								viewport				= vk::makeViewport((float)renderArea.extent.width, 0.0f, (float)renderArea.extent.width, (float)renderArea.extent.height, 0.0f, 1.0f);
974 	const vk::VkRect2D									scissor					= vk::makeRect2D(renderArea.extent);
975 
976 	const vk::VkPipelineViewportStateCreateInfo			viewportStateCreateInfo =
977 	{
978 		vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType
979 		DE_NULL,													// const void*                                 pNext
980 		(vk::VkPipelineViewportStateCreateFlags)0u,					// VkPipelineViewportStateCreateFlags          flags
981 		1u,															// deUint32                                    viewportCount
982 		&viewport,													// const VkViewport*                           pViewports
983 		1u,															// deUint32                                    scissorCount
984 		&scissor													// const VkRect2D*                             pScissors
985 	};
986 
987 	const auto								pipeline		= makeGraphicsPipeline(vk, device, emptyPipelineLayout.get(), vertShaderModule.get(), tescShaderModule.get(), teseShaderModule.get(), geomShaderModule.get(), fragShaderModule.get(), VK_NULL_HANDLE, 0u, &vertexInputStateParams, &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, &pipelineRenderingCreateInfo);
988 
989 
990 	const vk::VkDeviceSize					bufferSizeBytes = sizeof(deUint32) * 4;
991 
992 	const vk::Unique<vk::VkDescriptorSet>	descriptorSet	(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
993 	const vk::BufferWithMemory				outputBuffer	(vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
994 
995 	const vk::VkDescriptorBufferInfo		descriptorInfo	= vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
996 	vk::DescriptorSetUpdateBuilder()
997 		.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
998 		.update(vk, device);
999 
1000 	const vk::VkClearValue					clearValue		= vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
1001 	vk::VkImageMemoryBarrier				initialBarrier	= vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1002 
1003 	vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
1004 
1005 	vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL,
1006 		0, DE_NULL, 1, &initialBarrier);
1007 
1008 	vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1009 
1010 	vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1011 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1012 
1013 	vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
1014 	vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false, !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
1015 
1016 	vk::bindGraphicsShaders(vk, *cmdBuffer,
1017 		(m_params.vertShader) ? *vertShader : VK_NULL_HANDLE,
1018 		(m_params.tessShader) ? *tescShader : VK_NULL_HANDLE,
1019 		(m_params.tessShader) ? *teseShader : VK_NULL_HANDLE,
1020 		(m_params.geomShader) ? *geomShader : VK_NULL_HANDLE,
1021 		(m_params.fragShader) ? *fragShader : VK_NULL_HANDLE,
1022 		taskSupported,
1023 		meshSupported);
1024 
1025 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1026 
1027 	vk::endRendering(vk, *cmdBuffer);
1028 
1029 	vk::endCommandBuffer(vk, *cmdBuffer);
1030 
1031 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1032 
1033 	if (m_params.fragShader)
1034 	{
1035 		const vk::VkBufferImageCopy	copyRegion =
1036 		{
1037 			0u,																		// VkDeviceSize				bufferOffset;
1038 			0u,																		// deUint32					bufferRowLength;
1039 			0u,																		// deUint32					bufferImageHeight;
1040 			{
1041 				vk::VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags		aspect;
1042 				0u,																	// deUint32					mipLevel;
1043 				0u,																	// deUint32					baseArrayLayer;
1044 				1u,																	// deUint32					layerCount;
1045 			},																		// VkImageSubresourceLayers	imageSubresource;
1046 			{ 0, 0, 0 },															// VkOffset3D				imageOffset;
1047 			{renderArea.extent.width, renderArea.extent.height, 1}					// VkExtent3D				imageExtent;
1048 		};
1049 
1050 		vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
1051 		vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
1052 		vk::endCommandBuffer(vk, *copyCmdBuffer);
1053 		submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
1054 
1055 		if (!verifyImage(colorOutputBuffer))
1056 			return tcu::TestStatus::fail("Fail");
1057 	}
1058 
1059 	const vk::Allocation& outputBufferAllocation = outputBuffer.getAllocation();
1060 	invalidateAlloc(vk, device, outputBufferAllocation);
1061 
1062 	const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
1063 
1064 	if (m_params.vertShader && bufferPtr[0] != 1u)
1065 		return tcu::TestStatus::fail("Fail");
1066 	if (m_params.tessShader && bufferPtr[1] != 2u)
1067 		return tcu::TestStatus::fail("Fail");
1068 	if (m_params.geomShader && bufferPtr[2] != 3u)
1069 		return tcu::TestStatus::fail("Fail");
1070 
1071 	return tcu::TestStatus::pass("Pass");
1072 }
1073 
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer)1074 bool ShaderObjectStageBindingInstance::verifyImage (de::MovePtr<vk::BufferWithMemory>& outputBuffer)
1075 {
1076 	tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1, (const void*)outputBuffer->getAllocation().getHostPtr());
1077 
1078 	const tcu::Vec4			black		= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1079 	const tcu::Vec4			white		= tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1080 	const deInt32			width		= resultBuffer.getWidth();
1081 	const deInt32			height		= resultBuffer.getHeight();
1082 
1083 	const deInt32			xOffset		= m_params.tessShader ? 4 : 8;
1084 	const deInt32			yOffset		= m_params.geomShader ? 4 : 8;
1085 
1086 	for (deInt32 j = 0; j < height; ++j)
1087 	{
1088 		for (deInt32 i = 0; i < width; ++i)
1089 		{
1090 			const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1091 			if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
1092 			{
1093 				if (color != white)
1094 					return false;
1095 			}
1096 			else
1097 			{
1098 				if (color != black)
1099 					return false;
1100 			}
1101 		}
1102 	}
1103 
1104 	return true;
1105 }
1106 
1107 class ShaderObjectStageBindingCase : public vkt::TestCase
1108 {
1109 public:
ShaderObjectStageBindingCase(tcu::TestContext & testCtx,const std::string & name,const StageTestParams & params)1110 					ShaderObjectStageBindingCase			(tcu::TestContext& testCtx, const std::string& name, const StageTestParams& params)
1111 															: vkt::TestCase		(testCtx, name)
1112 															, m_params			(params)
1113 															{}
~ShaderObjectStageBindingCase(void)1114 	virtual			~ShaderObjectStageBindingCase			(void) {}
1115 
1116 	void			checkSupport							(vkt::Context& context) const override;
1117 	virtual void	initPrograms							(vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const1118 	TestInstance*	createInstance							(Context& context) const override { return new ShaderObjectStageBindingInstance(context, m_params); }
1119 private:
1120 	StageTestParams m_params;
1121 };
1122 
checkSupport(Context & context) const1123 void ShaderObjectStageBindingCase::checkSupport (Context& context) const
1124 {
1125 	context.requireDeviceFunctionality("VK_EXT_shader_object");
1126 
1127 	if (m_params.tessShader)
1128 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1129 
1130 	if (m_params.geomShader)
1131 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1132 }
1133 
initPrograms(vk::SourceCollections & programCollection) const1134 void ShaderObjectStageBindingCase::initPrograms(vk::SourceCollections& programCollection) const
1135 {
1136 	std::stringstream vert;
1137 	std::stringstream geom;
1138 	std::stringstream tesc;
1139 	std::stringstream tese;
1140 	std::stringstream frag;
1141 
1142 	std::stringstream pipeline_vert;
1143 	std::stringstream pipeline_geom;
1144 	std::stringstream pipeline_tesc;
1145 	std::stringstream pipeline_tese;
1146 	std::stringstream pipeline_frag;
1147 
1148 	vert
1149 		<< "#version 450\n"
1150 		<< "layout(set = 0, binding = 0) buffer Output {\n"
1151 		<< "    uint values[4];\n"
1152 		<< "} buffer_out;\n\n"
1153 		<< "void main() {\n"
1154 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1155 		<< "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1156 		<< "	if (gl_VertexIndex == 0u)\n"
1157 		<< "		buffer_out.values[0] = 1u;\n"
1158 		<< "}\n";
1159 
1160 	tesc
1161 		<< "#version 450\n"
1162 		<< "\n"
1163 		<< "layout(vertices = 4) out;\n"
1164 		<< "layout(set = 0, binding = 0) buffer Output {\n"
1165 		<< "    uint values[4];\n"
1166 		<< "} buffer_out;\n\n"
1167 		<< "\n"
1168 		<< "void main (void)\n"
1169 		<< "{\n"
1170 		<< "    if (gl_InvocationID == 0) {\n"
1171 		<< "		gl_TessLevelInner[0] = 1.0;\n"
1172 		<< "		gl_TessLevelInner[1] = 1.0;\n"
1173 		<< "		gl_TessLevelOuter[0] = 1.0;\n"
1174 		<< "		gl_TessLevelOuter[1] = 1.0;\n"
1175 		<< "		gl_TessLevelOuter[2] = 1.0;\n"
1176 		<< "		gl_TessLevelOuter[3] = 1.0;\n"
1177 		<< "		buffer_out.values[1] = 2u;\n"
1178 		<< "	}\n"
1179 		<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1180 		<< "}\n";
1181 
1182 	tese
1183 		<< "#version 450\n"
1184 		<< "\n"
1185 		<< "layout(quads, equal_spacing) in;\n"
1186 		<< "\n"
1187 		<< "void main (void)\n"
1188 		<< "{\n"
1189 		<< "	float u = gl_TessCoord.x;\n"
1190 		<< "	float v = gl_TessCoord.y;\n"
1191 		<< "	float omu = 1.0f - u;\n"
1192 		<< "	float omv = 1.0f - v;\n"
1193 		<< "	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"
1194 		<< "	gl_Position.x *= 1.5f;\n"
1195 		<< "}\n";
1196 
1197 	geom
1198 		<< "#version 450\n"
1199 		<< "layout(triangles) in;\n"
1200 		<< "layout(triangle_strip, max_vertices = 4) out;\n"
1201 		<< "layout(set = 0, binding = 0) buffer Output {\n"
1202 		<< "    uint values[4];\n"
1203 		<< "} buffer_out;\n\n"
1204 		<< "\n"
1205 		<< "void main(void)\n"
1206 		<< "{\n"
1207 		<< "    gl_Position = gl_in[0].gl_Position;\n"
1208 		<< "	gl_Position.y *= 1.5f;\n"
1209 		<< "    EmitVertex();\n"
1210 		<< "    gl_Position = gl_in[1].gl_Position;\n"
1211 		<< "	gl_Position.y *= 1.5f;\n"
1212 		<< "    EmitVertex();\n"
1213 		<< "    gl_Position = gl_in[2].gl_Position;\n"
1214 		<< "	gl_Position.y *= 1.5f;\n"
1215 		<< "    EmitVertex();\n"
1216 		<< "    EndPrimitive();\n"
1217 		<< "    if (gl_InvocationID == 0u)\n"
1218 		<< "		buffer_out.values[2] = 3u;\n"
1219 		<< "}\n";
1220 
1221 	frag
1222 		<< "#version 450\n"
1223 		<< "layout (location=0) out vec4 outColor;\n"
1224 		<< "void main() {\n"
1225 		<< "    outColor = vec4(1.0f);\n"
1226 		<< "}\n";
1227 
1228 	pipeline_vert
1229 		<< "#version 450\n"
1230 		<< "void main() {\n"
1231 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1232 		<< "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1233 		<< "}\n";
1234 
1235 	pipeline_tesc
1236 		<< "#version 450\n"
1237 		<< "\n"
1238 		<< "layout(vertices = 4) out;\n"
1239 		<< "\n"
1240 		<< "void main (void)\n"
1241 		<< "{\n"
1242 		<< "    if (gl_InvocationID == 0) {\n"
1243 		<< "		gl_TessLevelInner[0] = 1.0;\n"
1244 		<< "		gl_TessLevelInner[1] = 1.0;\n"
1245 		<< "		gl_TessLevelOuter[0] = 1.0;\n"
1246 		<< "		gl_TessLevelOuter[1] = 1.0;\n"
1247 		<< "		gl_TessLevelOuter[2] = 1.0;\n"
1248 		<< "		gl_TessLevelOuter[3] = 1.0;\n"
1249 		<< "	}\n"
1250 		<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1251 		<< "}\n";
1252 
1253 	pipeline_tese
1254 		<< "#version 450\n"
1255 		<< "\n"
1256 		<< "layout(quads, equal_spacing) in;\n"
1257 		<< "\n"
1258 		<< "void main (void)\n"
1259 		<< "{\n"
1260 		<< "	float u = gl_TessCoord.x;\n"
1261 		<< "	float v = gl_TessCoord.y;\n"
1262 		<< "	float omu = 1.0f - u;\n"
1263 		<< "	float omv = 1.0f - v;\n"
1264 		<< "	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"
1265 		<< "	gl_Position.x *= 0.5f;\n"
1266 		<< "	gl_Position.y *= 0.5f;\n"
1267 		<< "}\n";
1268 
1269 	pipeline_geom
1270 		<< "#version 450\n"
1271 		<< "layout(triangles) in;\n"
1272 		<< "layout(triangle_strip, max_vertices = 4) out;\n"
1273 		<< "\n"
1274 		<< "void main(void)\n"
1275 		<< "{\n"
1276 		<< "    gl_Position = gl_in[0].gl_Position;\n"
1277 		<< "	gl_Position.x += 0.25f;\n"
1278 		<< "	gl_Position.y += 0.25f;\n"
1279 		<< "    EmitVertex();\n"
1280 		<< "    gl_Position = gl_in[1].gl_Position;\n"
1281 		<< "	gl_Position.x += 0.25f;\n"
1282 		<< "	gl_Position.y += 0.25f;\n"
1283 		<< "    EmitVertex();\n"
1284 		<< "    gl_Position = gl_in[2].gl_Position;\n"
1285 		<< "	gl_Position.x += 0.25f;\n"
1286 		<< "	gl_Position.y += 0.25f;\n"
1287 		<< "    EmitVertex();\n"
1288 		<< "    EndPrimitive();\n"
1289 		<< "}\n";
1290 
1291 	pipeline_frag
1292 		<< "#version 450\n"
1293 		<< "layout (location=0) out vec4 outColor;\n"
1294 		<< "void main() {\n"
1295 		<< "    outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
1296 		<< "}\n";
1297 
1298 	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
1299 	programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
1300 	programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
1301 	programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
1302 	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
1303 
1304 	programCollection.glslSources.add("pipeline_vert") << glu::VertexSource(pipeline_vert.str());
1305 	programCollection.glslSources.add("pipeline_tesc") << glu::TessellationControlSource(pipeline_tesc.str());
1306 	programCollection.glslSources.add("pipeline_tese") << glu::TessellationEvaluationSource(pipeline_tese.str());
1307 	programCollection.glslSources.add("pipeline_geom") << glu::GeometrySource(pipeline_geom.str());
1308 	programCollection.glslSources.add("pipeline_frag") << glu::FragmentSource(pipeline_frag.str());
1309 }
1310 
1311 }
1312 
createShaderObjectPipelineInteractionTests(tcu::TestContext & testCtx)1313 tcu::TestCaseGroup* createShaderObjectPipelineInteractionTests (tcu::TestContext& testCtx)
1314 {
1315 	de::MovePtr<tcu::TestCaseGroup> pipelineInteractionGroup(new tcu::TestCaseGroup(testCtx, "pipeline_interaction"));
1316 
1317 	const struct
1318 	{
1319 		TestType	testType;
1320 		const char* name;
1321 	} tests[] =
1322 	{
1323 		{ SHADER_OBJECT,									"shader_object"										},
1324 		{ MAX_PIPELINE,										"max_pipeline"										},
1325 		{ MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE,			"max_pipeline_shader_object_max_pipeline"			},
1326 		{ SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT,			"shader_object_max_pipeline_shader_object"			},
1327 		{ MIN_PIPELINE_SHADER_OBJECT,						"min_pipeline_shader_object"						},
1328 		{ SHADER_OBJECT_MIN_PIPELINE,						"shader_object_min_pipeline"						},
1329 		{ RENDER_PASS_PIPELINE_SHADER_OBJECT,				"render_pass_pipeline_shader_object"				},
1330 		{ RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN,	"render_pass_pipeline_shader_object_after_begin"	},
1331 		{ COMPUTE_SHADER_OBJECT_MIN_PIPELINE,				"compute_shader_object_min_pipeline"				},
1332 		{ SHADER_OBJECT_COMPUTE_PIPELINE,					"shader_object_compute_pipeline"					},
1333 	};
1334 
1335 	for (const auto& test : tests)
1336 	{
1337 		TestParams params;
1338 		params.testType = test.testType;
1339 
1340 		pipelineInteractionGroup->addChild(new ShaderObjectPipelineInteractionCase(testCtx, test.name, params));
1341 	}
1342 
1343 	const struct
1344 	{
1345 		StageTestParams	shaders;
1346 		const char* name;
1347 	} shaderBindTests[] =
1348 	{
1349 		{ { true, false, false, false },	"vert"	},
1350 		{ { true, true, false, false },		"vert_tess"	},
1351 		{ { true, false, true, false },		"vert_geom"	},
1352 		{ { true, false, false, true },		"vert_frag"	},
1353 		{ { true, true, true, false },		"vert_tess_geom"	},
1354 		{ { true, true, false, true },		"vert_tess_frag"	},
1355 		{ { true, false, true, true },		"vert_geom_frag"	},
1356 		{ { true, true, true, true },		"vert_tess_geom_frag"	},
1357 	};
1358 
1359 	for (const auto& shaderBindTest : shaderBindTests)
1360 	{
1361 		pipelineInteractionGroup->addChild(new ShaderObjectStageBindingCase(testCtx, shaderBindTest.name, shaderBindTest.shaders));
1362 	}
1363 
1364 	return pipelineInteractionGroup.release();
1365 }
1366 
1367 } // ShaderObject
1368 } // vkt
1369