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