• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
6  * Copyright (c) 2023 LunarG, Inc.
7  * Copyright (c) 2023 Nintendo
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Wrapper that can construct monolithic pipeline or use
24           VK_EXT_graphics_pipeline_library for pipeline construction or use
25 		  VK_EXT_shader_object for shader objects.
26  *//*--------------------------------------------------------------------*/
27 
28 #include "vkRefUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "deSharedPtr.hpp"
31 #include "deSTLUtil.hpp"
32 #include "tcuVector.hpp"
33 #include "tcuVectorType.hpp"
34 #include "tcuMaybe.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPipelineConstructionUtil.hpp"
42 #include "vkBarrierUtil.hpp"
43 
44 #include <memory>
45 #include <set>
46 #include <map>
47 
48 namespace vk
49 {
50 
51 namespace
52 {
53 
54 enum PipelineSetupState
55 {
56 	PSS_NONE						= 0x00000000,
57 	PSS_VERTEX_INPUT_INTERFACE		= 0x00000001,
58 	PSS_PRE_RASTERIZATION_SHADERS	= 0x00000002,
59 	PSS_FRAGMENT_SHADER				= 0x00000004,
60 	PSS_FRAGMENT_OUTPUT_INTERFACE	= 0x00000008,
61 };
62 
63 using TessellationDomainOriginStatePtr = std::unique_ptr<VkPipelineTessellationDomainOriginStateCreateInfo>;
64 
65 } // anonymous namespace
66 
67 static const VkVertexInputBindingDescription defaultVertexInputBindingDescription
68 {
69 	0u,																// deUint32										binding
70 	sizeof(tcu::Vec4),												// deUint32										stride
71 	VK_VERTEX_INPUT_RATE_VERTEX,									// VkVertexInputRate							inputRate
72 };
73 
74 static const VkVertexInputAttributeDescription defaultVertexInputAttributeDescription
75 {
76 	0u,																// deUint32										location
77 	0u,																// deUint32										binding
78 	VK_FORMAT_R32G32B32A32_SFLOAT,									// VkFormat										format
79 	0u																// deUint32										offset
80 };
81 
82 static const VkPipelineVertexInputStateCreateInfo defaultVertexInputState
83 {
84 	VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType								sType
85 	DE_NULL,														// const void*									pNext
86 	(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags		flags
87 	1u,																// deUint32										vertexBindingDescriptionCount
88 	&defaultVertexInputBindingDescription,							// const VkVertexInputBindingDescription*		pVertexBindingDescriptions
89 	1u,																// deUint32										vertexAttributeDescriptionCount
90 	&defaultVertexInputAttributeDescription							// const VkVertexInputAttributeDescription*		pVertexAttributeDescriptions
91 };
92 
93 static const VkStencilOpState defaultStencilOpState
94 {
95 	VK_STENCIL_OP_KEEP,												// VkStencilOp									failOp
96 	VK_STENCIL_OP_KEEP,												// VkStencilOp									passOp
97 	VK_STENCIL_OP_KEEP,												// VkStencilOp									depthFailOp
98 	VK_COMPARE_OP_NEVER,											// VkCompareOp									compareOp
99 	0u,																// deUint32										compareMask
100 	0u,																// deUint32										writeMask
101 	0u																// deUint32										reference
102 };
103 
104 static const VkPipelineDepthStencilStateCreateInfo defaultDepthStencilState
105 {
106 	VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType								sType
107 	DE_NULL,														// const void*									pNext
108 	0u,																// VkPipelineDepthStencilStateCreateFlags		flags
109 	VK_FALSE,														// VkBool32										depthTestEnable
110 	VK_FALSE,														// VkBool32										depthWriteEnable
111 	VK_COMPARE_OP_LESS_OR_EQUAL,									// VkCompareOp									depthCompareOp
112 	VK_FALSE,														// VkBool32										depthBoundsTestEnable
113 	VK_FALSE,														// VkBool32										stencilTestEnable
114 	defaultStencilOpState,											// VkStencilOpState								front
115 	defaultStencilOpState,											// VkStencilOpState								back
116 	0.0f,															// float										minDepthBounds
117 	1.0f,															// float										maxDepthBounds
118 };
119 
120 static const VkPipelineMultisampleStateCreateInfo defaultMultisampleState
121 {
122 	VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType								sType
123 	DE_NULL,														// const void*									pNext
124 	0u,																// VkPipelineMultisampleStateCreateFlags		flags
125 	VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits						rasterizationSamples
126 	VK_FALSE,														// VkBool32										sampleShadingEnable
127 	1.0f,															// float										minSampleShading
128 	DE_NULL,														// const VkSampleMask*							pSampleMask
129 	VK_FALSE,														// VkBool32										alphaToCoverageEnable
130 	VK_FALSE														// VkBool32										alphaToOneEnable
131 };
132 
133 static const VkPipelineColorBlendAttachmentState defaultColorBlendAttachmentState
134 {
135 	VK_FALSE,														// VkBool32										blendEnable
136 	VK_BLEND_FACTOR_ZERO,											// VkBlendFactor								srcColorBlendFactor
137 	VK_BLEND_FACTOR_ZERO,											// VkBlendFactor								dstColorBlendFactor
138 	VK_BLEND_OP_ADD,												// VkBlendOp									colorBlendOp
139 	VK_BLEND_FACTOR_ZERO,											// VkBlendFactor								srcAlphaBlendFactor
140 	VK_BLEND_FACTOR_ZERO,											// VkBlendFactor								dstAlphaBlendFactor
141 	VK_BLEND_OP_ADD,												// VkBlendOp									alphaBlendOp
142 	0xf																// VkColorComponentFlags						colorWriteMask
143 };
144 
145 static const VkPipelineColorBlendStateCreateInfo defaultColorBlendState
146 {
147 	VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType
148 	DE_NULL,														// const void*									pNext
149 	0u,																// VkPipelineColorBlendStateCreateFlags			flags
150 	VK_FALSE,														// VkBool32										logicOpEnable
151 	VK_LOGIC_OP_CLEAR,												// VkLogicOp									logicOp
152 	1u,																// deUint32										attachmentCount
153 	&defaultColorBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments
154 	{ 0.0f, 0.0f, 0.0f, 0.0f }										// float										blendConstants[4]
155 };
156 
157 namespace
158 {
159 #ifndef CTS_USES_VULKANSC
makeGraphicsPipelineLibraryCreateInfo(const VkGraphicsPipelineLibraryFlagsEXT flags)160 VkGraphicsPipelineLibraryCreateInfoEXT makeGraphicsPipelineLibraryCreateInfo(const VkGraphicsPipelineLibraryFlagsEXT flags)
161 {
162 	return
163 	{
164 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,	// VkStructureType						sType;
165 		DE_NULL,														// void*								pNext;
166 		flags,															// VkGraphicsPipelineLibraryFlagsEXT	flags;
167 	};
168 }
169 #endif // CTS_USES_VULKANSC
170 
makeGraphicsPipeline(const DeviceInterface & vk,VkDevice device,VkPipelineCache pipelineCache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator=nullptr)171 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&				vk,
172 									   VkDevice								device,
173 									   VkPipelineCache						pipelineCache,
174 									   const VkGraphicsPipelineCreateInfo*	pCreateInfo,
175 									   const VkAllocationCallbacks*			pAllocator = nullptr)
176 {
177 	VkPipeline	object					= 0;
178 	const auto	retcode					= vk.createGraphicsPipelines(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object);
179 
180 #ifndef CTS_USES_VULKANSC
181 	const bool	allowCompileRequired	= ((pCreateInfo->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0u);
182 
183 	if (allowCompileRequired && retcode == VK_PIPELINE_COMPILE_REQUIRED)
184 		throw PipelineCompileRequiredError("createGraphicsPipelines returned VK_PIPELINE_COMPILE_REQUIRED");
185 #endif // CTS_USES_VULKANSC
186 
187 	VK_CHECK(retcode);
188 	return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
189 }
190 
191 } // anonymous
192 
isConstructionTypeLibrary(PipelineConstructionType pipelineConstructionType)193 bool isConstructionTypeLibrary (PipelineConstructionType pipelineConstructionType)
194 {
195 	return pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY ||
196 		   pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY;
197 }
198 
isConstructionTypeShaderObject(PipelineConstructionType pipelineConstructionType)199 bool isConstructionTypeShaderObject (PipelineConstructionType pipelineConstructionType) {
200 	return pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_SPIRV ||
201 		   pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY ||
202 		   pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV ||
203 		   pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
204 }
205 
checkPipelineConstructionRequirements(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,PipelineConstructionType pipelineConstructionType)206 void checkPipelineConstructionRequirements (const InstanceInterface&		vki,
207 											VkPhysicalDevice				physicalDevice,
208 											PipelineConstructionType		pipelineConstructionType)
209 {
210 	if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
211 		return;
212 
213 	const auto& supportedExtensions = enumerateCachedDeviceExtensionProperties(vki, physicalDevice);
214 
215 	if (isConstructionTypeShaderObject(pipelineConstructionType))
216 	{
217 		if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_shader_object")))
218 			TCU_THROW(NotSupportedError, "VK_EXT_shader_object not supported");
219 		return;
220 	}
221 
222 	if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_graphics_pipeline_library")))
223 		TCU_THROW(NotSupportedError, "VK_EXT_graphics_pipeline_library not supported");
224 }
225 
translateCreateFlag(VkPipelineCreateFlags flagToTranslate)226 PipelineCreateFlags2 translateCreateFlag(VkPipelineCreateFlags flagToTranslate)
227 {
228 	return (PipelineCreateFlags2)flagToTranslate;
229 }
230 
addToChain(void ** structThatStartsChain,void * structToAddAtTheEnd)231 void addToChain(void** structThatStartsChain, void* structToAddAtTheEnd)
232 {
233 	DE_ASSERT(structThatStartsChain);
234 
235 	if (structToAddAtTheEnd == DE_NULL)
236 		return;
237 
238 	// Cast to the base out structure which has a non-const pNext pointer.
239 	auto* structToAddAtTheEndCasted = reinterpret_cast<VkBaseOutStructure*>(structToAddAtTheEnd);
240 
241 	// make sure that pNext pointer of structure that is added to chain is empty;
242 	// we are construting chains on our own and there are cases that use same
243 	// structure for multiple instances of GraphicsPipelineWrapper
244 	structToAddAtTheEndCasted->pNext = DE_NULL;
245 
246 	deUint32	safetyCouter	= 10u;
247 	void**		structInChain	= structThatStartsChain;
248 
249 	do
250 	{
251 		// check if this is free spot
252 		if (*structInChain == DE_NULL)
253 		{
254 			// attach new structure at the end
255 			*structInChain = structToAddAtTheEndCasted;
256 			return;
257 		}
258 
259 		// Cast to the base out structure which has a non-const pNext pointer.
260 		auto* gpl = reinterpret_cast<VkBaseOutStructure*>(*structInChain);
261 
262 		// move structure pointer one position down the pNext chain
263 		structInChain = reinterpret_cast<void**>(&gpl->pNext);
264 	}
265 	while (--safetyCouter);
266 
267 	// probably safetyCouter is to small
268 	DE_ASSERT(false);
269 }
270 
271 namespace {
272 	using PipelineShaderStageModuleIdPtr = std::unique_ptr<PipelineShaderStageModuleIdentifierCreateInfoWrapper>;
273 }
274 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const std::vector<vk::Move<VkDescriptorSetLayout>> & descriptorSetLayout)275 PipelineLayoutWrapper::PipelineLayoutWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const std::vector<vk::Move<VkDescriptorSetLayout>>& descriptorSetLayout)
276 	: m_pipelineConstructionType	(pipelineConstructionType)
277 	, m_vk							(&vk)
278 	, m_device						(device)
279 	, m_flags						((VkPipelineLayoutCreateFlags)0u)
280 	, m_setLayoutCount				((deUint32)descriptorSetLayout.size())
281 	, m_pushConstantRangeCount		(0u)
282 	, m_pushConstantRanges			()
283 {
284 #ifndef CTS_USES_VULKANSC
285 	if (isConstructionTypeShaderObject(pipelineConstructionType))
286 		m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
287 #endif
288 
289 	m_setLayouts.resize(m_setLayoutCount);
290 	for (deUint32 i = 0; i < m_setLayoutCount; ++i)
291 		m_setLayouts[i] = *descriptorSetLayout[i];
292 
293 	VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
294 	createInfo.flags = m_flags;
295 	createInfo.setLayoutCount = m_setLayoutCount;
296 	createInfo.pSetLayouts = de::dataOrNull(m_setLayouts);
297 	createInfo.pushConstantRangeCount = m_pushConstantRangeCount;
298 	createInfo.pPushConstantRanges = de::dataOrNull(m_pushConstantRanges);
299 	m_pipelineLayout = createPipelineLayout(vk, device, &createInfo);
300 }
301 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,deUint32 setLayoutCount,const VkDescriptorSetLayout * descriptorSetLayout)302 PipelineLayoutWrapper::PipelineLayoutWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, deUint32 setLayoutCount, const VkDescriptorSetLayout* descriptorSetLayout)
303 	: m_pipelineConstructionType	(pipelineConstructionType)
304 	, m_vk							(&vk)
305 	, m_device						(device)
306 	, m_flags						((VkPipelineLayoutCreateFlags)0u)
307 	, m_setLayoutCount				(setLayoutCount)
308 	, m_pushConstantRangeCount		(0u)
309 	, m_pushConstantRanges			()
310 {
311 #ifndef CTS_USES_VULKANSC
312 	if (isConstructionTypeShaderObject(pipelineConstructionType))
313 		m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
314 #endif
315 
316 	m_setLayouts.resize(m_setLayoutCount);
317 	for (deUint32 i = 0; i < m_setLayoutCount; ++i)
318 		m_setLayouts[i] = descriptorSetLayout[i];
319 
320 	VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
321 	createInfo.flags = m_flags;
322 	createInfo.setLayoutCount = m_setLayoutCount;
323 	createInfo.pSetLayouts = de::dataOrNull(m_setLayouts);
324 	createInfo.pushConstantRangeCount = m_pushConstantRangeCount;
325 	createInfo.pPushConstantRanges = de::dataOrNull(m_pushConstantRanges);
326 	m_pipelineLayout = createPipelineLayout(vk, device, &createInfo);
327 }
328 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkDescriptorSetLayout descriptorSetLayout,const VkPushConstantRange * pushConstantRange)329 PipelineLayoutWrapper::PipelineLayoutWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkDescriptorSetLayout descriptorSetLayout, const VkPushConstantRange* pushConstantRange)
330 	: m_pipelineConstructionType	(pipelineConstructionType)
331 	, m_vk(&vk)
332 	, m_device(device)
333 	, m_flags						((VkPipelineLayoutCreateFlags)0u)
334 {
335 #ifndef CTS_USES_VULKANSC
336 	if (isConstructionTypeShaderObject(pipelineConstructionType))
337 		m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
338 #endif
339 
340 	if (descriptorSetLayout == VK_NULL_HANDLE)
341 	{
342 		m_setLayoutCount = 0;
343 	}
344 	else
345 	{
346 		m_setLayoutCount = 1;
347 		m_setLayouts.resize(1);
348 		m_setLayouts[0] = descriptorSetLayout;
349 	}
350 	if (pushConstantRange == DE_NULL)
351 	{
352 		m_pushConstantRangeCount = 0;
353 	}
354 	else
355 	{
356 		m_pushConstantRangeCount = 1;
357 		m_pushConstantRanges.resize(1);
358 		m_pushConstantRanges[0] = *pushConstantRange;
359 	}
360 
361 	VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
362 	createInfo.flags = m_flags;
363 	createInfo.setLayoutCount = m_setLayoutCount;
364 	createInfo.pSetLayouts = de::dataOrNull(m_setLayouts);
365 	createInfo.pushConstantRangeCount = m_pushConstantRangeCount;
366 	createInfo.pPushConstantRanges = de::dataOrNull(m_pushConstantRanges);
367 	m_pipelineLayout = createPipelineLayout(vk, device, &createInfo);
368 }
369 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks *)370 PipelineLayoutWrapper::PipelineLayoutWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks*)
371 	: m_pipelineConstructionType	(pipelineConstructionType)
372 	, m_vk							(&vk)
373 	, m_device						(device)
374 	, m_flags						(pCreateInfo->flags)
375 	, m_setLayoutCount				(pCreateInfo->setLayoutCount)
376 	, m_pushConstantRangeCount		(pCreateInfo->pushConstantRangeCount)
377 {
378 #ifndef CTS_USES_VULKANSC
379 	if (isConstructionTypeShaderObject(pipelineConstructionType))
380 		m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
381 #endif
382 
383 	m_setLayouts.resize(pCreateInfo->setLayoutCount);
384 	for (deUint32 i = 0; i < pCreateInfo->setLayoutCount; ++i)
385 		m_setLayouts[i] = pCreateInfo->pSetLayouts[i];
386 	m_pushConstantRanges.resize(pCreateInfo->pushConstantRangeCount);
387 	for (deUint32 i = 0; i < pCreateInfo->pushConstantRangeCount; ++i)
388 		m_pushConstantRanges[i] = pCreateInfo->pPushConstantRanges[i];
389 
390 	VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
391 	createInfo.flags = m_flags;
392 	createInfo.setLayoutCount = m_setLayoutCount;
393 	createInfo.pSetLayouts = m_setLayouts.data();
394 	createInfo.pushConstantRangeCount = m_pushConstantRangeCount;
395 	createInfo.pPushConstantRanges = m_pushConstantRanges.data();
396 	m_pipelineLayout = createPipelineLayout(vk, device, &createInfo);
397 }
398 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,const VkDevice device,const deUint32 setLayoutCount,const VkDescriptorSetLayout * descriptorSetLayout,const deUint32 pushConstantRangeCount,const VkPushConstantRange * pPushConstantRanges,const VkPipelineLayoutCreateFlags flags)399 PipelineLayoutWrapper::PipelineLayoutWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, const VkDevice device, const deUint32 setLayoutCount, const VkDescriptorSetLayout* descriptorSetLayout, const deUint32 pushConstantRangeCount, const VkPushConstantRange* pPushConstantRanges, const VkPipelineLayoutCreateFlags flags)
400 	: m_pipelineConstructionType	(pipelineConstructionType)
401 	, m_vk							(&vk)
402 	, m_device						(device)
403 	, m_flags						(flags)
404 	, m_setLayoutCount				(setLayoutCount)
405 	, m_pushConstantRangeCount		(pushConstantRangeCount)
406 {
407 #ifndef CTS_USES_VULKANSC
408 	if (isConstructionTypeShaderObject(pipelineConstructionType))
409 		m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
410 #endif
411 
412 	m_setLayouts.resize(m_setLayoutCount);
413 	m_pushConstantRanges.resize(m_pushConstantRangeCount);
414 	for (deUint32 i = 0; i < m_setLayoutCount; ++i)
415 		m_setLayouts[i] = descriptorSetLayout[i];
416 	for (deUint32 i = 0; i < m_pushConstantRangeCount; ++i)
417 		m_pushConstantRanges[i] = pPushConstantRanges[i];
418 
419 	VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
420 	createInfo.flags = m_flags;
421 	createInfo.setLayoutCount = m_setLayoutCount;
422 	createInfo.pSetLayouts = m_setLayouts.data();
423 	createInfo.pushConstantRangeCount = m_pushConstantRangeCount;
424 	createInfo.pPushConstantRanges = m_pushConstantRanges.data();
425 	m_pipelineLayout = createPipelineLayout(vk, device, &createInfo);
426 }
427 
operator =(PipelineLayoutWrapper && rhs)428 PipelineLayoutWrapper& PipelineLayoutWrapper::operator=	(PipelineLayoutWrapper&& rhs)
429 {
430 	m_pipelineConstructionType = rhs.m_pipelineConstructionType;
431 	m_vk = rhs.m_vk;
432 	m_device = rhs.m_device;
433 	m_flags = rhs.m_flags;
434 	m_setLayoutCount = rhs.m_setLayoutCount;
435 	m_setLayouts = std::move(rhs.m_setLayouts);
436 	m_pushConstantRangeCount = rhs.m_pushConstantRangeCount;
437 	m_pushConstantRanges = std::move(rhs.m_pushConstantRanges);
438 	m_pipelineLayout = rhs.m_pipelineLayout;
439 
440 	return *this;
441 }
442 
bindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets) const443 void PipelineLayoutWrapper::bindDescriptorSets (VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) const
444 {
445 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
446 	{
447 		m_vk->cmdBindDescriptorSets(commandBuffer, pipelineBindPoint, *m_pipelineLayout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
448 	}
449 	else
450 	{
451 		//m_vk->cmdBindDescriptorSets2EXT(commandBuffer, &m_setLayouts[firstSet], vk::VK_SHADER_STAGE_ALL_GRAPHICS, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
452 		m_vk->cmdBindDescriptorSets(commandBuffer, pipelineBindPoint, *m_pipelineLayout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
453 	}
454 }
455 
456 #ifndef CTS_USES_VULKANSC
SubpassDependency(const VkSubpassDependency & dependency)457 RenderPassWrapper::SubpassDependency::SubpassDependency (const VkSubpassDependency& dependency)
458 	: srcSubpass		(dependency.srcSubpass)
459 	, dstSubpass		(dependency.dstSubpass)
460 	, srcStageMask		(dependency.srcStageMask)
461 	, dstStageMask		(dependency.dstStageMask)
462 	, srcAccessMask		(dependency.srcAccessMask)
463 	, dstAccessMask		(dependency.dstAccessMask)
464 	, dependencyFlags	(dependency.dependencyFlags)
465 	, sync2				(false)
466 {
467 }
468 
SubpassDependency(const VkSubpassDependency2 & dependency)469 RenderPassWrapper::SubpassDependency::SubpassDependency (const VkSubpassDependency2& dependency)
470 	: srcSubpass		(dependency.srcSubpass)
471 	, dstSubpass		(dependency.dstSubpass)
472 	, srcStageMask		(0u)
473 	, dstStageMask		(0u)
474 	, srcAccessMask		(0u)
475 	, dstAccessMask		(0u)
476 	, dependencyFlags	(dependency.dependencyFlags)
477 	, sync2				(false)
478 {
479 	DE_ASSERT(dependency.viewOffset == 0);
480 	const auto memBarrier = findStructure<VkMemoryBarrier2>(dependency.pNext);
481 	if (memBarrier)
482 	{
483 		srcStageMask	= memBarrier->srcStageMask;
484 		dstStageMask	= memBarrier->dstStageMask;
485 		srcAccessMask	= memBarrier->srcAccessMask;
486 		dstAccessMask	= memBarrier->dstAccessMask;
487 		sync2			= true;
488 	}
489 	else
490 	{
491 		srcStageMask	= dependency.srcStageMask;
492 		dstStageMask	= dependency.dstStageMask;
493 		srcAccessMask	= dependency.srcAccessMask;
494 		dstAccessMask	= dependency.dstAccessMask;
495 	}
496 }
497 #endif // CTS_USES_VULKANSC
498 
RenderPassWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkRenderPassCreateInfo * pCreateInfo)499 RenderPassWrapper::RenderPassWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo* pCreateInfo)
500 	: m_pipelineConstructionType	(pipelineConstructionType)
501 #ifndef CTS_USES_VULKANSC
502 	, m_renderingInfo				()
503 	, m_secondaryCommandBuffers		(false)
504 #endif
505 {
506 	if (!isConstructionTypeShaderObject(pipelineConstructionType))
507 	{
508 		m_renderPass = vk::createRenderPass(vk, device, pCreateInfo);
509 	}
510 	else
511 	{
512 #ifndef CTS_USES_VULKANSC
513 		const auto multiView = findStructure<VkRenderPassMultiviewCreateInfo>(pCreateInfo->pNext);
514 		if (multiView)
515 		{
516 			for (deUint32 i = 0; i < multiView->subpassCount; ++i)
517 				m_viewMasks.push_back(multiView->pViewMasks[i]);
518 		}
519 
520 		m_attachments.resize(pCreateInfo->attachmentCount);
521 		m_layouts.resize(pCreateInfo->attachmentCount);
522 		for (deUint32 i = 0; i < pCreateInfo->attachmentCount; ++i)
523 		{
524 			m_attachments[i] = vk::initVulkanStructure();
525 			m_attachments[i].flags = pCreateInfo->pAttachments[i].flags;
526 			m_attachments[i].format = pCreateInfo->pAttachments[i].format;
527 			m_attachments[i].samples = pCreateInfo->pAttachments[i].samples;
528 			m_attachments[i].loadOp = pCreateInfo->pAttachments[i].loadOp;
529 			m_attachments[i].storeOp = pCreateInfo->pAttachments[i].storeOp;
530 			m_attachments[i].stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp;
531 			m_attachments[i].stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp;
532 			m_attachments[i].initialLayout = pCreateInfo->pAttachments[i].initialLayout;
533 			m_attachments[i].finalLayout = pCreateInfo->pAttachments[i].finalLayout;
534 			m_layouts[i] = pCreateInfo->pAttachments[i].initialLayout;
535 		}
536 
537 		m_subpasses.resize(pCreateInfo->subpassCount);
538 		for (deUint32 s = 0; s < pCreateInfo->subpassCount; ++s)
539 		{
540 			// Input attachments are not supported with dynamic rendering
541 			DE_ASSERT(pCreateInfo->pSubpasses[s].inputAttachmentCount == 0);
542 			auto& subpass = m_subpasses[s];
543 			subpass.m_colorAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
544 
545 			for (deUint32 i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
546 			{
547 				deUint32 j = pCreateInfo->pSubpasses[s].pColorAttachments[i].attachment;
548 				if (j < pCreateInfo->attachmentCount)
549 				{
550 					subpass.m_colorAttachments[i].attachmentInfo = vk::initVulkanStructure();
551 					subpass.m_colorAttachments[i].index = j;
552 					subpass.m_colorAttachments[i].format = pCreateInfo->pAttachments[j].format;
553 
554 					subpass.m_colorAttachments[i].attachmentInfo.imageView = DE_NULL;
555 					subpass.m_colorAttachments[i].attachmentInfo.imageLayout = pCreateInfo->pSubpasses[s].pColorAttachments[i].layout;
556 					subpass.m_colorAttachments[i].attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
557 					subpass.m_colorAttachments[i].attachmentInfo.resolveImageView = DE_NULL;
558 					subpass.m_colorAttachments[i].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
559 					subpass.m_colorAttachments[i].attachmentInfo.loadOp = pCreateInfo->pAttachments[j].loadOp;
560 					subpass.m_colorAttachments[i].attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
561 					subpass.m_colorAttachments[i].attachmentInfo.clearValue = {};
562 				}
563 				else
564 				{
565 					subpass.m_colorAttachments[i].index = VK_ATTACHMENT_UNUSED;
566 				}
567 			}
568 
569 			if (pCreateInfo->pSubpasses[s].pDepthStencilAttachment != DE_NULL)
570 			{
571 				deUint32 j = pCreateInfo->pSubpasses[s].pDepthStencilAttachment->attachment;
572 				if (j < pCreateInfo->attachmentCount)
573 				{
574 					subpass.m_depthStencilAttachment.attachmentInfo = vk::initVulkanStructure();
575 					subpass.m_depthStencilAttachment.index = j;
576 					subpass.m_depthStencilAttachment.format = pCreateInfo->pAttachments[j].format;
577 
578 					subpass.m_depthStencilAttachment.attachmentInfo.imageView = DE_NULL;
579 					subpass.m_depthStencilAttachment.attachmentInfo.imageLayout = pCreateInfo->pSubpasses[s].pDepthStencilAttachment->layout;
580 					subpass.m_depthStencilAttachment.attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
581 					subpass.m_depthStencilAttachment.attachmentInfo.resolveImageView = DE_NULL;
582 					subpass.m_depthStencilAttachment.attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
583 					subpass.m_depthStencilAttachment.attachmentInfo.loadOp = pCreateInfo->pAttachments[j].loadOp;
584 					subpass.m_depthStencilAttachment.attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
585 					subpass.m_depthStencilAttachment.attachmentInfo.clearValue = {};
586 					subpass.m_depthStencilAttachment.stencilLoadOp = pCreateInfo->pAttachments[j].stencilLoadOp;
587 					subpass.m_depthStencilAttachment.stencilStoreOp = pCreateInfo->pAttachments[j].stencilStoreOp;
588 				}
589 				else
590 				{
591 					subpass.m_depthStencilAttachment.index = VK_ATTACHMENT_UNUSED;
592 				}
593 			}
594 
595 			if (pCreateInfo->pSubpasses[s].pResolveAttachments != DE_NULL)
596 			{
597 				subpass.m_resolveAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
598 				for (deUint32 i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
599 				{
600 					deUint32 j = pCreateInfo->pSubpasses[s].pResolveAttachments[i].attachment;
601 					if (j < pCreateInfo->attachmentCount)
602 					{
603 						subpass.m_resolveAttachments[i].attachmentInfo = vk::initVulkanStructure();
604 						subpass.m_resolveAttachments[i].index = j;
605 						subpass.m_resolveAttachments[i].format = pCreateInfo->pAttachments[j].format;
606 
607 						subpass.m_resolveAttachments[i].attachmentInfo.imageView = DE_NULL;
608 						subpass.m_resolveAttachments[i].attachmentInfo.imageLayout = pCreateInfo->pSubpasses[s].pResolveAttachments[i].layout;
609 						subpass.m_resolveAttachments[i].attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
610 						subpass.m_resolveAttachments[i].attachmentInfo.resolveImageView = DE_NULL;
611 						subpass.m_resolveAttachments[i].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
612 						subpass.m_resolveAttachments[i].attachmentInfo.loadOp = pCreateInfo->pAttachments[j].loadOp;
613 						subpass.m_resolveAttachments[i].attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
614 						subpass.m_resolveAttachments[i].attachmentInfo.clearValue = {};
615 					}
616 					else
617 					{
618 						subpass.m_resolveAttachments[i].index = VK_ATTACHMENT_UNUSED;
619 					}
620 				}
621 			}
622 		}
623 
624 		m_dependencies.reserve(pCreateInfo->dependencyCount);
625 		for (uint32_t depIdx = 0u; depIdx < pCreateInfo->dependencyCount; ++depIdx)
626 			m_dependencies.emplace_back(pCreateInfo->pDependencies[depIdx]);
627 #endif
628 	}
629 }
630 
RenderPassWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkRenderPassCreateInfo2 * pCreateInfo)631 RenderPassWrapper::RenderPassWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo)
632 	: m_pipelineConstructionType	(pipelineConstructionType)
633 #ifndef CTS_USES_VULKANSC
634 	, m_renderingInfo				()
635 	, m_secondaryCommandBuffers		(false)
636 #endif
637 {
638 
639 	if (!isConstructionTypeShaderObject(pipelineConstructionType))
640 	{
641 		m_renderPass = vk::createRenderPass2(vk, device, pCreateInfo);
642 	}
643 	else
644 	{
645 #ifndef CTS_USES_VULKANSC
646 		const auto multiView = findStructure<VkRenderPassMultiviewCreateInfo>(pCreateInfo->pNext);
647 		if (multiView)
648 		{
649 			for (deUint32 i = 0; i < multiView->subpassCount; ++i)
650 				m_viewMasks.push_back(multiView->pViewMasks[i]);
651 		}
652 
653 		m_attachments.resize(pCreateInfo->attachmentCount);
654 		m_layouts.resize(pCreateInfo->attachmentCount);
655 		for (deUint32 i = 0; i < pCreateInfo->attachmentCount; ++i)
656 		{
657 			m_attachments[i] = pCreateInfo->pAttachments[i];
658 			m_layouts[i] = pCreateInfo->pAttachments[i].initialLayout;
659 		}
660 
661 		m_subpasses.resize(pCreateInfo->subpassCount);
662 		for (deUint32 s = 0; s < pCreateInfo->subpassCount; ++s)
663 		{
664 			// Input attachments are not supported with dynamic rendering
665 			DE_ASSERT(pCreateInfo->pSubpasses[s].inputAttachmentCount == 0);
666 			auto& subpass = m_subpasses[s];
667 			subpass.m_colorAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
668 
669 			const auto msrtss = findStructure<VkMultisampledRenderToSingleSampledInfoEXT>(pCreateInfo->pSubpasses[s].pNext);
670 			if (msrtss)
671 				subpass.m_msrtss = *msrtss;
672 
673 			const auto dsr = findStructure<VkSubpassDescriptionDepthStencilResolve>(pCreateInfo->pSubpasses[s].pNext);
674 			if (dsr)
675 			{
676 				subpass.m_dsr = *dsr;
677 				if (dsr->pDepthStencilResolveAttachment)
678 				{
679 					subpass.m_depthStencilResolveAttachment = *dsr->pDepthStencilResolveAttachment;
680 					subpass.m_dsr.pDepthStencilResolveAttachment = &subpass.m_depthStencilResolveAttachment;
681 				}
682 			}
683 
684 			for (deUint32 i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
685 			{
686 				deUint32 j = pCreateInfo->pSubpasses[s].pColorAttachments[i].attachment;
687 				if (j < pCreateInfo->attachmentCount)
688 				{
689 					subpass.m_colorAttachments[i].attachmentInfo = vk::initVulkanStructure();
690 					subpass.m_colorAttachments[i].index = j;
691 					subpass.m_colorAttachments[i].format = pCreateInfo->pAttachments[j].format;
692 
693 					subpass.m_colorAttachments[i].attachmentInfo.imageView = DE_NULL;
694 					subpass.m_colorAttachments[i].attachmentInfo.imageLayout = pCreateInfo->pSubpasses[s].pColorAttachments[i].layout;
695 					subpass.m_colorAttachments[i].attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
696 					subpass.m_colorAttachments[i].attachmentInfo.resolveImageView = DE_NULL;
697 					subpass.m_colorAttachments[i].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
698 					subpass.m_colorAttachments[i].attachmentInfo.loadOp = pCreateInfo->pAttachments[j].loadOp;
699 					subpass.m_colorAttachments[i].attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
700 					subpass.m_colorAttachments[i].attachmentInfo.clearValue = {};
701 				}
702 				else
703 				{
704 					subpass.m_colorAttachments[i].index = VK_ATTACHMENT_UNUSED;
705 				}
706 			}
707 
708 			if (pCreateInfo->pSubpasses[s].pDepthStencilAttachment != DE_NULL)
709 			{
710 				deUint32 j = pCreateInfo->pSubpasses[s].pDepthStencilAttachment->attachment;
711 				if (j < pCreateInfo->attachmentCount)
712 				{
713 					subpass.m_depthStencilAttachment.attachmentInfo = vk::initVulkanStructure();
714 					subpass.m_depthStencilAttachment.index = j;
715 					subpass.m_depthStencilAttachment.format = pCreateInfo->pAttachments[j].format;
716 
717 					subpass.m_depthStencilAttachment.attachmentInfo.imageView = DE_NULL;
718 					subpass.m_depthStencilAttachment.attachmentInfo.imageLayout = pCreateInfo->pSubpasses[s].pDepthStencilAttachment->layout;
719 					subpass.m_depthStencilAttachment.attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
720 					subpass.m_depthStencilAttachment.attachmentInfo.resolveImageView = DE_NULL;
721 					subpass.m_depthStencilAttachment.attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
722 					subpass.m_depthStencilAttachment.attachmentInfo.loadOp = pCreateInfo->pAttachments[j].loadOp;
723 					subpass.m_depthStencilAttachment.attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
724 					subpass.m_depthStencilAttachment.attachmentInfo.clearValue = {};
725 					subpass.m_depthStencilAttachment.stencilLoadOp = pCreateInfo->pAttachments[j].stencilLoadOp;
726 					subpass.m_depthStencilAttachment.stencilStoreOp = pCreateInfo->pAttachments[j].stencilStoreOp;
727 				}
728 				else
729 				{
730 					subpass.m_depthStencilAttachment.index = VK_ATTACHMENT_UNUSED;
731 				}
732 			}
733 
734 			if (pCreateInfo->pSubpasses[s].pResolveAttachments != DE_NULL)
735 			{
736 				subpass.m_resolveAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
737 				for (deUint32 i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
738 				{
739 					deUint32 j = pCreateInfo->pSubpasses[s].pResolveAttachments[i].attachment;
740 					if (j < pCreateInfo->attachmentCount)
741 					{
742 						subpass.m_resolveAttachments[i].attachmentInfo = vk::initVulkanStructure();
743 						subpass.m_resolveAttachments[i].index = j;
744 						subpass.m_resolveAttachments[i].format = pCreateInfo->pAttachments[j].format;
745 
746 						subpass.m_resolveAttachments[i].attachmentInfo.imageView = DE_NULL;
747 						subpass.m_resolveAttachments[i].attachmentInfo.imageLayout = pCreateInfo->pSubpasses[s].pResolveAttachments[i].layout;
748 						subpass.m_resolveAttachments[i].attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
749 						subpass.m_resolveAttachments[i].attachmentInfo.resolveImageView = DE_NULL;
750 						subpass.m_resolveAttachments[i].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
751 						subpass.m_resolveAttachments[i].attachmentInfo.loadOp = pCreateInfo->pAttachments[j].loadOp;
752 						subpass.m_resolveAttachments[i].attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
753 						subpass.m_resolveAttachments[i].attachmentInfo.clearValue = {};
754 					}
755 					else
756 					{
757 						subpass.m_resolveAttachments[i].index = VK_ATTACHMENT_UNUSED;
758 					}
759 				}
760 			}
761 		}
762 
763 		m_dependencies.reserve(pCreateInfo->dependencyCount);
764 		for (uint32_t depIdx = 0u; depIdx < pCreateInfo->dependencyCount; ++depIdx)
765 			m_dependencies.emplace_back(pCreateInfo->pDependencies[depIdx]);
766 #endif
767 	}
768 }
769 
RenderPassWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const VkFormat depthStencilFormat,const VkAttachmentLoadOp loadOperation,const VkImageLayout finalLayoutColor,const VkImageLayout finalLayoutDepthStencil,const VkImageLayout subpassLayoutColor,const VkImageLayout subpassLayoutDepthStencil,const VkAllocationCallbacks * const allocationCallbacks)770 RenderPassWrapper::RenderPassWrapper (PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, const VkDevice device, const VkFormat colorFormat, const VkFormat depthStencilFormat, const VkAttachmentLoadOp loadOperation, const VkImageLayout finalLayoutColor,
771 	const VkImageLayout finalLayoutDepthStencil, const VkImageLayout subpassLayoutColor, const VkImageLayout subpassLayoutDepthStencil, const VkAllocationCallbacks* const allocationCallbacks)
772 	: m_pipelineConstructionType	(pipelineConstructionType)
773 #ifndef CTS_USES_VULKANSC
774 	, m_renderingInfo				()
775 #endif
776 {
777 
778 	if (!isConstructionTypeShaderObject(pipelineConstructionType))
779 	{
780 		m_renderPass = vk::makeRenderPass(vk, device, colorFormat, depthStencilFormat, loadOperation, finalLayoutColor, finalLayoutDepthStencil, subpassLayoutColor, subpassLayoutDepthStencil, allocationCallbacks);
781 	}
782 	else
783 	{
784 #ifndef CTS_USES_VULKANSC
785 		const bool				hasColor					= colorFormat != VK_FORMAT_UNDEFINED;
786 		const bool				hasDepthStencil				= depthStencilFormat != VK_FORMAT_UNDEFINED;
787 		const VkImageLayout		initialLayoutColor			= loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
788 		const VkImageLayout		initialLayoutDepthStencil	= loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
789 
790 		m_subpasses.resize(1);
791 		auto& subpass = m_subpasses[0];
792 
793 		if (hasColor)
794 		{
795 			subpass.m_colorAttachments.resize(1);
796 			subpass.m_colorAttachments[0].attachmentInfo = vk::initVulkanStructure();
797 			subpass.m_colorAttachments[0].index = 0u;
798 			subpass.m_colorAttachments[0].format = colorFormat;
799 
800 			subpass.m_colorAttachments[0].attachmentInfo.imageView = DE_NULL;
801 			subpass.m_colorAttachments[0].attachmentInfo.imageLayout = subpassLayoutColor;
802 			subpass.m_colorAttachments[0].attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
803 			subpass.m_colorAttachments[0].attachmentInfo.resolveImageView = DE_NULL;
804 			subpass.m_colorAttachments[0].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
805 			subpass.m_colorAttachments[0].attachmentInfo.loadOp = loadOperation;
806 			subpass.m_colorAttachments[0].attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
807 			subpass.m_colorAttachments[0].attachmentInfo.clearValue = {};
808 
809 			const VkAttachmentDescription2			colorAttachmentDescription =
810 			{
811 				VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
812 				DE_NULL,
813 				(VkAttachmentDescriptionFlags)0,	// VkAttachmentDescriptionFlags    flags
814 				colorFormat,						// VkFormat                        format
815 				VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits           samples
816 				loadOperation,						// VkAttachmentLoadOp              loadOp
817 				VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             storeOp
818 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,	// VkAttachmentLoadOp              stencilLoadOp
819 				VK_ATTACHMENT_STORE_OP_DONT_CARE,	// VkAttachmentStoreOp             stencilStoreOp
820 				initialLayoutColor,					// VkImageLayout                   initialLayout
821 				finalLayoutColor					// VkImageLayout                   finalLayout
822 			};
823 			m_attachments.push_back(colorAttachmentDescription);
824 			m_layouts.push_back(colorAttachmentDescription.initialLayout);
825 		}
826 		if (hasDepthStencil)
827 		{
828 			subpass.m_depthStencilAttachment.attachmentInfo = vk::initVulkanStructure();
829 			subpass.m_depthStencilAttachment.index = hasColor ? 1u : 0u;
830 			subpass.m_depthStencilAttachment.format = depthStencilFormat;
831 
832 			subpass.m_depthStencilAttachment.attachmentInfo.imageView = DE_NULL;
833 			subpass.m_depthStencilAttachment.attachmentInfo.imageLayout = subpassLayoutDepthStencil;
834 			subpass.m_depthStencilAttachment.attachmentInfo.resolveMode = vk::VK_RESOLVE_MODE_NONE;
835 			subpass.m_depthStencilAttachment.attachmentInfo.resolveImageView = DE_NULL;
836 			subpass.m_depthStencilAttachment.attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
837 			subpass.m_depthStencilAttachment.attachmentInfo.loadOp = loadOperation;
838 			subpass.m_depthStencilAttachment.attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
839 			subpass.m_depthStencilAttachment.attachmentInfo.clearValue = {};
840 			subpass.m_depthStencilAttachment.stencilLoadOp = loadOperation;
841 			subpass.m_depthStencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
842 
843 			const VkAttachmentDescription2			depthStencilAttachmentDescription =
844 			{
845 				VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
846 				DE_NULL,
847 				(VkAttachmentDescriptionFlags)0,	// VkAttachmentDescriptionFlags    flags
848 				depthStencilFormat,					// VkFormat                        format
849 				VK_SAMPLE_COUNT_1_BIT,				// VkSampleCountFlagBits           samples
850 				loadOperation,						// VkAttachmentLoadOp              loadOp
851 				VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             storeOp
852 				loadOperation,						// VkAttachmentLoadOp              stencilLoadOp
853 				VK_ATTACHMENT_STORE_OP_STORE,		// VkAttachmentStoreOp             stencilStoreOp
854 				initialLayoutDepthStencil,			// VkImageLayout                   initialLayout
855 				finalLayoutDepthStencil				// VkImageLayout                   finalLayout
856 			};
857 			m_attachments.push_back(depthStencilAttachmentDescription);
858 			m_layouts.push_back(depthStencilAttachmentDescription.initialLayout);
859 		}
860 #endif
861 	}
862 }
863 
RenderPassWrapper(RenderPassWrapper && rhs)864 RenderPassWrapper::RenderPassWrapper (RenderPassWrapper&& rhs) noexcept
865 	: m_pipelineConstructionType	(rhs.m_pipelineConstructionType)
866 	, m_renderPass					(rhs.m_renderPass)
867 	, m_framebuffer					(rhs.m_framebuffer)
868 #ifndef CTS_USES_VULKANSC
869 	, m_subpasses					(std::move(rhs.m_subpasses))
870 	, m_dependencies				(std::move(rhs.m_dependencies))
871 	, m_attachments					(std::move(rhs.m_attachments))
872 	, m_images						(std::move(rhs.m_images))
873 	, m_imageViews					(std::move(rhs.m_imageViews))
874 	, m_clearValues					(std::move(rhs.m_clearValues))
875 	, m_layouts						(std::move(rhs.m_layouts))
876 	, m_activeSubpass				(rhs.m_activeSubpass)
877 	, m_renderingInfo				(rhs.m_renderingInfo)
878 	, m_layers						(rhs.m_layers)
879 	, m_viewMasks					(std::move(rhs.m_viewMasks))
880 	, m_secondaryCommandBuffers		(rhs.m_secondaryCommandBuffers)
881 #endif
882 {
883 
884 }
885 
operator =(RenderPassWrapper && rhs)886 RenderPassWrapper& RenderPassWrapper::operator=	(RenderPassWrapper&& rhs) noexcept
887 {
888 	m_pipelineConstructionType = rhs.m_pipelineConstructionType;
889 	m_renderPass = rhs.m_renderPass;
890 	m_framebuffer = rhs.m_framebuffer;
891 #ifndef CTS_USES_VULKANSC
892 	m_subpasses = std::move(rhs.m_subpasses);
893 	m_dependencies = std::move(rhs.m_dependencies);
894 	m_attachments = std::move(rhs.m_attachments);
895 	m_images = std::move(rhs.m_images);
896 	m_imageViews = std::move(rhs.m_imageViews);
897 	m_clearValues = std::move(rhs.m_clearValues);
898 	m_layouts = std::move(rhs.m_layouts);
899 	m_activeSubpass = rhs.m_activeSubpass;
900 	m_renderingInfo = rhs.m_renderingInfo;
901 	m_layers = rhs.m_layers;
902 	m_viewMasks = std::move(rhs.m_viewMasks);
903 	m_secondaryCommandBuffers = rhs.m_secondaryCommandBuffers;
904 #endif
905 	return *this;
906 }
907 
908 #ifndef CTS_USES_VULKANSC
909 
910 
clearAttachments(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const911 void RenderPassWrapper::clearAttachments(const DeviceInterface& vk, const VkCommandBuffer commandBuffer) const
912 {
913 	for (deUint32 i = 0; i < (deUint32)m_attachments.size() && i < (deUint32)m_clearValues.size(); ++i)
914 	{
915 		const auto tcuFormat = vk::mapVkFormat(m_attachments[i].format);
916 		bool hasDepthAspect = tcu::hasDepthComponent(tcuFormat.order);
917 		bool hasStencilAspect = tcu::hasStencilComponent(tcuFormat.order);
918 
919 		if (m_attachments[i].loadOp != vk::VK_ATTACHMENT_LOAD_OP_CLEAR && !(hasStencilAspect && m_attachments[i].stencilLoadOp == vk::VK_ATTACHMENT_LOAD_OP_CLEAR))
920 			continue;
921 
922 		vk::VkRenderingInfo renderingInfo = vk::initVulkanStructure();
923 		renderingInfo.renderArea = m_renderingInfo.renderArea;
924 		renderingInfo.layerCount = m_renderingInfo.layerCount;
925 
926 		vk::VkRenderingAttachmentInfo attachment = vk::initVulkanStructure();
927 		attachment.imageView = m_imageViews[i];
928 		attachment.imageLayout = m_layouts[i];
929 		attachment.loadOp = vk::VK_ATTACHMENT_LOAD_OP_CLEAR;
930 		attachment.storeOp = vk::VK_ATTACHMENT_STORE_OP_STORE;
931 		attachment.clearValue = m_clearValues[i];
932 
933 		if (hasDepthAspect || hasStencilAspect)
934 		{
935 			renderingInfo.pDepthAttachment = hasDepthAspect ? &attachment : DE_NULL;
936 			renderingInfo.pStencilAttachment = hasStencilAspect ? &attachment : DE_NULL;
937 		}
938 		else
939 		{
940 			renderingInfo.colorAttachmentCount = 1u;
941 			renderingInfo.pColorAttachments = &attachment;
942 		}
943 
944 		vk.cmdBeginRendering(commandBuffer, &renderingInfo);
945 		vk.cmdEndRendering(commandBuffer);
946 	}
947 }
948 
updateLayout(VkImage updatedImage,VkImageLayout newLayout) const949 void RenderPassWrapper::updateLayout(VkImage updatedImage, VkImageLayout newLayout) const
950 {
951 	for (deUint32 i = 0; i < (deUint32)m_images.size(); ++i)
952 		if (m_images[i] == updatedImage)
953 			m_layouts[i] = newLayout;
954 }
955 
956 namespace
957 {
958 
recordImageBarrier(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const bool sync2,const VkPipelineStageFlags2 srcStageMask,const VkAccessFlags2 srcAccessMask,const VkPipelineStageFlags2 dstStageMask,const VkAccessFlags2 dstAccessMask,const VkImageLayout prevLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange & subresourceRange)959 void recordImageBarrier (const DeviceInterface&			vk,
960 						 const VkCommandBuffer			commandBuffer,
961 						 const bool						sync2,
962 						 const VkPipelineStageFlags2	srcStageMask,
963 						 const VkAccessFlags2			srcAccessMask,
964 						 const VkPipelineStageFlags2	dstStageMask,
965 						 const VkAccessFlags2			dstAccessMask,
966 						 const VkImageLayout			prevLayout,
967 						 const VkImageLayout			newLayout,
968 						 const VkImage					image,
969 						 const VkImageSubresourceRange&	subresourceRange)
970 {
971 	if (sync2)
972 	{
973 		const auto barrier = makeImageMemoryBarrier2(
974 			srcStageMask,
975 			srcAccessMask,
976 			dstStageMask,
977 			dstAccessMask,
978 			prevLayout,
979 			newLayout,
980 			image,
981 			subresourceRange);
982 
983 		const VkDependencyInfo depInfo =
984 		{
985 			VK_STRUCTURE_TYPE_DEPENDENCY_INFO,	//	VkStructureType					sType;
986 			nullptr,							//	const void*						pNext;
987 			0u,									//	VkDependencyFlags				dependencyFlags;
988 			0u,									//	uint32_t						memoryBarrierCount;
989 			nullptr,							//	const VkMemoryBarrier2*			pMemoryBarriers;
990 			0u,									//	uint32_t						bufferMemoryBarrierCount;
991 			nullptr,							//	const VkBufferMemoryBarrier2*	pBufferMemoryBarriers;
992 			1u,									//	uint32_t						imageMemoryBarrierCount;
993 			&barrier,							//	const VkImageMemoryBarrier2*	pImageMemoryBarriers;
994 		};
995 
996 		vk.cmdPipelineBarrier2(commandBuffer, &depInfo);
997 	}
998 	else
999 	{
1000 		const auto barrier = makeImageMemoryBarrier(
1001 			static_cast<VkAccessFlags>(srcAccessMask),
1002 			static_cast<VkAccessFlags>(dstAccessMask),
1003 			prevLayout,
1004 			newLayout,
1005 			image,
1006 			subresourceRange);
1007 
1008 		vk.cmdPipelineBarrier(
1009 			commandBuffer,
1010 			static_cast<VkPipelineStageFlags>(srcStageMask),
1011 			static_cast<VkPipelineStageFlags>(dstStageMask),
1012 			0u, 0u, nullptr, 0u, nullptr, 1u, &barrier);
1013 	}
1014 }
1015 
1016 } // anonymous namespace
1017 
transitionLayouts(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const Subpass & subpass,bool renderPassBegin) const1018 void RenderPassWrapper::transitionLayouts (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const Subpass& subpass, bool renderPassBegin) const
1019 {
1020 	// Use the access and stage flags for dependencies on external subpasses in
1021 	// the initial layout transitions for images.
1022 	VkAccessFlags2			externalAccessFlags	= 0u;
1023 	VkPipelineStageFlags2	externalStageFlags	= 0u;
1024 	bool					sync2				= false;
1025 
1026 	if (renderPassBegin)
1027 	{
1028 		for (const auto& dep : m_dependencies)
1029 		{
1030 			if (dep.srcSubpass == VK_SUBPASS_EXTERNAL)
1031 			{
1032 				externalAccessFlags	|= dep.srcAccessMask;
1033 				externalStageFlags	|= dep.srcStageMask;
1034 			}
1035 
1036 			if (dep.sync2)
1037 				sync2 = true;
1038 		}
1039 	}
1040 
1041 	for (deUint32 i = 0; i < (deUint32)m_attachments.size(); ++i)
1042 	{
1043 		// renderPassBegin is true when vkCmdBeginRenderPass should be called in a normal renderPass, and it is false when vkCmdNextSupass should be called
1044 		// Every image is transioned from VK_IMAGE_LAYOUT_UNDEFINED to it's first used layout, so that all images can be cleared in the beginning
1045 		if (renderPassBegin && m_layouts[i] != vk::VK_IMAGE_LAYOUT_UNDEFINED)
1046 			continue;
1047 
1048 		if (m_images[i] != VK_NULL_HANDLE)
1049 		{
1050 			for (deUint32 j = 0; j < (deUint32)subpass.m_colorAttachments.size(); ++j)
1051 			{
1052 				if (subpass.m_colorAttachments[j].index == i)
1053 				{
1054 					const auto subresourceRange = makeImageSubresourceRange(
1055 						vk::VK_IMAGE_ASPECT_COLOR_BIT,
1056 						0u,
1057 						VK_REMAINING_MIP_LEVELS,
1058 						0u,
1059 						VK_REMAINING_ARRAY_LAYERS);
1060 
1061 					const VkPipelineStageFlags2	srcStageMask	= (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1062 					const VkAccessFlags2		srcAccessMask	= externalAccessFlags;
1063 					const VkPipelineStageFlags2	dstStageMask	= vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1064 					const VkAccessFlags2		dstAccessMask	= vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1065 					const VkImageLayout			newLayout		= subpass.m_colorAttachments[j].attachmentInfo.imageLayout;
1066 
1067 					recordImageBarrier(vk,
1068 									   commandBuffer,
1069 									   sync2,
1070 									   srcStageMask,
1071 									   srcAccessMask,
1072 									   dstStageMask,
1073 									   dstAccessMask,
1074 									   m_layouts[i],
1075 									   newLayout,
1076 									   m_images[i],
1077 									   subresourceRange);
1078 
1079 					updateLayout(m_images[i], newLayout);
1080 				}
1081 			}
1082 			if (subpass.m_depthStencilAttachment.index == i)
1083 			{
1084 				const auto tcuFormat		= vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1085 				const bool hasDepthAspect	= tcu::hasDepthComponent(tcuFormat.order);
1086 				const bool hasStencilAspect	= tcu::hasStencilComponent(tcuFormat.order);
1087 
1088 				VkImageAspectFlags aspect = (VkImageAspectFlags)0u;
1089 				if (hasDepthAspect)
1090 					aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1091 				if (hasStencilAspect)
1092 					aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1093 
1094 				const auto subresourceRange = makeImageSubresourceRange(
1095 					aspect,
1096 					0u,
1097 					VK_REMAINING_MIP_LEVELS,
1098 					0u,
1099 					VK_REMAINING_ARRAY_LAYERS);
1100 
1101 				const VkPipelineStageFlags2	srcStageMask	= (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1102 				const VkAccessFlags2		srcAccessMask	= externalAccessFlags;
1103 				const VkPipelineStageFlags2	dstStageMask	= (vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1104 				const VkAccessFlags2		dstAccessMask	= (vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1105 				const VkImageLayout			newLayout		= subpass.m_depthStencilAttachment.attachmentInfo.imageLayout;
1106 
1107 				recordImageBarrier(vk,
1108 								   commandBuffer,
1109 								   sync2,
1110 								   srcStageMask,
1111 								   srcAccessMask,
1112 								   dstStageMask,
1113 								   dstAccessMask,
1114 								   m_layouts[i],
1115 								   newLayout,
1116 								   m_images[i],
1117 								   subresourceRange);
1118 
1119 				updateLayout(m_images[i], newLayout);
1120 			}
1121 			for (deUint32 j = 0; j < (deUint32)subpass.m_resolveAttachments.size(); ++j)
1122 			{
1123 				if (subpass.m_resolveAttachments[j].index == i)
1124 				{
1125 					const auto subresourceRange = makeImageSubresourceRange(
1126 						vk::VK_IMAGE_ASPECT_COLOR_BIT,
1127 						0u,
1128 						VK_REMAINING_MIP_LEVELS,
1129 						0u,
1130 						VK_REMAINING_ARRAY_LAYERS);
1131 
1132 					const VkPipelineStageFlags2	srcStageMask	= (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1133 					const VkAccessFlags2		srcAccessMask	= externalAccessFlags;
1134 					const VkPipelineStageFlags2	dstStageMask	= vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1135 					const VkAccessFlags2		dstAccessMask	= vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1136 					const VkImageLayout			newLayout		= subpass.m_resolveAttachments[j].attachmentInfo.imageLayout;
1137 
1138 					recordImageBarrier(vk,
1139 									   commandBuffer,
1140 									   sync2,
1141 									   srcStageMask,
1142 									   srcAccessMask,
1143 									   dstStageMask,
1144 									   dstAccessMask,
1145 									   m_layouts[i],
1146 									   newLayout,
1147 									   m_images[i],
1148 									   subresourceRange);
1149 
1150 					updateLayout(m_images[i], newLayout);
1151 				}
1152 			}
1153 			if (subpass.m_dsr.sType == vk::VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE)
1154 			{
1155 				if (subpass.m_dsr.pDepthStencilResolveAttachment && i == subpass.m_dsr.pDepthStencilResolveAttachment->attachment)
1156 				{
1157 					const auto tcuFormat		= vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1158 					const bool hasDepthAspect	= tcu::hasDepthComponent(tcuFormat.order);
1159 					const bool hasStencilAspect	= tcu::hasStencilComponent(tcuFormat.order);
1160 
1161 					VkImageAspectFlags aspect = (VkImageAspectFlags)0u;
1162 					if (hasDepthAspect)
1163 						aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1164 					if (hasStencilAspect)
1165 						aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1166 
1167 					const auto subresourceRange = makeImageSubresourceRange(
1168 						aspect,
1169 						0u,
1170 						VK_REMAINING_MIP_LEVELS,
1171 						0u,
1172 						VK_REMAINING_ARRAY_LAYERS);
1173 
1174 					const VkPipelineStageFlags2	srcStageMask	= (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1175 					const VkAccessFlags2		srcAccessMask	= externalAccessFlags;
1176 					const VkPipelineStageFlags2	dstStageMask	= (vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1177 					const VkAccessFlags2		dstAccessMask	= vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1178 					const VkImageLayout			newLayout		= subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1179 
1180 					recordImageBarrier(vk,
1181 									   commandBuffer,
1182 									   sync2,
1183 									   srcStageMask,
1184 									   srcAccessMask,
1185 									   dstStageMask,
1186 									   dstAccessMask,
1187 									   m_layouts[i],
1188 									   newLayout,
1189 									   m_images[i],
1190 									   subresourceRange);
1191 
1192 					updateLayout(m_images[i], newLayout);
1193 				}
1194 			}
1195 		}
1196 	}
1197 }
1198 
insertDependencies(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,uint32_t subpassIdx) const1199 void RenderPassWrapper::insertDependencies (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, uint32_t subpassIdx) const
1200 {
1201 	for (const auto& dep : m_dependencies)
1202 	{
1203 		// Subpass self-dependencies should be handled with manual barriers inside the render pass.
1204 		if (dep.dstSubpass != subpassIdx || dep.srcSubpass == subpassIdx)
1205 			continue;
1206 
1207 		if (dep.sync2)
1208 		{
1209 			const VkMemoryBarrier2 barrier =
1210 			{
1211 				VK_STRUCTURE_TYPE_MEMORY_BARRIER,	//	VkStructureType			sType;
1212 				nullptr,							//	const void*				pNext;
1213 				dep.srcStageMask,					//	VkPipelineStageFlags2	srcStageMask;
1214 				dep.srcAccessMask,					//	VkAccessFlags2			srcAccessMask;
1215 				dep.dstStageMask,					//	VkPipelineStageFlags2	dstStageMask;
1216 				dep.dstAccessMask,					//	VkAccessFlags2			dstAccessMask;
1217 			};
1218 			const VkDependencyInfo depInfo =
1219 			{
1220 				VK_STRUCTURE_TYPE_DEPENDENCY_INFO,	//	VkStructureType					sType;
1221 				nullptr,							//	const void*						pNext;
1222 				dep.dependencyFlags,				//	VkDependencyFlags				dependencyFlags;
1223 				1u,									//	uint32_t						memoryBarrierCount;
1224 				&barrier,							//	const VkMemoryBarrier2*			pMemoryBarriers;
1225 				0u,									//	uint32_t						bufferMemoryBarrierCount;
1226 				nullptr,							//	const VkBufferMemoryBarrier2*	pBufferMemoryBarriers;
1227 				0u,									//	uint32_t						imageMemoryBarrierCount;
1228 				nullptr,							//	const VkImageMemoryBarrier2*	pImageMemoryBarriers;
1229 			};
1230 			vk.cmdPipelineBarrier2(commandBuffer, &depInfo);
1231 		}
1232 		else
1233 		{
1234 			const VkMemoryBarrier barrier =
1235 			{
1236 				VK_STRUCTURE_TYPE_MEMORY_BARRIER,				//	VkStructureType	sType;
1237 				nullptr,										//	const void*		pNext;
1238 				static_cast<VkAccessFlags>(dep.srcAccessMask),	//	VkAccessFlags	srcAccessMask;
1239 				static_cast<VkAccessFlags>(dep.dstAccessMask),	//	VkAccessFlags	dstAccessMask;
1240 			};
1241 			vk.cmdPipelineBarrier(commandBuffer,
1242 				static_cast<VkPipelineStageFlags>(dep.srcStageMask),
1243 				static_cast<VkPipelineStageFlags>(dep.dstStageMask),
1244 				dep.dependencyFlags,
1245 				1u, &barrier,
1246 				0u, nullptr, 0u, nullptr);
1247 		}
1248 	}
1249 }
1250 
fillInheritanceRenderingInfo(deUint32 subpassIndex,std::vector<vk::VkFormat> * colorFormats,vk::VkCommandBufferInheritanceRenderingInfo * inheritanceRenderingInfo) const1251 void RenderPassWrapper::fillInheritanceRenderingInfo(deUint32 subpassIndex, std::vector<vk::VkFormat>* colorFormats, vk::VkCommandBufferInheritanceRenderingInfo* inheritanceRenderingInfo) const
1252 {
1253 	const auto& subpass = m_subpasses[subpassIndex];
1254 	colorFormats->resize(subpass.m_colorAttachments.size());
1255 	for (deUint32 i = 0; i < (deUint32)subpass.m_colorAttachments.size(); ++i)
1256 		(*colorFormats)[i] = subpass.m_colorAttachments[i].format;
1257 
1258 	inheritanceRenderingInfo->colorAttachmentCount = (deUint32)subpass.m_colorAttachments.size();
1259 	inheritanceRenderingInfo->pColorAttachmentFormats = colorFormats->data();
1260 
1261 	if (subpass.m_depthStencilAttachment.format != vk::VK_FORMAT_UNDEFINED)
1262 	{
1263 		const auto tcuFormat = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1264 		if (tcu::hasDepthComponent(tcuFormat.order))
1265 			inheritanceRenderingInfo->depthAttachmentFormat = subpass.m_depthStencilAttachment.format;
1266 		if (tcu::hasStencilComponent(tcuFormat.order))
1267 			inheritanceRenderingInfo->stencilAttachmentFormat = subpass.m_depthStencilAttachment.format;
1268 	}
1269 
1270 	if (subpassIndex < (deUint32)m_viewMasks.size())
1271 		inheritanceRenderingInfo->viewMask = m_viewMasks[subpassIndex];
1272 }
1273 
1274 #endif
1275 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const deUint32 clearValueCount,const VkClearValue * clearValues,const VkSubpassContents contents,const void * pNext) const1276 void RenderPassWrapper::begin (const DeviceInterface&	vk,
1277 							   const VkCommandBuffer	commandBuffer,
1278 							   const VkRect2D&			renderArea,
1279 							   const deUint32			clearValueCount,
1280 							   const VkClearValue*		clearValues,
1281 							   const VkSubpassContents	contents,
1282 							   const void*				pNext) const
1283 {
1284 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1285 	{
1286 		beginRenderPass(vk, commandBuffer, *m_renderPass, *m_framebuffer, renderArea, clearValueCount, clearValues, contents, pNext);
1287 	}
1288 	else
1289 	{
1290 #ifndef CTS_USES_VULKANSC
1291 		m_activeSubpass = 0;
1292 
1293 		m_clearValues.resize(clearValueCount);
1294 		for (deUint32 i = 0; i < clearValueCount; ++i)
1295 			m_clearValues[i] = clearValues[i];
1296 
1297 		for (deUint32 i = 0; i < (deUint32)m_subpasses.size(); ++i)
1298 			transitionLayouts(vk, commandBuffer, m_subpasses[i], true);
1299 
1300 		insertDependencies(vk, commandBuffer, 0u);
1301 
1302 		m_secondaryCommandBuffers = contents == vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
1303 
1304 		m_renderingInfo = vk::initVulkanStructure();
1305 		m_renderingInfo.flags = (vk::VkRenderingFlags)0u;
1306 		m_renderingInfo.renderArea = renderArea;
1307 		m_renderingInfo.layerCount = m_layers;
1308 		m_renderingInfo.viewMask = 0x0;
1309 
1310 		clearAttachments(vk, commandBuffer);
1311 
1312 		beginRendering(vk, commandBuffer);
1313 #endif
1314 	}
1315 }
1316 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const VkClearValue & clearValue,const VkSubpassContents contents) const1317 void RenderPassWrapper::begin (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkRect2D& renderArea, const VkClearValue& clearValue, const VkSubpassContents contents) const
1318 {
1319 	begin(vk, commandBuffer, renderArea, 1u, &clearValue, contents);
1320 }
1321 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor,const VkSubpassContents contents) const1322 void RenderPassWrapper::begin (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkRect2D& renderArea, const tcu::Vec4& clearColor, const VkSubpassContents contents) const
1323 {
1324 	const VkClearValue clearValue = makeClearValueColor(clearColor);
1325 	begin(vk, commandBuffer, renderArea, clearValue, contents);
1326 }
1327 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor,const float clearDepth,const deUint32 clearStencil,const VkSubpassContents contents) const1328 void RenderPassWrapper::begin(const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkRect2D& renderArea, const tcu::Vec4& clearColor, const float clearDepth, const deUint32 clearStencil, const VkSubpassContents contents) const
1329 {
1330 	const VkClearValue			clearValues[] =
1331 	{
1332 		makeClearValueColor(clearColor),						// attachment 0
1333 		makeClearValueDepthStencil(clearDepth, clearStencil),	// attachment 1
1334 	};
1335 	begin(vk, commandBuffer, renderArea, 2, clearValues, contents);
1336 }
1337 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const VkSubpassContents contents) const1338 void RenderPassWrapper::begin (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkRect2D& renderArea, const VkSubpassContents contents) const
1339 {
1340 	begin(vk, commandBuffer, renderArea, 0u, DE_NULL, contents);
1341 }
1342 
1343 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::UVec4 & clearColor,const VkSubpassContents contents) const1344 void RenderPassWrapper::begin(const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkRect2D& renderArea, const tcu::UVec4& clearColor, const VkSubpassContents contents) const
1345 {
1346 	const VkClearValue clearValue = makeClearValueColorU32(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
1347 
1348 	begin(vk, commandBuffer, renderArea, clearValue, contents);
1349 }
1350 
end(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const1351 void RenderPassWrapper::end (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) const
1352 {
1353 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1354 	{
1355 		vk.cmdEndRenderPass(commandBuffer);
1356 	}
1357 	else
1358 	{
1359 #ifndef CTS_USES_VULKANSC
1360 		vk.cmdEndRendering(commandBuffer);
1361 
1362 		// Use dependencies for external subpasses to extract destination access
1363 		// flags and pipeline stage flags for the final layout transition
1364 		// barriers.
1365 		VkAccessFlags2			externalAccessFlags	= 0u;
1366 		VkPipelineStageFlags2	externalStageFlags	= 0u;
1367 		bool					sync2				= false;
1368 
1369 		for (const auto& dep : m_dependencies)
1370 		{
1371 			if (dep.dstSubpass == VK_SUBPASS_EXTERNAL)
1372 			{
1373 				externalAccessFlags	|= dep.dstAccessMask;
1374 				externalStageFlags	|= dep.dstStageMask;
1375 			}
1376 			if (dep.sync2)
1377 				sync2 = true;
1378 		}
1379 
1380 		for (deUint32 i = 0; i < (deUint32)m_attachments.size(); ++i)
1381 		{
1382 			if (m_layouts[i] == m_attachments[i].finalLayout)
1383 				continue;
1384 
1385 			const bool			color	= !vk::isDepthStencilFormat(m_attachments[i].format);
1386 			VkImageAspectFlags	aspect	= color ? (vk::VkImageAspectFlags)vk::VK_IMAGE_ASPECT_COLOR_BIT : (vk::VkImageAspectFlags)0u;
1387 
1388 			if (!color)
1389 			{
1390 				const bool hasDepthAspect	= tcu::hasDepthComponent(vk::mapVkFormat(m_attachments[i].format).order);
1391 				const bool hasStencilAspect	= tcu::hasStencilComponent(vk::mapVkFormat(m_attachments[i].format).order);
1392 
1393 				if (hasDepthAspect)
1394 					aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1395 				if (hasStencilAspect)
1396 					aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1397 			}
1398 
1399 			const auto subresourceRange = makeImageSubresourceRange(
1400 				aspect,
1401 				0u,
1402 				VK_REMAINING_MIP_LEVELS,
1403 				0u,
1404 				VK_REMAINING_ARRAY_LAYERS);
1405 
1406 			const VkPipelineStageFlags2	srcStageMask	= (color ? vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT : vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1407 			const VkAccessFlags2		srcAccessMask	= (color ? vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT : vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1408 			const VkPipelineStageFlags2	dstStageMask	= (vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | externalStageFlags);
1409 			const VkAccessFlags2		dstAccessMask	= externalAccessFlags;
1410 			const VkImageLayout			newLayout		= m_attachments[i].finalLayout;
1411 
1412 			recordImageBarrier(vk,
1413 							   commandBuffer,
1414 							   sync2,
1415 							   srcStageMask,
1416 							   srcAccessMask,
1417 							   dstStageMask,
1418 							   dstAccessMask,
1419 							   m_layouts[i],
1420 							   newLayout,
1421 							   m_images[i],
1422 							   subresourceRange);
1423 		}
1424 
1425 		insertDependencies(vk, commandBuffer, VK_SUBPASS_EXTERNAL);
1426 #endif
1427 	}
1428 }
1429 
beginRendering(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const1430 void RenderPassWrapper::beginRendering (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) const
1431 {
1432 	DE_UNREF(vk);
1433 	DE_UNREF(commandBuffer);
1434 #ifndef CTS_USES_VULKANSC
1435 	const auto& subpass = m_subpasses[m_activeSubpass];
1436 	std::vector<vk::VkRenderingAttachmentInfo> colorAttachments;
1437 	for (deUint32 i = 0; i < (deUint32)subpass.m_colorAttachments.size(); ++i)
1438 	{
1439 		colorAttachments.emplace_back();
1440 		auto& colorAttachment = colorAttachments.back();
1441 		colorAttachment = vk::initVulkanStructure();
1442 		if (subpass.m_colorAttachments[i].index == VK_ATTACHMENT_UNUSED)
1443 			continue;
1444 		colorAttachment = subpass.m_colorAttachments[i].attachmentInfo;
1445 		colorAttachment.loadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
1446 		if (!subpass.m_resolveAttachments.empty() && subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1447 		{
1448 			if (isUintFormat(subpass.m_resolveAttachments[i].format) || isIntFormat(subpass.m_resolveAttachments[i].format))
1449 				colorAttachment.resolveMode = vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
1450 			else
1451 				colorAttachment.resolveMode = vk::VK_RESOLVE_MODE_AVERAGE_BIT;
1452 			colorAttachment.resolveImageView = subpass.m_resolveAttachments[i].attachmentInfo.imageView;
1453 			colorAttachment.resolveImageLayout = subpass.m_resolveAttachments[i].attachmentInfo.imageLayout;
1454 		}
1455 	}
1456 
1457 	m_renderingInfo.colorAttachmentCount = (deUint32)colorAttachments.size();
1458 	m_renderingInfo.pColorAttachments = colorAttachments.data();
1459 
1460 	subpass.m_depthStencilAttachment.attachmentInfo.loadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
1461 	VkRenderingAttachmentInfo depthAttachment = subpass.m_depthStencilAttachment.attachmentInfo;
1462 	VkRenderingAttachmentInfo stencilAttachment = subpass.m_depthStencilAttachment.attachmentInfo;
1463 	stencilAttachment.storeOp = subpass.m_depthStencilAttachment.stencilStoreOp;
1464 
1465 	if (depthAttachment.imageView != VK_NULL_HANDLE)
1466 	{
1467 		const auto tcuFormat = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1468 		bool hasDepthAspect = tcu::hasDepthComponent(tcuFormat.order);
1469 		bool hasStencilAspect = tcu::hasStencilComponent(tcuFormat.order);
1470 		m_renderingInfo.pDepthAttachment = hasDepthAspect ? &depthAttachment : DE_NULL;
1471 		m_renderingInfo.pStencilAttachment = hasStencilAspect ? &stencilAttachment : DE_NULL;
1472 	}
1473 	else
1474 	{
1475 		m_renderingInfo.pDepthAttachment = DE_NULL;
1476 		m_renderingInfo.pStencilAttachment = DE_NULL;
1477 	}
1478 
1479 	if (m_activeSubpass < (deUint32)m_viewMasks.size())
1480 		m_renderingInfo.viewMask = m_viewMasks[m_activeSubpass];
1481 
1482 	m_renderingInfo.pNext = DE_NULL;
1483 	if (subpass.m_msrtss.sType == VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT)
1484 	{
1485 		subpass.m_msrtss.pNext = DE_NULL;
1486 		m_renderingInfo.pNext = &subpass.m_msrtss;
1487 	}
1488 
1489 	if (subpass.m_dsr.sType == VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE)
1490 	{
1491 		depthAttachment.resolveMode = subpass.m_dsr.depthResolveMode;
1492 		stencilAttachment.resolveMode = subpass.m_dsr.stencilResolveMode;
1493 		if (subpass.m_dsr.pDepthStencilResolveAttachment)
1494 		{
1495 			depthAttachment.resolveImageView = m_imageViews[subpass.m_dsr.pDepthStencilResolveAttachment->attachment];
1496 			depthAttachment.resolveImageLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1497 			stencilAttachment.resolveImageView = m_imageViews[subpass.m_dsr.pDepthStencilResolveAttachment->attachment];
1498 			stencilAttachment.resolveImageLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1499 		}
1500 	}
1501 
1502 	m_renderingInfo.flags = (VkRenderingFlags)0u;
1503 
1504 	if (m_secondaryCommandBuffers)
1505 		m_renderingInfo.flags |= VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1506 
1507 	vk.cmdBeginRendering(commandBuffer, &m_renderingInfo);
1508 #endif
1509 }
1510 
nextSubpass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkSubpassContents contents) const1511 void RenderPassWrapper::nextSubpass (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkSubpassContents contents) const
1512 {
1513 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1514 	{
1515 		vk.cmdNextSubpass(commandBuffer, contents);
1516 	}
1517 	else
1518 	{
1519 #ifndef CTS_USES_VULKANSC
1520 		vk.cmdEndRendering(commandBuffer);
1521 		++m_activeSubpass;
1522 		DE_ASSERT(m_activeSubpass < (deUint32)m_subpasses.size());
1523 
1524 		const auto& subpass = m_subpasses[m_activeSubpass];
1525 
1526 		transitionLayouts(vk, commandBuffer, subpass, false);
1527 
1528 		insertDependencies(vk, commandBuffer, m_activeSubpass);
1529 
1530 		beginRendering(vk, commandBuffer);
1531 #endif
1532 	}
1533 }
1534 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,const std::vector<vk::VkImage> & images)1535 void RenderPassWrapper::createFramebuffer (const DeviceInterface& vk, const VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const std::vector<vk::VkImage>& images)
1536 {
1537 	DE_UNREF(images);
1538 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1539 	{
1540 		m_framebuffer = vk::createFramebuffer(vk, device, pCreateInfo);
1541 	}
1542 	else
1543 	{
1544 #ifndef CTS_USES_VULKANSC
1545 		m_images = images;
1546 		m_imageViews.resize(pCreateInfo->attachmentCount);
1547 		for (deUint32 i = 0; i < pCreateInfo->attachmentCount; ++i)
1548 			m_imageViews[i] = pCreateInfo->pAttachments[i];
1549 
1550 		for (auto& subpass : m_subpasses)
1551 		{
1552 			for (deUint32 i = 0; i < (deUint32)subpass.m_colorAttachments.size(); ++i)
1553 			{
1554 				if (subpass.m_colorAttachments[i].index != VK_ATTACHMENT_UNUSED)
1555 					subpass.m_colorAttachments[i].attachmentInfo.imageView = pCreateInfo->pAttachments[subpass.m_colorAttachments[i].index];
1556 			}
1557 
1558 			if (subpass.m_depthStencilAttachment.attachmentInfo.imageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
1559 			{
1560 				if (subpass.m_depthStencilAttachment.index != VK_ATTACHMENT_UNUSED)
1561 					subpass.m_depthStencilAttachment.attachmentInfo.imageView = pCreateInfo->pAttachments[subpass.m_depthStencilAttachment.index];
1562 			}
1563 
1564 			for (deUint32 i = 0; i < (deUint32)subpass.m_resolveAttachments.size(); ++i)
1565 			{
1566 				if (subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1567 					subpass.m_resolveAttachments[i].attachmentInfo.imageView = pCreateInfo->pAttachments[subpass.m_resolveAttachments[i].index];
1568 			}
1569 		}
1570 		m_layers = pCreateInfo->layers;
1571 #endif
1572 	}
1573 }
1574 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,vk::VkImage colorImage,vk::VkImage depthStencilImage)1575 void RenderPassWrapper::createFramebuffer (const DeviceInterface& vk, const VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, vk::VkImage colorImage, vk::VkImage depthStencilImage)
1576 {
1577 	DE_UNREF(colorImage);
1578 	DE_UNREF(depthStencilImage);
1579 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1580 	{
1581 		m_framebuffer = vk::createFramebuffer(vk, device, pCreateInfo);
1582 	}
1583 	else
1584 	{
1585 #ifndef CTS_USES_VULKANSC
1586 		if (colorImage != VK_NULL_HANDLE)
1587 		{
1588 			m_images.push_back(colorImage);
1589 			DE_ASSERT(pCreateInfo->attachmentCount > 0);
1590 			m_imageViews.push_back(pCreateInfo->pAttachments[0]);
1591 		}
1592 		if (depthStencilImage != VK_NULL_HANDLE)
1593 			m_images.push_back(depthStencilImage);
1594 		for (auto& subpass : m_subpasses)
1595 		{
1596 			DE_ASSERT(subpass.m_colorAttachments.size() <= 1);
1597 			if (pCreateInfo->pAttachments)
1598 			{
1599 				if (!subpass.m_colorAttachments.empty() && subpass.m_colorAttachments[0].index < pCreateInfo->attachmentCount)
1600 					subpass.m_colorAttachments[0].attachmentInfo.imageView = pCreateInfo->pAttachments[subpass.m_colorAttachments[0].index];
1601 				if (subpass.m_depthStencilAttachment.index < pCreateInfo->attachmentCount)
1602 					subpass.m_depthStencilAttachment.attachmentInfo.imageView = pCreateInfo->pAttachments[subpass.m_depthStencilAttachment.index];
1603 			}
1604 		}
1605 #endif
1606 	}
1607 }
1608 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkImage colorImage,const VkImageView colorAttachment,const deUint32 width,const deUint32 height,const deUint32 layers)1609 void RenderPassWrapper::createFramebuffer (const DeviceInterface& vk, const VkDevice device, const VkImage colorImage, const VkImageView colorAttachment, const deUint32 width, const deUint32 height, const deUint32 layers)
1610 {
1611 	DE_UNREF(colorImage);
1612 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1613 	{
1614 		VkFramebufferCreateInfo createInfo = initVulkanStructure();
1615 		createInfo.flags = (VkFramebufferCreateFlags)0u;
1616 		createInfo.renderPass = *m_renderPass;
1617 		createInfo.attachmentCount = (colorAttachment != VK_NULL_HANDLE) ? 1u : 0u;
1618 		createInfo.pAttachments = &colorAttachment;
1619 		createInfo.width = width;
1620 		createInfo.height = height;
1621 		createInfo.layers = layers;
1622 		m_framebuffer = vk::createFramebuffer(vk, device, &createInfo);
1623 	}
1624 	else
1625 	{
1626 #ifndef CTS_USES_VULKANSC
1627 		m_images.push_back(colorImage);
1628 		m_imageViews.push_back(colorAttachment);
1629 		if (colorImage != VK_NULL_HANDLE)
1630 		{
1631 			for (auto& subpass : m_subpasses)
1632 			{
1633 				DE_ASSERT(subpass.m_colorAttachments.size() == 1);
1634 				subpass.m_colorAttachments[0].attachmentInfo.imageView = colorAttachment;
1635 			}
1636 		}
1637 #endif
1638 	}
1639 }
1640 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const deUint32 attachmentCount,const VkImage * imagesArray,const VkImageView * attachmentsArray,const deUint32 width,const deUint32 height,const deUint32 layers)1641 void RenderPassWrapper::createFramebuffer (const DeviceInterface& vk, const VkDevice device, const deUint32 attachmentCount, const VkImage* imagesArray, const VkImageView* attachmentsArray, const deUint32 width, const deUint32 height, const deUint32 layers)
1642 {
1643 	DE_UNREF(imagesArray);
1644 	if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
1645 	{
1646 		VkFramebufferCreateInfo createInfo = initVulkanStructure();
1647 		createInfo.flags = (VkFramebufferCreateFlags)0u;
1648 		createInfo.renderPass = *m_renderPass;
1649 		createInfo.attachmentCount = attachmentCount;
1650 		createInfo.pAttachments = attachmentsArray;
1651 		createInfo.width = width;
1652 		createInfo.height = height;
1653 		createInfo.layers = layers;
1654 		m_framebuffer = vk::createFramebuffer(vk, device, &createInfo);
1655 	}
1656 	else
1657 	{
1658 #ifndef CTS_USES_VULKANSC
1659 		for (deUint32 i = 0; i < attachmentCount; ++i)
1660 		{
1661 			m_images.push_back(imagesArray[i]);
1662 			m_imageViews.push_back(attachmentsArray[i]);
1663 		}
1664 		for (auto& subpass : m_subpasses)
1665 		{
1666 			for (deUint32 i = 0; i < (deUint32)subpass.m_colorAttachments.size(); ++i)
1667 			{
1668 				if (subpass.m_colorAttachments[i].index != VK_ATTACHMENT_UNUSED)
1669 					subpass.m_colorAttachments[i].attachmentInfo.imageView = attachmentsArray[subpass.m_colorAttachments[i].index];
1670 			}
1671 			if (subpass.m_depthStencilAttachment.attachmentInfo.imageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
1672 			{
1673 				if (subpass.m_depthStencilAttachment.index != VK_ATTACHMENT_UNUSED)
1674 					subpass.m_depthStencilAttachment.attachmentInfo.imageView = attachmentsArray[subpass.m_depthStencilAttachment.index];
1675 			}
1676 			for (deUint32 i = 0; i < (deUint32)subpass.m_resolveAttachments.size(); ++i)
1677 			{
1678 				if (subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1679 					subpass.m_resolveAttachments[i].attachmentInfo.imageView = attachmentsArray[subpass.m_resolveAttachments[i].index];
1680 			}
1681 		}
1682 #endif
1683 	}
1684 }
1685 
ShaderWrapper()1686 ShaderWrapper::ShaderWrapper ()
1687 	: m_vk					(DE_NULL)
1688 	, m_device				(VK_NULL_HANDLE)
1689 	, m_binary				(DE_NULL)
1690 	, m_moduleCreateFlags	((VkShaderModuleCreateFlags)0u)
1691 	, m_layout				(DE_NULL)
1692 	, m_specializationInfo	(DE_NULL)
1693 #ifndef CTS_USES_VULKANSC
1694 	, m_shaderCreateFlags	((VkShaderCreateFlagsEXT)0u)
1695 	, m_binaryDataSize		(0u)
1696 #endif
1697 {
1698 }
1699 
ShaderWrapper(const DeviceInterface & vk,VkDevice device,const vk::ProgramBinary & binary,const vk::VkShaderModuleCreateFlags createFlags)1700 ShaderWrapper::ShaderWrapper (const DeviceInterface& vk, VkDevice device, const vk::ProgramBinary& binary, const vk::VkShaderModuleCreateFlags createFlags)
1701 	: m_vk					(&vk)
1702 	, m_device				(device)
1703 	, m_binary				(&binary)
1704 	, m_moduleCreateFlags	(createFlags)
1705 	, m_layout				(DE_NULL)
1706 	, m_specializationInfo(DE_NULL)
1707 #ifndef CTS_USES_VULKANSC
1708 	, m_shaderCreateFlags	((VkShaderCreateFlagsEXT)0u)
1709 	, m_binaryDataSize		(0u)
1710 #endif
1711 {
1712 }
1713 
ShaderWrapper(const ShaderWrapper & rhs)1714 ShaderWrapper::ShaderWrapper (const ShaderWrapper& rhs) noexcept
1715 	: m_vk					(rhs.m_vk)
1716 	, m_device				(rhs.m_device)
1717 	, m_binary				(rhs.m_binary)
1718 	, m_moduleCreateFlags	(rhs.m_moduleCreateFlags)
1719 	, m_layout				(rhs.m_layout)
1720 	, m_specializationInfo	(rhs.m_specializationInfo)
1721 #ifndef CTS_USES_VULKANSC
1722 	, m_shaderCreateFlags	(rhs.m_shaderCreateFlags)
1723 	, m_binaryDataSize		(rhs.m_binaryDataSize)
1724 	, m_binaryData			(rhs.m_binaryData)
1725 #endif
1726 {}
1727 
operator =(const ShaderWrapper & rhs)1728 ShaderWrapper& ShaderWrapper::operator= (const ShaderWrapper& rhs) noexcept
1729 {
1730 	m_vk = rhs.m_vk;
1731 	m_device = rhs.m_device;
1732 	m_binary = rhs.m_binary;
1733 	m_moduleCreateFlags = rhs.m_moduleCreateFlags;
1734 	m_layout = rhs.m_layout;
1735 	m_specializationInfo = rhs.m_specializationInfo;
1736 #ifndef CTS_USES_VULKANSC
1737 	m_shaderCreateFlags = rhs.m_shaderCreateFlags;
1738 	m_binaryDataSize = rhs.m_binaryDataSize;
1739 	m_binaryData = rhs.m_binaryData;
1740 #endif
1741 
1742 	return *this;
1743 }
1744 
getModule(void) const1745 vk::VkShaderModule ShaderWrapper::getModule (void) const
1746 {
1747 	if (!m_module)
1748 	{
1749 		if (!m_vk)
1750 			return DE_NULL;
1751 		m_module = createShaderModule(*m_vk, m_device, *m_binary, m_moduleCreateFlags);
1752 	}
1753 	return *m_module;
1754 }
1755 
getCodeSize(void) const1756 size_t ShaderWrapper::getCodeSize (void) const
1757 {
1758 	return m_binary->getSize();
1759 }
1760 
getBinary(void) const1761 void* ShaderWrapper::getBinary (void) const
1762 {
1763 	return (void*)m_binary->getBinary();
1764 }
1765 
createModule(void)1766 void ShaderWrapper::createModule (void)
1767 {
1768 	if (m_vk)
1769 		m_module = createShaderModule(*m_vk, m_device, *m_binary, m_moduleCreateFlags);
1770 }
1771 
setLayoutAndSpecialization(const PipelineLayoutWrapper * layout,const VkSpecializationInfo * specializationInfo)1772 void ShaderWrapper::setLayoutAndSpecialization (const PipelineLayoutWrapper* layout, const VkSpecializationInfo* specializationInfo)
1773 {
1774 	m_layout = layout;
1775 	m_specializationInfo = specializationInfo;
1776 }
1777 
1778 #ifndef CTS_USES_VULKANSC
getShaderBinary(void)1779 void ShaderWrapper::getShaderBinary (void)
1780 {
1781 	m_vk->getShaderBinaryDataEXT(m_device, *m_shader, &m_binaryDataSize, DE_NULL);
1782 	m_binaryData.resize(m_binaryDataSize);
1783 	m_vk->getShaderBinaryDataEXT(m_device, *m_shader, &m_binaryDataSize, m_binaryData.data());
1784 }
1785 #endif
1786 
1787 // Structure storing *CreateInfo structures that do not need to exist in memory after pipeline was constructed.
1788 struct GraphicsPipelineWrapper::InternalData
1789 {
1790 	const InstanceInterface&							vki;
1791 	const DeviceInterface&								vk;
1792 	VkPhysicalDevice									physicalDevice;
1793 	VkDevice											device;
1794 	const std::vector<std::string>&						deviceExtensions;
1795 	const PipelineConstructionType						pipelineConstructionType;
1796 	const VkPipelineCreateFlags							pipelineFlags;
1797 	PipelineCreateFlags2								pipelineFlags2;
1798 
1799 	// attribute used for making sure pipeline is configured in correct order
1800 	int													setupState;
1801 
1802 	std::vector<PipelineShaderStageModuleIdPtr>			pipelineShaderIdentifiers;
1803 	std::vector<VkPipelineShaderStageCreateInfo>		pipelineShaderStages;
1804 	VkPipelineInputAssemblyStateCreateInfo				inputAssemblyState;
1805 	VkPipelineRasterizationStateCreateInfo				defaultRasterizationState;
1806 	VkPipelineViewportStateCreateInfo					viewportState;
1807 	VkPipelineTessellationStateCreateInfo				tessellationState;
1808 	VkPipelineFragmentShadingRateStateCreateInfoKHR*	pFragmentShadingRateState;
1809 	PipelineRenderingCreateInfoWrapper					pRenderingState;
1810 	const VkPipelineDynamicStateCreateInfo*				pDynamicState;
1811 	PipelineRepresentativeFragmentTestCreateInfoWrapper	pRepresentativeFragmentTestState;
1812 
1813 	TessellationDomainOriginStatePtr					pTessellationDomainOrigin;
1814 	deBool												useViewportState;
1815 	deBool												useDefaultRasterizationState;
1816 	deBool												useDefaultDepthStencilState;
1817 	deBool												useDefaultColorBlendState;
1818 	deBool												useDefaultMultisampleState;
1819 	deBool												useDefaultVertexInputState;
1820 	bool												failOnCompileWhenLinking;
1821 
1822 	VkGraphicsPipelineCreateInfo						monolithicPipelineCreateInfo;
1823 
1824 	ShaderWrapper										vertexShader;
1825 	ShaderWrapper										tessellationControlShader;
1826 	ShaderWrapper										tessellationEvaluationShader;
1827 	ShaderWrapper										geometryShader;
1828 	ShaderWrapper										fragmentShader;
1829 
1830 	ShaderWrapper										meshShader;
1831 	ShaderWrapper										taskShader;
1832 
1833 	bool												tessellationShaderFeature;
1834 	bool												geometryShaderFeature;
1835 	bool												taskShaderFeature;
1836 	bool												meshShaderFeature;
1837 
1838 	// Store all dynamic state that are used with shader objects
1839 	std::vector<vk::VkDynamicState>						shaderObjectDynamicStates;
1840 
1841 #ifndef CTS_USES_VULKANSC
1842 	// Store the state that a pipeline would be created with, but shader objects have to set dynamically
1843 	struct PipelineCreateState {
1844 		std::vector<VkViewport>								viewports;
1845 		std::vector<VkRect2D>								scissors;
1846 		float												lineWidth = 1.0f;
1847 		VkDepthBiasRepresentationEXT						depthBiasRepresentation = vk::VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT;
1848 		VkBool32											depthBiasExact = VK_FALSE;
1849 		float												depthBiasConstantFactor = 0.0f;
1850 		float												depthBiasClamp = 0.0f;
1851 		float												depthBiasSlopeFactor = 1.0f;
1852 		float												blendConstants[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
1853 		float												minDepthBounds = 0.0f;
1854 		float												maxDepthBounds = 1.0f;
1855 		VkStencilOpState									stencilFront = { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0 };
1856 		VkStencilOpState									stencilBack = { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0 };
1857 		VkCullModeFlags										cullMode = VK_CULL_MODE_NONE;
1858 		deBool												depthTestEnable = VK_FALSE;
1859 		deBool												depthWriteEnable = VK_FALSE;
1860 		VkCompareOp											depthCompareOp = VK_COMPARE_OP_NEVER;
1861 		deBool												depthBoundsTestEnable = VK_FALSE;
1862 		VkFrontFace											frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1863 		VkPrimitiveTopology									topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1864 		deBool												stencilTestEnable = VK_FALSE;
1865 		std::vector<VkVertexInputAttributeDescription2EXT>	attributes;
1866 		std::vector<VkVertexInputBindingDescription2EXT>	bindings;
1867 		deBool												depthBiasEnable = VK_FALSE;
1868 		VkLogicOp											logicOp = VK_LOGIC_OP_CLEAR;
1869 		uint32_t											patchControlPoints = 1;
1870 		deBool												primitiveRestartEnable = VK_FALSE;
1871 		deBool												rasterizerDiscardEnable = VK_FALSE;
1872 		deBool												alphaToCoverageEnable = VK_FALSE;
1873 		deBool												alphaToOneEnable = VK_FALSE;
1874 		std::vector<VkColorBlendAdvancedEXT>				colorBlendAdvanced;
1875 		std::vector<VkBool32>								colorBlendEnables;
1876 		std::vector<VkColorBlendEquationEXT>				blendEquations;
1877 		std::vector<VkColorComponentFlags>					colorWriteMasks;
1878 		VkConservativeRasterizationModeEXT					conservativeRasterizationMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
1879 		VkCoverageModulationModeNV							coverageModulationMode = VK_COVERAGE_MODULATION_MODE_NONE_NV;
1880 		deBool												coverageModulationTableEnable = VK_FALSE;
1881 		std::vector<float>									coverageModulationTable;
1882 		VkCoverageReductionModeNV							coverageReductionMode = VK_COVERAGE_REDUCTION_MODE_MERGE_NV;
1883 		deBool												coverageToColorEnable = VK_FALSE;
1884 		deUint32											coverageToColorLocation = 0;
1885 		deBool												depthClampEnable = VK_FALSE;
1886 		deBool												depthClipEnable = VK_FALSE;
1887 		deBool												negativeOneToOne = VK_FALSE;
1888 		deUint32											colorWriteEnableAttachmentCount = 0;
1889 		std::vector<VkBool32>								colorWriteEnables;
1890 		float												extraPrimitiveOverestimationSize = 0.0f;
1891 		VkLineRasterizationModeEXT							lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
1892 		deBool												stippledLineEnable = VK_FALSE;
1893 		deUint32											lineStippleFactor = 1;
1894 		deUint16											lineStipplePattern = 0x1;
1895 		deBool												logicOpEnable = VK_FALSE;
1896 		VkPolygonMode										polygonMode = VK_POLYGON_MODE_FILL;
1897 		VkProvokingVertexModeEXT							provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
1898 		VkSampleCountFlagBits								rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1899 		VkExtent2D											fragmentShadingRateSize = { 1u, 1u };
1900 		VkFragmentShadingRateCombinerOpKHR					combinerOps[2] = { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR };
1901 		deUint32											rasterizationStream = 0;
1902 		deBool												representativeFragmentTestEnable = VK_FALSE;
1903 		deBool												sampleLocationsEnable = VK_FALSE;
1904 		std::vector<VkSampleLocationEXT>					pSampleLocations;
1905 		VkSampleLocationsInfoEXT							sampleLocationsInfo = vk::initVulkanStructure();
1906 		std::vector<VkSampleMask>							sampleMasks;
1907 		deBool												shadingRateImageEnable = VK_FALSE;
1908 		VkTessellationDomainOrigin							domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT;
1909 		std::vector<VkViewportSwizzleNV>					viewportSwizzles;
1910 		deBool												viewportWScalingEnable = VK_FALSE;
1911 		deUint32											viewportWScalingCount = 0;
1912 		std::vector<VkViewportWScalingNV>					viewportWScalings;
1913 		VkCoarseSampleOrderTypeNV							coarseSampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV;
1914 		deUint32											coarseCustomSampleOrderCount = 0;
1915 		std::vector<std::vector<VkCoarseSampleLocationNV>>	coarseSampleLocations;
1916 		std::vector<VkCoarseSampleOrderCustomNV>			coarseCustomSampleOrders;
1917 		deUint32											shadingRatePaletteCount = 0;
1918 		std::vector<std::vector<VkShadingRatePaletteEntryNV>> shadingRatePaletteEntries;
1919 		std::vector<VkShadingRatePaletteNV>					shadingRatePalettes;
1920 		deUint32											exclusiveScissorCount = 0;
1921 		std::vector<VkRect2D>								exclussiveScissors;
1922 		deBool												discardRectangleEnable = VK_FALSE;
1923 		std::vector<VkRect2D>								discardRectangles;
1924 		VkDiscardRectangleModeEXT							discardRectangleMode = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
1925 		VkImageAspectFlags									attachmentFeedbackLoopEnable = VK_IMAGE_ASPECT_NONE;
1926 	} pipelineCreateState;
1927 #endif
1928 
1929 	// initialize with most common values
InternalDatavk::GraphicsPipelineWrapper::InternalData1930 	InternalData(const InstanceInterface& instanceInterface, const DeviceInterface& vkd, VkPhysicalDevice physDevice, VkDevice vkDevice, const std::vector<std::string>& deviceExts, const PipelineConstructionType constructionType, const VkPipelineCreateFlags pipelineCreateFlags)
1931 		: vki						(instanceInterface)
1932 		, vk						(vkd)
1933 		, physicalDevice			(physDevice)
1934 		, device					(vkDevice)
1935 		, deviceExtensions			(deviceExts)
1936 		, pipelineConstructionType	(constructionType)
1937 		, pipelineFlags				(pipelineCreateFlags)
1938 		, pipelineFlags2			(0u)
1939 		, setupState				(PSS_NONE)
1940 		, inputAssemblyState
1941 		{
1942 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType								sType
1943 			DE_NULL,														// const void*									pNext
1944 			0u,																// VkPipelineInputAssemblyStateCreateFlags		flags
1945 			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology							topology
1946 			VK_FALSE														// VkBool32										primitiveRestartEnable
1947 		}
1948 		, defaultRasterizationState
1949 		{
1950 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType								sType
1951 			DE_NULL,														// const void*									pNext
1952 			0u,																// VkPipelineRasterizationStateCreateFlags		flags
1953 			VK_FALSE,														// VkBool32										depthClampEnable
1954 			VK_FALSE,														// VkBool32										rasterizerDiscardEnable
1955 			VK_POLYGON_MODE_FILL,											// VkPolygonMode								polygonMode
1956 			VK_CULL_MODE_NONE,												// VkCullModeFlags								cullMode
1957 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace									frontFace
1958 			VK_FALSE,														// VkBool32										depthBiasEnable
1959 			0.0f,															// float										depthBiasConstantFactor
1960 			0.0f,															// float										depthBiasClamp
1961 			0.0f,															// float										depthBiasSlopeFactor
1962 			1.0f															// float										lineWidth
1963 		}
1964 		, viewportState
1965 		{
1966 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType								sType
1967 			DE_NULL,														// const void*									pNext
1968 			(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags			flags
1969 			1u,																// deUint32										viewportCount
1970 			DE_NULL,														// const VkViewport*							pViewports
1971 			1u,																// deUint32										scissorCount
1972 			DE_NULL															// const VkRect2D*								pScissors
1973 		}
1974 		, tessellationState
1975 		{
1976 			VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType								sType
1977 			DE_NULL,														// const void*									pNext
1978 			0u,																// VkPipelineTessellationStateCreateFlags		flags
1979 			3u																// deUint32										patchControlPoints
1980 		}
1981 		, pFragmentShadingRateState		(nullptr)
1982 		, pDynamicState					(DE_NULL)
1983 		, pRepresentativeFragmentTestState(nullptr)
1984 		, pTessellationDomainOrigin		()
1985 		, useViewportState				(DE_TRUE)
1986 		, useDefaultRasterizationState	(DE_FALSE)
1987 		, useDefaultDepthStencilState	(DE_FALSE)
1988 		, useDefaultColorBlendState		(DE_FALSE)
1989 		, useDefaultMultisampleState	(DE_FALSE)
1990 		, useDefaultVertexInputState	(DE_TRUE)
1991 		, failOnCompileWhenLinking		(false)
1992 		, tessellationShaderFeature		(false)
1993 		, geometryShaderFeature			(false)
1994 		, taskShaderFeature				(false)
1995 		, meshShaderFeature				(false)
1996 	{
1997 		monolithicPipelineCreateInfo = initVulkanStructure();
1998 	}
1999 
extensionEnabledvk::GraphicsPipelineWrapper::InternalData2000 	bool extensionEnabled (const std::string& ext) const
2001 	{
2002 		return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
2003 	}
2004 
2005 };
2006 
GraphicsPipelineWrapper(const InstanceInterface & vki,const DeviceInterface & vk,VkPhysicalDevice physicalDevice,VkDevice device,const std::vector<std::string> & deviceExtensions,const PipelineConstructionType pipelineConstructionType,const VkPipelineCreateFlags flags)2007 GraphicsPipelineWrapper::GraphicsPipelineWrapper(const InstanceInterface&			vki,
2008 												 const DeviceInterface&				vk,
2009 												 VkPhysicalDevice					physicalDevice,
2010 												 VkDevice							device,
2011 												 const std::vector<std::string>&	deviceExtensions,
2012 												 const PipelineConstructionType		pipelineConstructionType,
2013 												 const VkPipelineCreateFlags		flags)
2014 	: m_internalData	(new InternalData(vki, vk, physicalDevice, device, deviceExtensions, pipelineConstructionType, flags))
2015 {
2016 }
2017 
GraphicsPipelineWrapper(GraphicsPipelineWrapper && pw)2018 GraphicsPipelineWrapper::GraphicsPipelineWrapper(GraphicsPipelineWrapper&& pw) noexcept
2019 	: m_pipelineFinal	(pw.m_pipelineFinal)
2020 	, m_internalData	(pw.m_internalData)
2021 {
2022 	std::move(pw.m_pipelineParts, pw.m_pipelineParts + de::arrayLength(pw.m_pipelineParts), m_pipelineParts);
2023 }
2024 
setMonolithicPipelineLayout(const PipelineLayoutWrapper & layout)2025 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setMonolithicPipelineLayout(const PipelineLayoutWrapper& layout)
2026 {
2027 	// make sure pipeline was not already built
2028 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2029 
2030 	m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2031 
2032 	return *this;
2033 }
2034 
setDynamicState(const VkPipelineDynamicStateCreateInfo * dynamicState)2035 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDynamicState(const VkPipelineDynamicStateCreateInfo* dynamicState)
2036 {
2037 	// make sure states are not yet setup - all pipeline states must know about dynamic state
2038 	DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
2039 
2040 	m_internalData->pDynamicState								= dynamicState;
2041 	m_internalData->monolithicPipelineCreateInfo.pDynamicState	= dynamicState;
2042 
2043 	return *this;
2044 }
2045 
setRepresentativeFragmentTestState(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)2046 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setRepresentativeFragmentTestState(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)
2047 {
2048 	// Representative fragment test state is needed by the fragment shader state.
2049 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2050 
2051 	m_internalData->pRepresentativeFragmentTestState = representativeFragmentTestState;
2052 	return *this;
2053 }
2054 
setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2)2055 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2)
2056 {
2057 	// make sure states are not yet setup - all pipeline states must know about createFlags2
2058 	DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
2059 
2060 	m_internalData->pipelineFlags2 = pipelineFlags2;
2061 	return *this;
2062 }
2063 
getDynamicStates(const VkPipelineDynamicStateCreateInfo * dynamicStateInfo,uint32_t setupState)2064 std::vector<VkDynamicState> getDynamicStates(const VkPipelineDynamicStateCreateInfo* dynamicStateInfo, uint32_t setupState)
2065 {
2066 	static const std::set<VkDynamicState> vertexInputStates {
2067 		VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
2068 		VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
2069 		VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
2070 		VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
2071 	};
2072 
2073 	static const std::set<VkDynamicState> preRastStates {
2074 		VK_DYNAMIC_STATE_VIEWPORT,
2075 		VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
2076 		VK_DYNAMIC_STATE_SCISSOR,
2077 		VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
2078 		VK_DYNAMIC_STATE_LINE_WIDTH,
2079 		VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
2080 		VK_DYNAMIC_STATE_CULL_MODE_EXT,
2081 		VK_DYNAMIC_STATE_FRONT_FACE_EXT,
2082 		VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
2083 		VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
2084 		VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
2085 		VK_DYNAMIC_STATE_DEPTH_BIAS,
2086 		VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
2087 		VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2088 #ifndef CTS_USES_VULKANSC
2089 		VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
2090 		VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
2091 		VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
2092 		VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT,
2093 		VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT,
2094 		VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT,
2095 		VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,
2096 		VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
2097 		VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
2098 		VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
2099 		VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT,
2100 		VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
2101 		VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV,
2102 		VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV,
2103 		VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV,
2104 		VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
2105 		VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,
2106 		VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,
2107 		VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV,
2108 #endif
2109 	};
2110 
2111 	static const std::set<VkDynamicState> fragShaderStates {
2112 		VK_DYNAMIC_STATE_DEPTH_BOUNDS,
2113 		VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
2114 		VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
2115 		VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
2116 		VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
2117 		VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
2118 		VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
2119 		VK_DYNAMIC_STATE_STENCIL_REFERENCE,
2120 		VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
2121 		VK_DYNAMIC_STATE_STENCIL_OP_EXT,
2122 		VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2123 		// Needs MSAA info here as well as fragment output state
2124 		VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
2125 #ifndef CTS_USES_VULKANSC
2126 		VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
2127 		VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
2128 		VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
2129 		VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
2130 		VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
2131 		VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
2132 		VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
2133 		VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
2134 		VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
2135 		VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
2136 		VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
2137 		VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
2138 #endif
2139 	};
2140 
2141 	static const std::set<VkDynamicState> fragOutputStates {
2142 		VK_DYNAMIC_STATE_LOGIC_OP_EXT,
2143 		VK_DYNAMIC_STATE_BLEND_CONSTANTS,
2144 		VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT,
2145 		VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2146 		VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
2147 #ifndef CTS_USES_VULKANSC
2148 		VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
2149 		VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
2150 		VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
2151 		VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
2152 		VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
2153 		VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
2154 		VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
2155 		VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
2156 		VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
2157 		VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
2158 		VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
2159 		VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
2160 		VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
2161 		VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
2162 		VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
2163 		VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
2164 		VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
2165 		VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT,
2166 #endif
2167 	};
2168 
2169 	const std::set<VkDynamicState> dynamicStates (dynamicStateInfo->pDynamicStates,
2170 												  dynamicStateInfo->pDynamicStates + dynamicStateInfo->dynamicStateCount);
2171 
2172 	// Verify all passed states are contained in at least one of the vectors above, so they won't get lost.
2173 	for (const auto dynState : dynamicStates)
2174 	{
2175 		DE_UNREF(dynState); // For release builds.
2176 		DE_ASSERT(		de::contains(vertexInputStates.begin(),	vertexInputStates.end(),	dynState)
2177 				  ||	de::contains(preRastStates.begin(),		preRastStates.end(),		dynState)
2178 				  ||	de::contains(fragShaderStates.begin(),	fragShaderStates.end(),		dynState)
2179 				  ||	de::contains(fragOutputStates.begin(),	fragOutputStates.end(),		dynState));
2180 	}
2181 
2182 	std::set<VkDynamicState> intersectedStates;
2183 
2184 	if (setupState & PSS_VERTEX_INPUT_INTERFACE)
2185 		std::set_intersection(vertexInputStates.begin(), vertexInputStates.end(), dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2186 
2187 	if (setupState & PSS_PRE_RASTERIZATION_SHADERS)
2188 		std::set_intersection(preRastStates.begin(),	 preRastStates.end(),	  dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2189 
2190 	if (setupState & PSS_FRAGMENT_SHADER)
2191 		std::set_intersection(fragShaderStates.begin(),  fragShaderStates.end(),  dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2192 
2193 	if (setupState & PSS_FRAGMENT_OUTPUT_INTERFACE)
2194 		std::set_intersection(fragOutputStates.begin(),  fragOutputStates.end(),  dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2195 
2196 	const std::vector<VkDynamicState> returnedStates (begin(intersectedStates), end(intersectedStates));
2197 
2198 	return returnedStates;
2199 }
2200 
setDefaultTopology(const VkPrimitiveTopology topology)2201 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultTopology(const VkPrimitiveTopology topology)
2202 {
2203 	// topology is needed by vertex input state, make sure vertex input state was not setup yet
2204 	DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2205 
2206 	m_internalData->inputAssemblyState.topology = topology;
2207 
2208 	return *this;
2209 }
2210 
setDefaultPatchControlPoints(const deUint32 patchControlPoints)2211 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultPatchControlPoints(const deUint32 patchControlPoints)
2212 {
2213 	// patchControlPoints are needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2214 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2215 
2216 	m_internalData->tessellationState.patchControlPoints = patchControlPoints;
2217 
2218 	return *this;
2219 }
2220 
setDefaultTessellationDomainOrigin(const VkTessellationDomainOrigin domainOrigin,bool forceExtStruct)2221 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultTessellationDomainOrigin (const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct)
2222 {
2223 	// Tessellation domain origin is needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2224 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2225 
2226 	// We need the extension structure when:
2227 	// - We want to force it.
2228 	// - The domain origin is not the default value.
2229 	// - We have already hooked the extension structure.
2230 	if (forceExtStruct || domainOrigin != VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT || m_internalData->pTessellationDomainOrigin)
2231 	{
2232 		if (!m_internalData->pTessellationDomainOrigin)
2233 		{
2234 			m_internalData->pTessellationDomainOrigin.reset(new VkPipelineTessellationDomainOriginStateCreateInfo(initVulkanStructure()));
2235 			m_internalData->tessellationState.pNext = m_internalData->pTessellationDomainOrigin.get();
2236 		}
2237 		m_internalData->pTessellationDomainOrigin->domainOrigin = domainOrigin;
2238 	}
2239 
2240 	return *this;
2241 }
2242 
setDefaultRasterizerDiscardEnable(const deBool rasterizerDiscardEnable)2243 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultRasterizerDiscardEnable(const deBool rasterizerDiscardEnable)
2244 {
2245 	// rasterizerDiscardEnable is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2246 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2247 
2248 	m_internalData->defaultRasterizationState.rasterizerDiscardEnable = rasterizerDiscardEnable;
2249 
2250 	return *this;
2251 }
2252 
2253 
setDefaultRasterizationState()2254 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultRasterizationState()
2255 {
2256 	// RasterizationState is used in pre-rasterization shader state, make sure this state was not setup yet
2257 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2258 
2259 	m_internalData->useDefaultRasterizationState = DE_TRUE;
2260 
2261 	return *this;
2262 }
2263 
setDefaultDepthStencilState()2264 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultDepthStencilState()
2265 {
2266 	// DepthStencilState is used in fragment shader state, make sure fragment shader state was not setup yet
2267 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2268 
2269 	m_internalData->useDefaultDepthStencilState = DE_TRUE;
2270 
2271 	return *this;
2272 }
2273 
setDefaultColorBlendState()2274 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultColorBlendState()
2275 {
2276 	// ColorBlendState is used in fragment shader state, make sure fragment shader state was not setup yet
2277 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2278 
2279 	m_internalData->useDefaultColorBlendState = DE_TRUE;
2280 
2281 	return *this;
2282 }
2283 
setDefaultMultisampleState()2284 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultMultisampleState()
2285 {
2286 	// MultisampleState is used in fragment shader state, make sure fragment shader state was not setup yet
2287 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2288 
2289 	m_internalData->useDefaultMultisampleState = DE_TRUE;
2290 
2291 	return *this;
2292 }
2293 
setDefaultVertexInputState(const deBool useDefaultVertexInputState)2294 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultVertexInputState(const deBool useDefaultVertexInputState)
2295 {
2296 	// Make sure vertex input state was not setup yet.
2297 	DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2298 
2299 	m_internalData->useDefaultVertexInputState = useDefaultVertexInputState;
2300 
2301 	return *this;
2302 }
2303 
setDefaultViewportsCount(deUint32 viewportCount)2304 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultViewportsCount(deUint32 viewportCount)
2305 {
2306 	// ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2307 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2308 
2309 	m_internalData->viewportState.viewportCount = viewportCount;
2310 
2311 	return *this;
2312 }
2313 
setDefaultScissorsCount(deUint32 scissorCount)2314 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultScissorsCount(deUint32 scissorCount)
2315 {
2316 	// ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2317 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2318 
2319 	m_internalData->viewportState.scissorCount = scissorCount;
2320 
2321 	return *this;
2322 }
2323 
setViewportStatePnext(const void * pNext)2324 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setViewportStatePnext(const void* pNext)
2325 {
2326 	// ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2327 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2328 
2329 	m_internalData->viewportState.pNext = pNext;
2330 
2331 	return *this;
2332 }
2333 
2334 #ifndef CTS_USES_VULKANSC
setRenderingColorAttachmentsInfo(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)2335 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setRenderingColorAttachmentsInfo(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)
2336 {
2337 	/* When both graphics pipeline library and dynamic rendering enabled, we just need only viewMask of VkPipelineRenderingCreateInfo
2338 	 * on non-fragment stages. But we need the rest info for setting up fragment output states.
2339 	 * This method provides a way to verify this condition.
2340 	 */
2341 	if (!m_internalData->pRenderingState.ptr || !isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2342 		return *this;
2343 
2344 	DE_ASSERT(m_internalData && (m_internalData->setupState > PSS_VERTEX_INPUT_INTERFACE) &&
2345 								(m_internalData->setupState < PSS_FRAGMENT_OUTPUT_INTERFACE) &&
2346 								(m_internalData->pRenderingState.ptr->viewMask == pipelineRenderingCreateInfo.ptr->viewMask));
2347 
2348 	m_internalData->pRenderingState.ptr = pipelineRenderingCreateInfo.ptr;
2349 
2350 	return *this;
2351 }
2352 #endif
2353 
disableViewportState(const bool disable)2354 GraphicsPipelineWrapper& GraphicsPipelineWrapper::disableViewportState(const bool disable)
2355 {
2356 	// ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2357 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2358 
2359 	m_internalData->useViewportState = !disable;
2360 
2361 	return *this;
2362 }
2363 
setupVertexInputState(const VkPipelineVertexInputStateCreateInfo * vertexInputState,const VkPipelineInputAssemblyStateCreateInfo * inputAssemblyState,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,const bool useNullPtrs)2364 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupVertexInputState(const VkPipelineVertexInputStateCreateInfo*		vertexInputState,
2365 																		const VkPipelineInputAssemblyStateCreateInfo*	inputAssemblyState,
2366 																		const VkPipelineCache							partPipelineCache,
2367 																		PipelineCreationFeedbackCreateInfoWrapper		partCreationFeedback,
2368 																		const bool										useNullPtrs)
2369 {
2370 	// make sure pipeline was not already build
2371 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2372 
2373 	// make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set first
2374 	DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2375 
2376 	// Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2377 	DE_UNREF(partPipelineCache);
2378 	DE_UNREF(partCreationFeedback);
2379 
2380 	m_internalData->setupState = PSS_VERTEX_INPUT_INTERFACE;
2381 
2382 	const auto pVertexInputState	= ((vertexInputState || useNullPtrs || !m_internalData->useDefaultVertexInputState)
2383 									? vertexInputState
2384 									: &defaultVertexInputState);
2385 	const auto pInputAssemblyState	= ((inputAssemblyState || useNullPtrs) ? inputAssemblyState : &m_internalData->inputAssemblyState);
2386 
2387 	if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2388 	{
2389 		m_internalData->monolithicPipelineCreateInfo.pVertexInputState = pVertexInputState;
2390 		m_internalData->monolithicPipelineCreateInfo.pInputAssemblyState = pInputAssemblyState;
2391 	}
2392 
2393 #ifndef CTS_USES_VULKANSC
2394 	// note we could just use else to if statement above but sinc
2395 	// this section is cut out for Vulkan SC its cleaner with separate if
2396 	if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2397 	{
2398 		auto	libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT);
2399 		void*	firstStructInChain = reinterpret_cast<void*>(&libraryCreateInfo);
2400 		addToChain(&firstStructInChain, partCreationFeedback.ptr);
2401 
2402 		VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2403 		std::vector<VkDynamicState> states;
2404 
2405 		if(m_internalData->pDynamicState)
2406 		{
2407 			states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2408 
2409 			pickedDynamicStateInfo.pDynamicStates = states.data();
2410 			pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2411 		}
2412 
2413 		VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2414 		pipelinePartCreateInfo.pNext						= firstStructInChain;
2415 		pipelinePartCreateInfo.flags						= (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2416 		pipelinePartCreateInfo.pVertexInputState			= pVertexInputState;
2417 		pipelinePartCreateInfo.pInputAssemblyState			= pInputAssemblyState;
2418 		pipelinePartCreateInfo.pDynamicState				= &pickedDynamicStateInfo;
2419 
2420 		if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2421 			pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2422 
2423 		VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2424 		if (m_internalData->pipelineFlags2)
2425 		{
2426 			pipelineFlags2CreateInfo.flags = m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2427 			addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2428 			pipelinePartCreateInfo.flags = 0u;
2429 		}
2430 
2431 		m_pipelineParts[0] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
2432 	}
2433 #endif // CTS_USES_VULKANSC
2434 
2435 	return *this;
2436 }
2437 
setupPreRasterizationShaderState(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const deUint32 subpass,const ShaderWrapper vertexShader,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const ShaderWrapper tessellationControlShader,const ShaderWrapper tessellationEvalShader,const ShaderWrapper geometryShader,const VkSpecializationInfo * specializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2438 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationShaderState(const std::vector<VkViewport>&					viewports,
2439 																				   const std::vector<VkRect2D>&						scissors,
2440 																				   const PipelineLayoutWrapper&						layout,
2441 																				   const VkRenderPass								renderPass,
2442 																				   const deUint32									subpass,
2443 																				   const ShaderWrapper								vertexShader,
2444 																				   const VkPipelineRasterizationStateCreateInfo*	rasterizationState,
2445 																				   const ShaderWrapper								tessellationControlShader,
2446 																				   const ShaderWrapper								tessellationEvalShader,
2447 																				   const ShaderWrapper								geometryShader,
2448 																				   const VkSpecializationInfo						*specializationInfo,
2449 																				   VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState,
2450 																				   PipelineRenderingCreateInfoWrapper				rendering,
2451 																				   const VkPipelineCache							partPipelineCache,
2452 																				   PipelineCreationFeedbackCreateInfoWrapper		partCreationFeedback)
2453 {
2454 	return setupPreRasterizationShaderState2(viewports,
2455 											 scissors,
2456 											 layout,
2457 											 renderPass,
2458 											 subpass,
2459 											 vertexShader,
2460 											 rasterizationState,
2461 											 tessellationControlShader,
2462 											 tessellationEvalShader,
2463 											 geometryShader,
2464 											 // Reuse the same specialization info for all stages.
2465 											 specializationInfo,
2466 											 specializationInfo,
2467 											 specializationInfo,
2468 											 specializationInfo,
2469 											 fragmentShadingRateState,
2470 											 rendering,
2471 											 partPipelineCache,
2472 											 partCreationFeedback);
2473 }
2474 
setupPreRasterizationShaderState2(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const deUint32 subpass,const ShaderWrapper vertexShader,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const ShaderWrapper tessellationControlShader,const ShaderWrapper tessellationEvalShader,const ShaderWrapper geometryShader,const VkSpecializationInfo * vertSpecializationInfo,const VkSpecializationInfo * tescSpecializationInfo,const VkSpecializationInfo * teseSpecializationInfo,const VkSpecializationInfo * geomSpecializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2475 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationShaderState2(const std::vector<VkViewport>&					viewports,
2476 																					const std::vector<VkRect2D>&					scissors,
2477 																					const PipelineLayoutWrapper&					layout,
2478 																					const VkRenderPass								renderPass,
2479 																					const deUint32									subpass,
2480 																					const ShaderWrapper								vertexShader,
2481 																					const VkPipelineRasterizationStateCreateInfo*	rasterizationState,
2482 																					const ShaderWrapper								tessellationControlShader,
2483 																					const ShaderWrapper								tessellationEvalShader,
2484 																					const ShaderWrapper								geometryShader,
2485 																					const VkSpecializationInfo*						vertSpecializationInfo,
2486 																					const VkSpecializationInfo*						tescSpecializationInfo,
2487 																					const VkSpecializationInfo*						teseSpecializationInfo,
2488 																					const VkSpecializationInfo*						geomSpecializationInfo,
2489 																					VkPipelineFragmentShadingRateStateCreateInfoKHR*fragmentShadingRateState,
2490 																					PipelineRenderingCreateInfoWrapper				rendering,
2491 																					const VkPipelineCache							partPipelineCache,
2492 																					PipelineCreationFeedbackCreateInfoWrapper		partCreationFeedback)
2493 {
2494 	return setupPreRasterizationShaderState3(viewports,
2495 											 scissors,
2496 											 layout,
2497 											 renderPass,
2498 											 subpass,
2499 											 vertexShader,
2500 											 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
2501 											 rasterizationState,
2502 											 tessellationControlShader,
2503 											 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
2504 											 tessellationEvalShader,
2505 											 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
2506 											 geometryShader,
2507 											 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
2508 											 vertSpecializationInfo,
2509 											 tescSpecializationInfo,
2510 											 teseSpecializationInfo,
2511 											 geomSpecializationInfo,
2512 											 fragmentShadingRateState,
2513 											 rendering,
2514 											 partPipelineCache,
2515 											 partCreationFeedback);
2516 }
2517 
setupPreRasterizationShaderState3(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const deUint32 subpass,const ShaderWrapper vertexShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const ShaderWrapper tessellationControlShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId,const ShaderWrapper tessellationEvalShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId,const ShaderWrapper geometryShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId,const VkSpecializationInfo * vertSpecializationInfo,const VkSpecializationInfo * tescSpecializationInfo,const VkSpecializationInfo * teseSpecializationInfo,const VkSpecializationInfo * geomSpecializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2518 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationShaderState3(const std::vector<VkViewport>&								viewports,
2519 																					const std::vector<VkRect2D>&								scissors,
2520 																					const PipelineLayoutWrapper&								layout,
2521 																					const VkRenderPass											renderPass,
2522 																					const deUint32												subpass,
2523 																					const ShaderWrapper											vertexShader,
2524 																					PipelineShaderStageModuleIdentifierCreateInfoWrapper		vertShaderModuleId,
2525 																					const VkPipelineRasterizationStateCreateInfo*				rasterizationState,
2526 																					const ShaderWrapper											tessellationControlShader,
2527 																					PipelineShaderStageModuleIdentifierCreateInfoWrapper		tescShaderModuleId,
2528 																					const ShaderWrapper											tessellationEvalShader,
2529 																					PipelineShaderStageModuleIdentifierCreateInfoWrapper		teseShaderModuleId,
2530 																					const ShaderWrapper											geometryShader,
2531 																					PipelineShaderStageModuleIdentifierCreateInfoWrapper		geomShaderModuleId,
2532 																					const VkSpecializationInfo*									vertSpecializationInfo,
2533 																					const VkSpecializationInfo*									tescSpecializationInfo,
2534 																					const VkSpecializationInfo*									teseSpecializationInfo,
2535 																					const VkSpecializationInfo*									geomSpecializationInfo,
2536 																					VkPipelineFragmentShadingRateStateCreateInfoKHR*			fragmentShadingRateState,
2537 																					PipelineRenderingCreateInfoWrapper							rendering,
2538 																					const VkPipelineCache										partPipelineCache,
2539 																					PipelineCreationFeedbackCreateInfoWrapper					partCreationFeedback)
2540 {
2541 	// make sure pipeline was not already build
2542 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2543 
2544 	// make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set second
2545 	DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_VERTEX_INPUT_INTERFACE));
2546 
2547 	// Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2548 	DE_UNREF(partPipelineCache);
2549 	DE_UNREF(partCreationFeedback);
2550 	DE_UNREF(vertShaderModuleId);
2551 	DE_UNREF(tescShaderModuleId);
2552 	DE_UNREF(teseShaderModuleId);
2553 	DE_UNREF(geomShaderModuleId);
2554 
2555 	m_internalData->setupState |= PSS_PRE_RASTERIZATION_SHADERS;
2556 	m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
2557 	m_internalData->pRenderingState.ptr = rendering.ptr;
2558 
2559 	const bool hasTesc = (tessellationControlShader.isSet() || tescShaderModuleId.ptr);
2560 	const bool hasTese = (tessellationEvalShader.isSet() || teseShaderModuleId.ptr);
2561 	const bool hasGeom = (geometryShader.isSet() || geomShaderModuleId.ptr);
2562 
2563 	const auto pRasterizationState = rasterizationState ? rasterizationState
2564 														: (m_internalData->useDefaultRasterizationState ? &m_internalData->defaultRasterizationState : DE_NULL);
2565 	const bool forceNullTessState	= (m_internalData->tessellationState.patchControlPoints == std::numeric_limits<uint32_t>::max());
2566 	const auto pTessellationState	= ((hasTesc || hasTese) && !forceNullTessState) ? &m_internalData->tessellationState : nullptr;
2567 	const auto pViewportState		= m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
2568 
2569 	VkPipelineCreateFlags shaderModuleIdFlags = 0u;
2570 
2571 	m_internalData->vertexShader = vertexShader;
2572 	m_internalData->vertexShader.setLayoutAndSpecialization(&layout, vertSpecializationInfo);
2573 	if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2574 		m_internalData->vertexShader.createModule();
2575 
2576 	// reserve space for all stages including fragment - this is needed when we create monolithic pipeline
2577 	m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(2u + hasTesc + hasTese + hasGeom,
2578 	{
2579 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,				// VkStructureType						sType
2580 		DE_NULL,															// const void*							pNext
2581 		0u,																	// VkPipelineShaderStageCreateFlags		flags
2582 		VK_SHADER_STAGE_VERTEX_BIT,											// VkShaderStageFlagBits				stage
2583 		m_internalData->vertexShader.getModule(),							// VkShaderModule						module
2584 		"main",																// const char*							pName
2585 		vertSpecializationInfo												// const VkSpecializationInfo*			pSpecializationInfo
2586 	});
2587 
2588 #ifndef CTS_USES_VULKANSC
2589 	if (vertShaderModuleId.ptr)
2590 	{
2591 		m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(vertShaderModuleId.ptr));
2592 		m_internalData->pipelineShaderStages[0].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2593 
2594 		if (!vertexShader.isSet())
2595 			shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2596 	}
2597 #endif // CTS_USES_VULKANSC
2598 
2599 	std::vector<VkPipelineShaderStageCreateInfo>::iterator currStage = m_internalData->pipelineShaderStages.begin() + 1;
2600 
2601 	if (hasTesc)
2602 	{
2603 		m_internalData->tessellationControlShader = tessellationControlShader;
2604 		m_internalData->tessellationControlShader.setLayoutAndSpecialization(&layout, tescSpecializationInfo);
2605 		if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2606 			m_internalData->tessellationControlShader.createModule();
2607 
2608 		currStage->stage				= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
2609 		currStage->module				= m_internalData->tessellationControlShader.getModule();
2610 		currStage->pSpecializationInfo	= tescSpecializationInfo;
2611 
2612 #ifndef CTS_USES_VULKANSC
2613 		if (tescShaderModuleId.ptr)
2614 		{
2615 			m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(tescShaderModuleId.ptr));
2616 			currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2617 
2618 			if (!tessellationControlShader.isSet())
2619 				shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2620 		}
2621 #endif // CTS_USES_VULKANSC
2622 
2623 		++currStage;
2624 	}
2625 
2626 	if (hasTese)
2627 	{
2628 		m_internalData->tessellationEvaluationShader = tessellationEvalShader;
2629 		m_internalData->tessellationEvaluationShader.setLayoutAndSpecialization(&layout, teseSpecializationInfo);
2630 		if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2631 			m_internalData->tessellationEvaluationShader.createModule();
2632 
2633 		currStage->stage				= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
2634 		currStage->module				= m_internalData->tessellationEvaluationShader.getModule();
2635 		currStage->pSpecializationInfo	= teseSpecializationInfo;
2636 
2637 #ifndef CTS_USES_VULKANSC
2638 		if (teseShaderModuleId.ptr)
2639 		{
2640 			m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(teseShaderModuleId.ptr));
2641 			currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2642 
2643 			if (!tessellationEvalShader.isSet())
2644 				shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2645 		}
2646 #endif // CTS_USES_VULKANSC
2647 
2648 		++currStage;
2649 	}
2650 
2651 	if (hasGeom)
2652 	{
2653 		m_internalData->geometryShader = geometryShader;
2654 		m_internalData->geometryShader.setLayoutAndSpecialization(&layout, geomSpecializationInfo);
2655 		if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2656 			m_internalData->geometryShader.createModule();
2657 
2658 		currStage->stage				= VK_SHADER_STAGE_GEOMETRY_BIT;
2659 		currStage->module				= m_internalData->geometryShader.getModule();
2660 		currStage->pSpecializationInfo	= geomSpecializationInfo;
2661 
2662 #ifndef CTS_USES_VULKANSC
2663 		if (geomShaderModuleId.ptr)
2664 		{
2665 			m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(geomShaderModuleId.ptr));
2666 			currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2667 
2668 			if (!geometryShader.isSet())
2669 				shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2670 		}
2671 #endif // CTS_USES_VULKANSC
2672 	}
2673 
2674 	if (pViewportState)
2675 	{
2676 		if (!viewports.empty())
2677 		{
2678 			pViewportState->viewportCount	= (deUint32)viewports.size();
2679 			pViewportState->pViewports		= &viewports[0];
2680 		}
2681 		if (!scissors.empty())
2682 		{
2683 			pViewportState->scissorCount	= (deUint32)scissors.size();
2684 			pViewportState->pScissors		= &scissors[0];
2685 		}
2686 	}
2687 
2688 	if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2689 	{
2690 		// make sure we dont overwrite layout specified with setupMonolithicPipelineLayout
2691 		if (m_internalData->monolithicPipelineCreateInfo.layout == 0)
2692 			m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2693 
2694 		m_internalData->monolithicPipelineCreateInfo.renderPass				= renderPass;
2695 		m_internalData->monolithicPipelineCreateInfo.subpass				= subpass;
2696 		m_internalData->monolithicPipelineCreateInfo.pRasterizationState	= pRasterizationState;
2697 		m_internalData->monolithicPipelineCreateInfo.pViewportState			= pViewportState;
2698 		m_internalData->monolithicPipelineCreateInfo.stageCount				= 1u + hasTesc + hasTese + hasGeom;
2699 		m_internalData->monolithicPipelineCreateInfo.pStages				= m_internalData->pipelineShaderStages.data();
2700 		m_internalData->monolithicPipelineCreateInfo.pTessellationState		= pTessellationState;
2701 		m_internalData->monolithicPipelineCreateInfo.flags					|= shaderModuleIdFlags;
2702 	}
2703 
2704 #ifndef CTS_USES_VULKANSC
2705 	// note we could just use else to if statement above but sinc
2706 	// this section is cut out for Vulkan SC its cleaner with separate if
2707 	if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2708 	{
2709 		auto	libraryCreateInfo	= makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
2710 		void*	firstStructInChain	= reinterpret_cast<void*>(&libraryCreateInfo);
2711 		addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
2712 		addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
2713 		addToChain(&firstStructInChain, partCreationFeedback.ptr);
2714 
2715 		VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2716 		std::vector<VkDynamicState> states;
2717 
2718 		if(m_internalData->pDynamicState)
2719 		{
2720 			states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2721 
2722 			pickedDynamicStateInfo.pDynamicStates = states.data();
2723 			pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2724 		}
2725 
2726 		VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2727 		pipelinePartCreateInfo.pNext				= firstStructInChain;
2728 		pipelinePartCreateInfo.flags				= (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2729 		pipelinePartCreateInfo.layout				= *layout;
2730 		pipelinePartCreateInfo.renderPass			= renderPass;
2731 		pipelinePartCreateInfo.subpass				= subpass;
2732 		pipelinePartCreateInfo.pRasterizationState	= pRasterizationState;
2733 		pipelinePartCreateInfo.pViewportState		= pViewportState;
2734 		pipelinePartCreateInfo.stageCount			= 1u + hasTesc + hasTese + hasGeom;
2735 		pipelinePartCreateInfo.pStages				= m_internalData->pipelineShaderStages.data();
2736 		pipelinePartCreateInfo.pTessellationState	= pTessellationState;
2737 		pipelinePartCreateInfo.pDynamicState		= &pickedDynamicStateInfo;
2738 
2739 		if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2740 			pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2741 
2742 		if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
2743 			m_internalData->failOnCompileWhenLinking = true;
2744 
2745 		VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2746 		if (m_internalData->pipelineFlags2)
2747 		{
2748 			pipelineFlags2CreateInfo.flags = m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2749 			addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2750 			pipelinePartCreateInfo.flags = 0u;
2751 		}
2752 
2753 		m_pipelineParts[1] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
2754 	}
2755 #endif // CTS_USES_VULKANSC
2756 
2757 	return *this;
2758 }
2759 
2760 #ifndef CTS_USES_VULKANSC
setupPreRasterizationMeshShaderState(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const deUint32 subpass,const ShaderWrapper taskShader,const ShaderWrapper meshShader,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const VkSpecializationInfo * taskSpecializationInfo,const VkSpecializationInfo * meshSpecializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,VkPipelineCreationFeedbackCreateInfoEXT * partCreationFeedback)2761 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationMeshShaderState(const std::vector<VkViewport>&					viewports,
2762 																					   const std::vector<VkRect2D>&						scissors,
2763 																					   const PipelineLayoutWrapper&						layout,
2764 																					   const VkRenderPass								renderPass,
2765 																					   const deUint32									subpass,
2766 																					   const ShaderWrapper								taskShader,
2767 																					   const ShaderWrapper								meshShader,
2768 																					   const VkPipelineRasterizationStateCreateInfo*	rasterizationState,
2769 																					   const VkSpecializationInfo						*taskSpecializationInfo,
2770 																					   const VkSpecializationInfo						*meshSpecializationInfo,
2771 																					   VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState,
2772 																					   PipelineRenderingCreateInfoWrapper				rendering,
2773 																					   const VkPipelineCache							partPipelineCache,
2774 																					   VkPipelineCreationFeedbackCreateInfoEXT			*partCreationFeedback)
2775 {
2776 	// Make sure pipeline was not already built.
2777 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2778 
2779 	// Make sure states are set in order - this state needs to be set first or second.
2780 	DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2781 
2782 	// The vertex input interface is not needed for mesh shading pipelines, so we're going to mark it as ready here.
2783 	m_internalData->setupState					|= (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS);
2784 	m_internalData->pFragmentShadingRateState	= fragmentShadingRateState;
2785 	m_internalData->pRenderingState				= rendering;
2786 
2787 	const bool hasTask				= (taskShader.isSet());
2788 	const auto taskShaderCount		= static_cast<uint32_t>(hasTask);
2789 	const auto pRasterizationState	= rasterizationState
2790 									? rasterizationState
2791 									: (m_internalData->useDefaultRasterizationState
2792 										? &m_internalData->defaultRasterizationState
2793 										: nullptr);
2794 	const auto pTessellationState	= nullptr;
2795 	const auto pViewportState		= m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
2796 
2797 	// Reserve space for all stages including fragment. This is needed when we create monolithic pipeline.
2798 	m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(2u + taskShaderCount,
2799 	{
2800 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType
2801 		nullptr,												// const void*							pNext
2802 		0u,														// VkPipelineShaderStageCreateFlags		flags
2803 		VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage
2804 		DE_NULL,												// VkShaderModule						module
2805 		"main",													// const char*							pName
2806 		nullptr,												// const VkSpecializationInfo*			pSpecializationInfo
2807 	});
2808 
2809 	// Mesh shader.
2810 	auto currStage = m_internalData->pipelineShaderStages.begin();
2811 	{
2812 		m_internalData->meshShader = meshShader;
2813 		m_internalData->meshShader.setLayoutAndSpecialization(&layout, meshSpecializationInfo);
2814 		if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2815 			m_internalData->meshShader.createModule();
2816 
2817 		auto& stageInfo = *currStage;
2818 
2819 		stageInfo.stage					= VK_SHADER_STAGE_MESH_BIT_EXT;
2820 		stageInfo.module				= m_internalData->meshShader.getModule();
2821 		stageInfo.pSpecializationInfo	= meshSpecializationInfo;
2822 
2823 		++currStage;
2824 	}
2825 
2826 	if (hasTask)
2827 	{
2828 		m_internalData->taskShader = taskShader;
2829 		m_internalData->taskShader.setLayoutAndSpecialization(&layout, taskSpecializationInfo);
2830 		if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2831 			m_internalData->taskShader.createModule();
2832 
2833 		auto& stageInfo = *currStage;
2834 
2835 		stageInfo.stage					= VK_SHADER_STAGE_TASK_BIT_EXT;
2836 		stageInfo.module				= m_internalData->taskShader.getModule();
2837 		stageInfo.pSpecializationInfo	= taskSpecializationInfo;
2838 
2839 		++currStage;
2840 	}
2841 
2842 	if (pViewportState)
2843 	{
2844 		if (!viewports.empty())
2845 		{
2846 			pViewportState->viewportCount	= (deUint32)viewports.size();
2847 			pViewportState->pViewports		= &viewports[0];
2848 		}
2849 		if (!scissors.empty())
2850 		{
2851 			pViewportState->scissorCount	= (deUint32)scissors.size();
2852 			pViewportState->pScissors		= &scissors[0];
2853 		}
2854 	}
2855 
2856 	if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2857 	{
2858 		// make sure we dont overwrite layout specified with setupMonolithicPipelineLayout
2859 		if (m_internalData->monolithicPipelineCreateInfo.layout == 0)
2860 			m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2861 
2862 		m_internalData->monolithicPipelineCreateInfo.renderPass				= renderPass;
2863 		m_internalData->monolithicPipelineCreateInfo.subpass				= subpass;
2864 		m_internalData->monolithicPipelineCreateInfo.pRasterizationState	= pRasterizationState;
2865 		m_internalData->monolithicPipelineCreateInfo.pViewportState			= pViewportState;
2866 		m_internalData->monolithicPipelineCreateInfo.stageCount				= 1u + taskShaderCount;
2867 		m_internalData->monolithicPipelineCreateInfo.pStages				= m_internalData->pipelineShaderStages.data();
2868 		m_internalData->monolithicPipelineCreateInfo.pTessellationState		= pTessellationState;
2869 	}
2870 	else
2871 	{
2872 		auto	libraryCreateInfo	= makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
2873 		void*	firstStructInChain	= reinterpret_cast<void*>(&libraryCreateInfo);
2874 		addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
2875 		addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
2876 		addToChain(&firstStructInChain, partCreationFeedback);
2877 
2878 		VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2879 		std::vector<VkDynamicState> states;
2880 
2881 		if(m_internalData->pDynamicState)
2882 		{
2883 			states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2884 
2885 			pickedDynamicStateInfo.pDynamicStates = states.data();
2886 			pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2887 		}
2888 
2889 		VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2890 		pipelinePartCreateInfo.pNext			= firstStructInChain;
2891 		pipelinePartCreateInfo.flags			= m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
2892 		pipelinePartCreateInfo.layout				= *layout;
2893 		pipelinePartCreateInfo.renderPass			= renderPass;
2894 		pipelinePartCreateInfo.subpass				= subpass;
2895 		pipelinePartCreateInfo.pRasterizationState	= pRasterizationState;
2896 		pipelinePartCreateInfo.pViewportState		= pViewportState;
2897 		pipelinePartCreateInfo.stageCount			= 1u + taskShaderCount;
2898 		pipelinePartCreateInfo.pStages				= m_internalData->pipelineShaderStages.data();
2899 		pipelinePartCreateInfo.pTessellationState	= pTessellationState;
2900 		pipelinePartCreateInfo.pDynamicState		= &pickedDynamicStateInfo;
2901 
2902 		if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2903 			pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2904 
2905 		VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2906 		if (m_internalData->pipelineFlags2)
2907 		{
2908 			pipelineFlags2CreateInfo.flags = m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2909 			addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2910 			pipelinePartCreateInfo.flags = 0u;
2911 		}
2912 
2913 		m_pipelineParts[1] = createGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
2914 	}
2915 
2916 	return *this;
2917 }
2918 #endif // CTS_USES_VULKANSC
2919 
setupFragmentShaderState(const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const deUint32 subpass,const ShaderWrapper fragmentShader,const VkPipelineDepthStencilStateCreateInfo * depthStencilState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkSpecializationInfo * specializationInfo,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2920 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupFragmentShaderState(const PipelineLayoutWrapper&						layout,
2921 																		   const VkRenderPass								renderPass,
2922 																		   const deUint32									subpass,
2923 																		   const ShaderWrapper								fragmentShader,
2924 																		   const VkPipelineDepthStencilStateCreateInfo*		depthStencilState,
2925 																		   const VkPipelineMultisampleStateCreateInfo*		multisampleState,
2926 																		   const VkSpecializationInfo*						specializationInfo,
2927 																		   const VkPipelineCache							partPipelineCache,
2928 																		   PipelineCreationFeedbackCreateInfoWrapper		partCreationFeedback)
2929 {
2930 	return setupFragmentShaderState2(layout,
2931 									 renderPass,
2932 									 subpass,
2933 									 fragmentShader,
2934 									 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
2935 									 depthStencilState,
2936 									 multisampleState,
2937 									 specializationInfo,
2938 									 partPipelineCache,
2939 									 partCreationFeedback);
2940 }
2941 
setupFragmentShaderState2(const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const deUint32 subpass,const ShaderWrapper fragmentShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId,const VkPipelineDepthStencilStateCreateInfo * depthStencilState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkSpecializationInfo * specializationInfo,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2942 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupFragmentShaderState2(const PipelineLayoutWrapper&								layout,
2943 																			const VkRenderPass											renderPass,
2944 																			const deUint32												subpass,
2945 																			const ShaderWrapper											fragmentShader,
2946 																			PipelineShaderStageModuleIdentifierCreateInfoWrapper		fragmentShaderModuleId,
2947 																			const VkPipelineDepthStencilStateCreateInfo*				depthStencilState,
2948 																			const VkPipelineMultisampleStateCreateInfo*					multisampleState,
2949 																			const VkSpecializationInfo*									specializationInfo,
2950 																			const VkPipelineCache										partPipelineCache,
2951 																			PipelineCreationFeedbackCreateInfoWrapper					partCreationFeedback)
2952 {
2953 	// make sure pipeline was not already build
2954 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2955 
2956 	// make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set third
2957 	DE_ASSERT(m_internalData && (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS)));
2958 
2959 	// Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2960 	DE_UNREF(layout);
2961 	DE_UNREF(renderPass);
2962 	DE_UNREF(subpass);
2963 	DE_UNREF(partPipelineCache);
2964 	DE_UNREF(partCreationFeedback);
2965 	DE_UNREF(fragmentShaderModuleId);
2966 
2967 	m_internalData->setupState |= PSS_FRAGMENT_SHADER;
2968 
2969 	const auto pDepthStencilState	= depthStencilState ? depthStencilState
2970 														: (m_internalData->useDefaultDepthStencilState ? &defaultDepthStencilState : DE_NULL);
2971 	const auto pMultisampleState	= multisampleState ? multisampleState
2972 														: (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
2973 	const bool hasFrag				= (fragmentShader.isSet() || fragmentShaderModuleId.ptr);
2974 
2975 	VkPipelineCreateFlags shaderModuleIdFlags = 0u;
2976 
2977 	deUint32 stageIndex = 1;
2978 	if (hasFrag)
2979 	{
2980 		// find free space for fragment shader
2981 		for (; stageIndex < 5; ++stageIndex)
2982 		{
2983 			if (m_internalData->pipelineShaderStages[stageIndex].stage == VK_SHADER_STAGE_VERTEX_BIT)
2984 			{
2985 				m_internalData->fragmentShader = fragmentShader;
2986 				m_internalData->fragmentShader.setLayoutAndSpecialization(&layout, specializationInfo);
2987 				if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2988 					m_internalData->fragmentShader.createModule();
2989 
2990 				m_internalData->pipelineShaderStages[stageIndex].stage					= VK_SHADER_STAGE_FRAGMENT_BIT;
2991 				m_internalData->pipelineShaderStages[stageIndex].module					= m_internalData->fragmentShader.getModule();
2992 				m_internalData->pipelineShaderStages[stageIndex].pSpecializationInfo	= specializationInfo;
2993 #ifndef CTS_USES_VULKANSC
2994 				if (fragmentShaderModuleId.ptr)
2995 				{
2996 					m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(fragmentShaderModuleId.ptr));
2997 					m_internalData->pipelineShaderStages[stageIndex].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2998 
2999 					if (!fragmentShader.isSet())
3000 						shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
3001 				}
3002 #endif // CTS_USES_VULKANSC
3003 				break;
3004 			}
3005 		}
3006 	}
3007 
3008 	if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3009 	{
3010 		m_internalData->monolithicPipelineCreateInfo.pDepthStencilState	= pDepthStencilState;
3011 		m_internalData->monolithicPipelineCreateInfo.pMultisampleState	= pMultisampleState;
3012 		m_internalData->monolithicPipelineCreateInfo.stageCount			+= (hasFrag ? 1u : 0u);
3013 		m_internalData->monolithicPipelineCreateInfo.flags				|= shaderModuleIdFlags;
3014 	}
3015 
3016 #ifndef CTS_USES_VULKANSC
3017 	// note we could just use else to if statement above but sinc
3018 	// this section is cut out for Vulkan SC its cleaner with separate if
3019 	if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3020 	{
3021 		auto	libraryCreateInfo	= makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT);
3022 		void*	firstStructInChain	= reinterpret_cast<void*>(&libraryCreateInfo);
3023 		addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
3024 		addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
3025 		addToChain(&firstStructInChain, partCreationFeedback.ptr);
3026 		addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
3027 
3028 		VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
3029 		std::vector<VkDynamicState> states;
3030 
3031 		if(m_internalData->pDynamicState)
3032 		{
3033 			states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
3034 
3035 			pickedDynamicStateInfo.pDynamicStates = states.data();
3036 			pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
3037 		}
3038 
3039 		VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
3040 		pipelinePartCreateInfo.pNext				= firstStructInChain;
3041 		pipelinePartCreateInfo.flags				= (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
3042 		pipelinePartCreateInfo.layout				= *layout;
3043 		pipelinePartCreateInfo.renderPass			= renderPass;
3044 		pipelinePartCreateInfo.subpass				= subpass;
3045 		pipelinePartCreateInfo.pDepthStencilState	= pDepthStencilState;
3046 		pipelinePartCreateInfo.pMultisampleState	= pMultisampleState;
3047 		pipelinePartCreateInfo.stageCount			= hasFrag;
3048 		pipelinePartCreateInfo.pStages				= hasFrag ? &m_internalData->pipelineShaderStages[stageIndex] : DE_NULL;
3049 		pipelinePartCreateInfo.pDynamicState		= &pickedDynamicStateInfo;
3050 
3051 		if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3052 			pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
3053 
3054 		if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
3055 			m_internalData->failOnCompileWhenLinking = true;
3056 
3057 		VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3058 		if (m_internalData->pipelineFlags2)
3059 		{
3060 			pipelineFlags2CreateInfo.flags = m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
3061 			addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3062 			pipelinePartCreateInfo.flags = 0u;
3063 		}
3064 
3065 		m_pipelineParts[2] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
3066 	}
3067 #endif // CTS_USES_VULKANSC
3068 
3069 	return *this;
3070 }
3071 
setupFragmentOutputState(const VkRenderPass renderPass,const deUint32 subpass,const VkPipelineColorBlendStateCreateInfo * colorBlendState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)3072 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupFragmentOutputState(const VkRenderPass								renderPass,
3073 																		   const deUint32									subpass,
3074 																		   const VkPipelineColorBlendStateCreateInfo*		colorBlendState,
3075 																		   const VkPipelineMultisampleStateCreateInfo*		multisampleState,
3076 																		   const VkPipelineCache							partPipelineCache,
3077 																		   PipelineCreationFeedbackCreateInfoWrapper		partCreationFeedback)
3078 {
3079 	// make sure pipeline was not already build
3080 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
3081 
3082 	// make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set last
3083 	DE_ASSERT(m_internalData && (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS | PSS_FRAGMENT_SHADER)));
3084 	m_internalData->setupState |= PSS_FRAGMENT_OUTPUT_INTERFACE;
3085 
3086 	// Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
3087 	DE_UNREF(renderPass);
3088 	DE_UNREF(subpass);
3089 	DE_UNREF(partPipelineCache);
3090 	DE_UNREF(partCreationFeedback);
3091 
3092 	void* firstStructInChain = DE_NULL;
3093 	addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
3094 
3095 #ifndef CTS_USES_VULKANSC
3096 	addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
3097 #endif // CTS_USES_VULKANSC
3098 
3099 	const auto pColorBlendState		= colorBlendState ? colorBlendState
3100 														: (m_internalData->useDefaultColorBlendState ? &defaultColorBlendState : DE_NULL);
3101 	const auto pMultisampleState	= multisampleState ? multisampleState
3102 														: (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
3103 
3104 	if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3105 	{
3106 		m_internalData->monolithicPipelineCreateInfo.pNext				= firstStructInChain;
3107 		m_internalData->monolithicPipelineCreateInfo.flags				|= m_internalData->pipelineFlags;
3108 		m_internalData->monolithicPipelineCreateInfo.pColorBlendState	= pColorBlendState;
3109 		m_internalData->monolithicPipelineCreateInfo.pMultisampleState	= pMultisampleState;
3110 	}
3111 
3112 #ifndef CTS_USES_VULKANSC
3113 	// note we could just use else to if statement above but sinc
3114 	// this section is cut out for Vulkan SC its cleaner with separate if
3115 	if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3116 	{
3117 		auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
3118 		addToChain(&firstStructInChain, &libraryCreateInfo);
3119 		addToChain(&firstStructInChain, partCreationFeedback.ptr);
3120 
3121 
3122 		VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
3123 		std::vector<VkDynamicState> states;
3124 
3125 		if(m_internalData->pDynamicState)
3126 		{
3127 			states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
3128 
3129 			pickedDynamicStateInfo.pDynamicStates = states.data();
3130 			pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
3131 		}
3132 
3133 
3134 		VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
3135 		pipelinePartCreateInfo.pNext				= firstStructInChain;
3136 		pipelinePartCreateInfo.flags				= (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
3137 		pipelinePartCreateInfo.renderPass			= renderPass;
3138 		pipelinePartCreateInfo.subpass				= subpass;
3139 		pipelinePartCreateInfo.pColorBlendState		= pColorBlendState;
3140 		pipelinePartCreateInfo.pMultisampleState	= pMultisampleState;
3141 		pipelinePartCreateInfo.pDynamicState		= &pickedDynamicStateInfo;
3142 
3143 		if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3144 			pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
3145 
3146 		VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3147 		if (m_internalData->pipelineFlags2)
3148 		{
3149 			pipelineFlags2CreateInfo.flags = m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
3150 			addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3151 			pipelinePartCreateInfo.flags = 0u;
3152 		}
3153 
3154 		m_pipelineParts[3] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
3155 	}
3156 #endif // CTS_USES_VULKANSC
3157 
3158 	return *this;
3159 }
3160 
3161 #ifndef CTS_USES_VULKANSC
getNextStages(vk::VkShaderStageFlagBits shaderStage,bool tessellationShaders,bool geometryShaders,bool link)3162 vk::VkShaderStageFlags GraphicsPipelineWrapper::getNextStages (vk::VkShaderStageFlagBits shaderStage, bool tessellationShaders, bool geometryShaders, bool link)
3163 {
3164 	if (link)
3165 	{
3166 		if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
3167 		{
3168 			if (m_internalData->tessellationControlShader.isSet())
3169 				return vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
3170 			if (m_internalData->geometryShader.isSet())
3171 				return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3172 			if (m_internalData->fragmentShader.isSet())
3173 				return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3174 		}
3175 		if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3176 			return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
3177 		if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3178 		{
3179 			if (m_internalData->geometryShader.isSet())
3180 				return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3181 			if (m_internalData->fragmentShader.isSet())
3182 				return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3183 		}
3184 		if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3185 		{
3186 			if (m_internalData->fragmentShader.isSet())
3187 				return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3188 		}
3189 		if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
3190 		{
3191 			if (m_internalData->meshShader.isSet())
3192 				return vk::VK_SHADER_STAGE_MESH_BIT_EXT;
3193 			if (m_internalData->fragmentShader.isSet())
3194 				return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3195 		}
3196 		if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
3197 		{
3198 			if (m_internalData->fragmentShader.isSet())
3199 				return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3200 		}
3201 	}
3202 	else
3203 	{
3204 		if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
3205 		{
3206 			VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3207 			if (tessellationShaders)
3208 				flags |= vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
3209 			if (geometryShaders)
3210 				flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3211 			return flags;
3212 		}
3213 		else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3214 		{
3215 			return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
3216 		}
3217 		else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3218 		{
3219 			VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3220 			if (geometryShaders)
3221 				flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3222 			return flags;
3223 		}
3224 		else if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3225 		{
3226 			return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3227 		}
3228 		else if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
3229 		{
3230 			return vk::VK_SHADER_STAGE_MESH_BIT_EXT;
3231 		}
3232 		else if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
3233 		{
3234 			return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3235 		}
3236 	}
3237 	return 0;
3238 }
3239 
makeShaderCreateInfo(VkShaderStageFlagBits stage,ShaderWrapper & shader,bool link,bool binary,ShaderWrapper & other)3240 vk::VkShaderCreateInfoEXT GraphicsPipelineWrapper::makeShaderCreateInfo (VkShaderStageFlagBits stage, ShaderWrapper& shader, bool link, bool binary, ShaderWrapper& other)
3241 {
3242 	if (binary)
3243 		shader.getShaderBinary();
3244 
3245 	vk::VkShaderCreateInfoEXT shaderCreateInfo = vk::initVulkanStructure();
3246 	shaderCreateInfo.flags = link ? (vk::VkShaderCreateFlagsEXT)vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT : (vk::VkShaderCreateFlagsEXT)0u;
3247 	shaderCreateInfo.stage = stage;
3248 	shaderCreateInfo.nextStage = getNextStages(stage, m_internalData->tessellationShaderFeature, m_internalData->geometryShaderFeature, link);
3249 	if (binary)
3250 	{
3251 		shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_BINARY_EXT;
3252 		shaderCreateInfo.codeSize = shader.getShaderBinaryDataSize();
3253 		shaderCreateInfo.pCode = shader.getShaderBinaryData();
3254 	}
3255 	else
3256 	{
3257 		shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_SPIRV_EXT;
3258 		shaderCreateInfo.codeSize = shader.getCodeSize();
3259 		shaderCreateInfo.pCode = shader.getBinary();
3260 	}
3261 	shaderCreateInfo.pName = "main";
3262 	if (shader.getPipelineLayout() != DE_NULL)
3263 	{
3264 		shaderCreateInfo.setLayoutCount = shader.getPipelineLayout()->getSetLayoutCount();
3265 		shaderCreateInfo.pSetLayouts = shader.getPipelineLayout()->getSetLayouts();
3266 		shaderCreateInfo.pushConstantRangeCount = shader.getPipelineLayout()->getPushConstantRangeCount();
3267 		shaderCreateInfo.pPushConstantRanges = shader.getPipelineLayout()->getPushConstantRanges();
3268 	}
3269 	// Pipeline layouts and push constant ranges must match between shaders that are used together
3270 	if (other.isSet() && shaderCreateInfo.setLayoutCount == 0)
3271 	{
3272 		shaderCreateInfo.setLayoutCount = other.getPipelineLayout()->getSetLayoutCount();
3273 		shaderCreateInfo.pSetLayouts = other.getPipelineLayout()->getSetLayouts();
3274 	}
3275 	if (other.isSet() && shaderCreateInfo.pushConstantRangeCount == 0)
3276 	{
3277 		shaderCreateInfo.pushConstantRangeCount = other.getPipelineLayout()->getPushConstantRangeCount();
3278 		shaderCreateInfo.pPushConstantRanges = other.getPipelineLayout()->getPushConstantRanges();
3279 	}
3280 	shaderCreateInfo.pSpecializationInfo = shader.getSpecializationInfo();
3281 	return shaderCreateInfo;
3282 }
3283 
createShaders(bool linked,bool binary)3284 void GraphicsPipelineWrapper::createShaders (bool linked, bool binary)
3285 {
3286 	std::vector<vk::VkShaderCreateInfoEXT> createInfos;
3287 	if (m_internalData->vertexShader.isSet())
3288 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, m_internalData->vertexShader, linked, binary, m_internalData->fragmentShader));
3289 	if (m_internalData->tessellationControlShader.isSet())
3290 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_internalData->tessellationControlShader, linked, binary, m_internalData->fragmentShader));
3291 	if (m_internalData->tessellationEvaluationShader.isSet())
3292 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_internalData->tessellationEvaluationShader, linked, binary, m_internalData->fragmentShader));
3293 	if (m_internalData->geometryShader.isSet())
3294 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_internalData->geometryShader, linked, binary, m_internalData->fragmentShader));
3295 	if (m_internalData->fragmentShader.isSet())
3296 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, m_internalData->fragmentShader, linked, binary, m_internalData->vertexShader));
3297 	if (m_internalData->taskShader.isSet())
3298 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TASK_BIT_EXT, m_internalData->taskShader, linked, binary, m_internalData->fragmentShader));
3299 	if (m_internalData->meshShader.isSet())
3300 	{
3301 		createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, m_internalData->meshShader, linked, binary, m_internalData->fragmentShader));
3302 		if (!m_internalData->taskShader.isSet())
3303 			createInfos.back().flags |= vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
3304 	}
3305 
3306 	std::vector<VkShaderEXT> shaders(createInfos.size());
3307 	m_internalData->vk.createShadersEXT(m_internalData->device, (deUint32)createInfos.size(), createInfos.data(), DE_NULL, shaders.data());
3308 	deUint32 shaderIndex = 0;
3309 	if (m_internalData->vertexShader.isSet())
3310 		m_internalData->vertexShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3311 	if (m_internalData->tessellationControlShader.isSet())
3312 		m_internalData->tessellationControlShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3313 	if (m_internalData->tessellationEvaluationShader.isSet())
3314 		m_internalData->tessellationEvaluationShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3315 	if (m_internalData->geometryShader.isSet())
3316 		m_internalData->geometryShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3317 	if (m_internalData->fragmentShader.isSet())
3318 		m_internalData->fragmentShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3319 	if (m_internalData->taskShader.isSet())
3320 		m_internalData->taskShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3321 	if (m_internalData->meshShader.isSet())
3322 		m_internalData->meshShader.setShader(Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]), Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3323 }
3324 #endif
3325 
buildPipeline(const VkPipelineCache pipelineCache,const VkPipeline basePipelineHandle,const deInt32 basePipelineIndex,PipelineCreationFeedbackCreateInfoWrapper creationFeedback,void * pNext)3326 void GraphicsPipelineWrapper::buildPipeline(const VkPipelineCache						pipelineCache,
3327 											const VkPipeline							basePipelineHandle,
3328 											const deInt32								basePipelineIndex,
3329 											PipelineCreationFeedbackCreateInfoWrapper	creationFeedback,
3330 											void*										pNext)
3331 {
3332 	// make sure we are not trying to build pipeline second time
3333 	DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
3334 
3335 	// make sure all states were set
3336 	DE_ASSERT(m_internalData && (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS |
3337 																PSS_FRAGMENT_SHADER | PSS_FRAGMENT_OUTPUT_INTERFACE)));
3338 
3339 	// Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
3340 	DE_UNREF(creationFeedback);
3341 	DE_UNREF(pNext);
3342 
3343 	VkGraphicsPipelineCreateInfo*	pointerToCreateInfo	= &m_internalData->monolithicPipelineCreateInfo;
3344 
3345 	if (isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
3346 	{
3347 #ifndef CTS_USES_VULKANSC
3348 		// Dynamic states that don't require additional extensions
3349 		std::vector<vk::VkDynamicState> dynamicStates = {
3350 			vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
3351 			vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
3352 			vk::VK_DYNAMIC_STATE_LINE_WIDTH,
3353 			vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
3354 			vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS,
3355 			vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
3356 			vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
3357 			vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
3358 			vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
3359 			vk::VK_DYNAMIC_STATE_CULL_MODE_EXT,
3360 			vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
3361 			vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
3362 			vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
3363 			vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
3364 			vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT,
3365 			vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
3366 			vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT,
3367 			vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
3368 			vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
3369 			vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
3370 			vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
3371 			vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
3372 			vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT,
3373 			vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
3374 			vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
3375 			vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
3376 			vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
3377 			vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
3378 			vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
3379 			vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
3380 			vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
3381 			vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
3382 			vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
3383 			vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
3384 			vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
3385 			vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
3386 		};
3387 
3388 		vk::VkPhysicalDeviceMeshShaderFeaturesEXT				meshShaderFeatures	= initVulkanStructure();
3389 		vk::VkPhysicalDeviceFeatures2							features			= initVulkanStructure(&meshShaderFeatures);
3390 		m_internalData->vki.getPhysicalDeviceFeatures2(m_internalData->physicalDevice, &features);
3391 
3392 		m_internalData->tessellationShaderFeature = features.features.tessellationShader;
3393 		m_internalData->geometryShaderFeature = features.features.geometryShader;
3394 		m_internalData->taskShaderFeature = meshShaderFeatures.taskShader;
3395 		m_internalData->meshShaderFeature = meshShaderFeatures.meshShader;
3396 
3397 		DE_ASSERT(m_internalData->extensionEnabled("VK_EXT_shader_object"));
3398 
3399 		// Add dynamic states that are required for each enabled extension
3400 		if (m_internalData->extensionEnabled("VK_EXT_transform_feedback"))
3401 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
3402 		if (m_internalData->extensionEnabled("VK_EXT_blend_operation_advanced"))
3403 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
3404 		if (m_internalData->extensionEnabled("VK_EXT_conservative_rasterization"))
3405 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
3406 		if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3407 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
3408 		if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3409 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
3410 		if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3411 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
3412 		if (m_internalData->extensionEnabled("VK_NV_coverage_reduction_mode"))
3413 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
3414 		if (m_internalData->extensionEnabled("VK_NV_fragment_coverage_to_color"))
3415 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
3416 		if (m_internalData->extensionEnabled("VK_NV_fragment_coverage_to_color"))
3417 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
3418 		if (m_internalData->extensionEnabled("VK_EXT_depth_clip_enable"))
3419 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
3420 		if (m_internalData->extensionEnabled("VK_EXT_depth_clip_control"))
3421 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
3422 		if (m_internalData->extensionEnabled("VK_EXT_color_write_enable"))
3423 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
3424 		if (m_internalData->extensionEnabled("VK_EXT_conservative_rasterization"))
3425 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
3426 		if (m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3427 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
3428 		if (m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3429 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
3430 		if (m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3431 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
3432 		if (m_internalData->extensionEnabled("VK_EXT_provoking_vertex"))
3433 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
3434 		if (m_internalData->extensionEnabled("VK_KHR_fragment_shading_rate"))
3435 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
3436 		if (m_internalData->extensionEnabled("VK_NV_representative_fragment_test"))
3437 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
3438 		if (m_internalData->extensionEnabled("VK_EXT_sample_locations"))
3439 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
3440 		if (m_internalData->extensionEnabled("VK_EXT_sample_locations"))
3441 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
3442 		// Not working with VK_KHR_fragment_shading_rate
3443 		/*if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3444 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
3445 		if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3446 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
3447 		if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3448 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);*/
3449 		if (m_internalData->extensionEnabled("VK_NV_viewport_swizzle"))
3450 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
3451 		if (m_internalData->extensionEnabled("VK_NV_clip_space_w_scaling"))
3452 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
3453 		if (m_internalData->extensionEnabled("VK_NV_clip_space_w_scaling"))
3454 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
3455 		if (m_internalData->extensionEnabled("VK_NV_scissor_exclusive"))
3456 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV);
3457 		if (m_internalData->extensionEnabled("VK_NV_scissor_exclusive"))
3458 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
3459 		if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3460 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
3461 		if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3462 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
3463 		if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3464 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
3465 		if (m_internalData->extensionEnabled("VK_EXT_attachment_feedback_loop_dynamic_state"))
3466 			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT);
3467 
3468 
3469 		// Remove dynamic states that were already set as dynamic for the pipeline
3470 		// These dynamic state will already be set in the tests
3471 		bool depthClampEnableDynamic = false;
3472 		if (pointerToCreateInfo->pDynamicState)
3473 		{
3474 			for (deUint32 i = 0; i < pointerToCreateInfo->pDynamicState->dynamicStateCount; ++i)
3475 			{
3476 				if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_VIEWPORT)
3477 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT), dynamicStates.end());
3478 				else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_SCISSOR)
3479 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT), dynamicStates.end());
3480 				else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT)
3481 				{
3482 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT), dynamicStates.end());
3483 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT), dynamicStates.end());
3484 				}
3485 				else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
3486 				{
3487 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT), dynamicStates.end());
3488 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT), dynamicStates.end());
3489 				}
3490 				else
3491 					dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(), pointerToCreateInfo->pDynamicState->pDynamicStates[i]), dynamicStates.end());
3492 
3493 				if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT)
3494 					depthClampEnableDynamic = true;
3495 			}
3496 		}
3497 
3498 		m_internalData->shaderObjectDynamicStates = dynamicStates;
3499 
3500 		// Save state needed for setting shader object dynamic state
3501 		auto state = &m_internalData->pipelineCreateState;
3502 		if (pointerToCreateInfo->pViewportState)
3503 		{
3504 			if (pointerToCreateInfo->pViewportState->pViewports)
3505 			{
3506 				state->viewports.resize(pointerToCreateInfo->pViewportState->viewportCount);
3507 				for (deUint32 i = 0; i < pointerToCreateInfo->pViewportState->viewportCount; ++i)
3508 					state->viewports[i] = pointerToCreateInfo->pViewportState->pViewports[i];
3509 			}
3510 
3511 			if (pointerToCreateInfo->pViewportState->pScissors)
3512 			{
3513 				state->scissors.resize(pointerToCreateInfo->pViewportState->scissorCount);
3514 				for (deUint32 i = 0; i < pointerToCreateInfo->pViewportState->scissorCount; ++i)
3515 					state->scissors[i] = pointerToCreateInfo->pViewportState->pScissors[i];
3516 			}
3517 
3518 			const auto depthClipControl = findStructure<VkPipelineViewportDepthClipControlCreateInfoEXT>(pointerToCreateInfo->pViewportState->pNext);
3519 			if (depthClipControl)
3520 				state->negativeOneToOne = depthClipControl->negativeOneToOne;
3521 			const auto viewportShadingRate = findStructure<VkPipelineViewportShadingRateImageStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3522 			if (viewportShadingRate)
3523 			{
3524 				state->shadingRateImageEnable = viewportShadingRate->shadingRateImageEnable;
3525 				state->shadingRatePaletteCount = viewportShadingRate->viewportCount;
3526 				state->shadingRatePalettes.resize(viewportShadingRate->viewportCount);
3527 				state->shadingRatePaletteEntries.resize(viewportShadingRate->viewportCount);
3528 				for (deUint32 i = 0; i < viewportShadingRate->viewportCount; ++i)
3529 				{
3530 					state->shadingRatePalettes[i] = viewportShadingRate->pShadingRatePalettes[i];
3531 					state->shadingRatePaletteEntries[i].resize(viewportShadingRate->pShadingRatePalettes[i].shadingRatePaletteEntryCount);
3532 					for (deUint32 j = 0; j < viewportShadingRate->pShadingRatePalettes[i].shadingRatePaletteEntryCount; ++j)
3533 						state->shadingRatePaletteEntries[i][j] = viewportShadingRate->pShadingRatePalettes[i].pShadingRatePaletteEntries[j];
3534 					state->shadingRatePalettes[i].pShadingRatePaletteEntries = state->shadingRatePaletteEntries[i].data();
3535 				}
3536 			}
3537 			const auto viewportSwizzle = findStructure<VkPipelineViewportSwizzleStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3538 			if (viewportSwizzle)
3539 			{
3540 				state->viewportSwizzles.resize(viewportSwizzle->viewportCount);
3541 				for (deUint32 i = 0; i < viewportSwizzle->viewportCount; ++i)
3542 					state->viewportSwizzles[i] = viewportSwizzle->pViewportSwizzles[i];
3543 			}
3544 			const auto viewportWScaling = findStructure<VkPipelineViewportWScalingStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3545 			if (viewportWScaling)
3546 			{
3547 				state->viewportWScalingEnable = viewportWScaling->viewportWScalingEnable;
3548 				state->viewportWScalingCount = viewportWScaling->viewportCount;
3549 				state->viewportWScalings.resize(viewportWScaling->viewportCount);
3550 				for (deUint32 i = 0; i < viewportWScaling->viewportCount; ++i)
3551 					state->viewportWScalings[i] = viewportWScaling->pViewportWScalings[i];
3552 			}
3553 			const auto coarseSampleOrder = findStructure<VkPipelineViewportCoarseSampleOrderStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3554 			if (coarseSampleOrder)
3555 			{
3556 				state->coarseSampleOrderType = coarseSampleOrder->sampleOrderType;
3557 				state->coarseCustomSampleOrderCount = coarseSampleOrder->customSampleOrderCount;
3558 				state->coarseCustomSampleOrders.resize(coarseSampleOrder->customSampleOrderCount);
3559 				state->coarseSampleLocations.resize(coarseSampleOrder->customSampleOrderCount);
3560 				for (deUint32 i = 0; i < coarseSampleOrder->customSampleOrderCount; ++i)
3561 				{
3562 					state->coarseCustomSampleOrders[i] = coarseSampleOrder->pCustomSampleOrders[i];
3563 					state->coarseSampleLocations[i].resize(coarseSampleOrder->pCustomSampleOrders[i].sampleCount);
3564 					for (deUint32 j = 0; j < coarseSampleOrder->pCustomSampleOrders[i].sampleCount; ++j)
3565 						state->coarseSampleLocations[i][j] = coarseSampleOrder->pCustomSampleOrders[i].pSampleLocations[j];
3566 					state->coarseCustomSampleOrders[i].pSampleLocations = state->coarseSampleLocations[i].data();
3567 				}
3568 			}
3569 		}
3570 
3571 		if (pointerToCreateInfo->pRasterizationState)
3572 		{
3573 			state->lineWidth = pointerToCreateInfo->pRasterizationState->lineWidth;
3574 			state->depthBiasConstantFactor = pointerToCreateInfo->pRasterizationState->depthBiasConstantFactor;
3575 			state->depthBiasClamp = pointerToCreateInfo->pRasterizationState->depthBiasClamp;
3576 			state->depthBiasSlopeFactor = pointerToCreateInfo->pRasterizationState->depthBiasSlopeFactor;
3577 			state->cullMode = pointerToCreateInfo->pRasterizationState->cullMode;
3578 			state->frontFace = pointerToCreateInfo->pRasterizationState->frontFace;
3579 			state->depthBiasEnable = pointerToCreateInfo->pRasterizationState->depthBiasEnable;
3580 			state->rasterizerDiscardEnable = pointerToCreateInfo->pRasterizationState->rasterizerDiscardEnable;
3581 			const auto conservative = findStructure<VkPipelineRasterizationConservativeStateCreateInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3582 			if (conservative)
3583 			{
3584 				state->conservativeRasterizationMode = conservative->conservativeRasterizationMode;
3585 				state->extraPrimitiveOverestimationSize = conservative->extraPrimitiveOverestimationSize;
3586 			}
3587 			state->depthClampEnable = pointerToCreateInfo->pRasterizationState->depthClampEnable;
3588 			const auto depthClip = findStructure<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3589 			if (depthClip)
3590 				state->depthClipEnable = depthClip->depthClipEnable;
3591 			else
3592 				state->depthClipEnable = !pointerToCreateInfo->pRasterizationState->depthClampEnable && !depthClampEnableDynamic;
3593 
3594 			const auto rasterizationLine = findStructure<VkPipelineRasterizationLineStateCreateInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3595 			if (rasterizationLine)
3596 			{
3597 				state->lineRasterizationMode = rasterizationLine->lineRasterizationMode;
3598 				state->stippledLineEnable = rasterizationLine->stippledLineEnable;
3599 				state->lineStippleFactor = rasterizationLine->lineStippleFactor;
3600 				state->lineStipplePattern = rasterizationLine->lineStipplePattern;
3601 			}
3602 			const auto rasterizationStream = findStructure<VkPipelineRasterizationStateStreamCreateInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3603 			if (rasterizationStream)
3604 				state->rasterizationStream = rasterizationStream->rasterizationStream;
3605 			state->polygonMode = pointerToCreateInfo->pRasterizationState->polygonMode;
3606 			const auto provokingVertex = findStructure<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3607 			 if (provokingVertex)
3608 				 state->provokingVertexMode = provokingVertex->provokingVertexMode;
3609 			 const auto depthBiasRepresentationInfo = findStructure<VkDepthBiasRepresentationInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3610 			 if (depthBiasRepresentationInfo)
3611 			 {
3612 				 state->depthBiasRepresentation = depthBiasRepresentationInfo->depthBiasRepresentation;
3613 				 state->depthBiasExact = depthBiasRepresentationInfo->depthBiasExact;
3614 			 }
3615 		}
3616 		if (pointerToCreateInfo->pColorBlendState)
3617 		{
3618 			memcpy(&state->blendConstants, pointerToCreateInfo->pColorBlendState->blendConstants, sizeof(float) * 4);
3619 			state->logicOp = pointerToCreateInfo->pColorBlendState->logicOp;
3620 			const auto blendAdvancedState = findStructure<VkPipelineColorBlendAdvancedStateCreateInfoEXT>(pointerToCreateInfo->pColorBlendState->pNext);
3621 			if (blendAdvancedState)
3622 			{
3623 				state->colorBlendAdvanced.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3624 				for (deUint32 i = 0; i < pointerToCreateInfo->pColorBlendState->attachmentCount; ++i)
3625 				{
3626 					if (pointerToCreateInfo->pColorBlendState->pAttachments)
3627 						state->colorBlendAdvanced[i].advancedBlendOp = pointerToCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp;
3628 					state->colorBlendAdvanced[i].srcPremultiplied = blendAdvancedState->srcPremultiplied;
3629 					state->colorBlendAdvanced[i].dstPremultiplied = blendAdvancedState->dstPremultiplied;
3630 					state->colorBlendAdvanced[i].blendOverlap = blendAdvancedState->blendOverlap;
3631 					state->colorBlendAdvanced[i].clampResults = VK_FALSE;
3632 				}
3633 			}
3634 			state->colorBlendEnables.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3635 			state->blendEquations.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3636 			state->colorWriteMasks.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3637 			for (deUint32 i = 0; i < (deUint32)pointerToCreateInfo->pColorBlendState->attachmentCount; ++i)
3638 			{
3639 				if (pointerToCreateInfo->pColorBlendState->pAttachments)
3640 				{
3641 					state->colorBlendEnables[i] = pointerToCreateInfo->pColorBlendState->pAttachments[i].blendEnable;
3642 					state->blendEquations[i].srcColorBlendFactor = pointerToCreateInfo->pColorBlendState->pAttachments[i].srcColorBlendFactor;
3643 					state->blendEquations[i].dstColorBlendFactor = pointerToCreateInfo->pColorBlendState->pAttachments[i].dstColorBlendFactor;
3644 					state->blendEquations[i].colorBlendOp = pointerToCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp;
3645 					state->blendEquations[i].srcAlphaBlendFactor = pointerToCreateInfo->pColorBlendState->pAttachments[i].srcAlphaBlendFactor;
3646 					state->blendEquations[i].dstAlphaBlendFactor = pointerToCreateInfo->pColorBlendState->pAttachments[i].dstAlphaBlendFactor;
3647 					state->blendEquations[i].alphaBlendOp = pointerToCreateInfo->pColorBlendState->pAttachments[i].alphaBlendOp;
3648 					state->colorWriteMasks[i] = pointerToCreateInfo->pColorBlendState->pAttachments[i].colorWriteMask;
3649 				}
3650 
3651 				// colorBlendOp and alphaBlendOp must not be advanced blend operations and they will be set with colorBlendAdvanced
3652 				if (blendAdvancedState)
3653 				{
3654 					state->blendEquations[i].colorBlendOp = vk::VK_BLEND_OP_ADD;
3655 					state->blendEquations[i].alphaBlendOp = vk::VK_BLEND_OP_ADD;
3656 				}
3657 			}
3658 			state->logicOpEnable = pointerToCreateInfo->pColorBlendState->logicOpEnable;
3659 			const auto colorWrite = findStructure<VkPipelineColorWriteCreateInfoEXT>(pointerToCreateInfo->pColorBlendState->pNext);
3660 			if (colorWrite)
3661 			{
3662 				state->colorWriteEnableAttachmentCount = colorWrite->attachmentCount;
3663 				state->colorWriteEnables.resize(colorWrite->attachmentCount);
3664 				for (deUint32 i = 0; i < colorWrite->attachmentCount; ++i)
3665 					state->colorWriteEnables[i] = colorWrite->pColorWriteEnables[i];
3666 			}
3667 		}
3668 		if (pointerToCreateInfo->pDepthStencilState)
3669 		{
3670 			state->minDepthBounds = pointerToCreateInfo->pDepthStencilState->minDepthBounds;
3671 			state->maxDepthBounds = pointerToCreateInfo->pDepthStencilState->maxDepthBounds;
3672 			state->stencilFront = pointerToCreateInfo->pDepthStencilState->front;
3673 			state->stencilBack = pointerToCreateInfo->pDepthStencilState->back;
3674 			state->depthBoundsTestEnable = pointerToCreateInfo->pDepthStencilState->depthBoundsTestEnable;
3675 			state->depthCompareOp = pointerToCreateInfo->pDepthStencilState->depthCompareOp;
3676 			state->depthTestEnable = pointerToCreateInfo->pDepthStencilState->depthTestEnable;
3677 			state->depthWriteEnable = pointerToCreateInfo->pDepthStencilState->depthWriteEnable;
3678 			state->stencilTestEnable = pointerToCreateInfo->pDepthStencilState->stencilTestEnable;
3679 		}
3680 		if (pointerToCreateInfo->pInputAssemblyState)
3681 		{
3682 			state->topology = pointerToCreateInfo->pInputAssemblyState->topology;
3683 			state->primitiveRestartEnable = pointerToCreateInfo->pInputAssemblyState->primitiveRestartEnable;
3684 		}
3685 		if (pointerToCreateInfo->pVertexInputState)
3686 		{
3687 			state->attributes.resize(pointerToCreateInfo->pVertexInputState->vertexAttributeDescriptionCount);
3688 			state->bindings.resize(pointerToCreateInfo->pVertexInputState->vertexBindingDescriptionCount);
3689 			for (deUint32 i = 0; i < pointerToCreateInfo->pVertexInputState->vertexAttributeDescriptionCount; ++i)
3690 			{
3691 				state->attributes[i] = initVulkanStructure();
3692 				state->attributes[i].location = pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].location;
3693 				state->attributes[i].binding = pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].binding;
3694 				state->attributes[i].format = pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].format;
3695 				state->attributes[i].offset = pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].offset;
3696 			}
3697 
3698 			const auto divisorInfo = findStructure<VkPipelineVertexInputDivisorStateCreateInfoEXT>(pointerToCreateInfo->pVertexInputState->pNext);
3699 
3700 			for (deUint32 i = 0; i < pointerToCreateInfo->pVertexInputState->vertexBindingDescriptionCount; ++i)
3701 			{
3702 				state->bindings[i] = initVulkanStructure();
3703 				state->bindings[i].binding = pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].binding;
3704 				state->bindings[i].stride = pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].stride;
3705 				state->bindings[i].inputRate = pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].inputRate;
3706 				state->bindings[i].divisor = 1;
3707 				if (divisorInfo)
3708 				{
3709 					for (deUint32 j = 0; j < divisorInfo->vertexBindingDivisorCount; ++j)
3710 					{
3711 						if (state->bindings[i].binding == divisorInfo->pVertexBindingDivisors[j].binding)
3712 						{
3713 							state->bindings[i].divisor = divisorInfo->pVertexBindingDivisors[i].divisor;
3714 						}
3715 					}
3716 				}
3717 			}
3718 		}
3719 		if (pointerToCreateInfo->pTessellationState)
3720 		{
3721 			state->patchControlPoints = pointerToCreateInfo->pTessellationState->patchControlPoints;
3722 			const auto tessellationDomainOrigin = findStructure<VkPipelineTessellationDomainOriginStateCreateInfo>(pointerToCreateInfo->pTessellationState->pNext);
3723 			if (tessellationDomainOrigin)
3724 				state->domainOrigin = tessellationDomainOrigin->domainOrigin;
3725 		}
3726 		if (pointerToCreateInfo->pMultisampleState)
3727 		{
3728 			state->alphaToCoverageEnable = pointerToCreateInfo->pMultisampleState->alphaToCoverageEnable;
3729 			state->alphaToOneEnable = pointerToCreateInfo->pMultisampleState->alphaToOneEnable;
3730 			const auto coverageModulation = findStructure<VkPipelineCoverageModulationStateCreateInfoNV>(pointerToCreateInfo->pMultisampleState->pNext);
3731 			if (coverageModulation)
3732 			{
3733 				state->coverageModulationMode = coverageModulation->coverageModulationMode;
3734 				state->coverageModulationTableEnable = coverageModulation->coverageModulationTableEnable;
3735 				state->coverageModulationTable.resize(coverageModulation->coverageModulationTableCount);
3736 				for (deUint32 i = 0; i < (deUint32)coverageModulation->coverageModulationTableCount; ++i)
3737 					state->coverageModulationTable[i] = coverageModulation->pCoverageModulationTable[i];
3738 			}
3739 			const auto coverageReduction = findStructure<VkPipelineCoverageReductionStateCreateInfoNV>(pointerToCreateInfo->pMultisampleState->pNext);
3740 			if (coverageReduction)
3741 				state->coverageReductionMode = coverageReduction->coverageReductionMode;
3742 			const auto coverageToColor = findStructure<VkPipelineCoverageToColorStateCreateInfoNV>(pointerToCreateInfo->pMultisampleState->pNext);
3743 			if (coverageToColor)
3744 			{
3745 				state->coverageToColorEnable = coverageToColor->coverageToColorEnable;
3746 				state->coverageToColorLocation = coverageToColor->coverageToColorLocation;
3747 			}
3748 			state->rasterizationSamples = pointerToCreateInfo->pMultisampleState->rasterizationSamples;
3749 			const auto sampleLocations = findStructure<VkPipelineSampleLocationsStateCreateInfoEXT>(pointerToCreateInfo->pMultisampleState->pNext);
3750 			if (sampleLocations)
3751 			{
3752 				state->sampleLocationsEnable = sampleLocations->sampleLocationsEnable;
3753 				state->sampleLocationsInfo = sampleLocations->sampleLocationsInfo;
3754 				state->pSampleLocations.resize(sampleLocations->sampleLocationsInfo.sampleLocationsCount);
3755 				for (deUint32 i = 0; i < sampleLocations->sampleLocationsInfo.sampleLocationsCount; ++i)
3756 					state->pSampleLocations[i] = sampleLocations->sampleLocationsInfo.pSampleLocations[i];
3757 				state->sampleLocationsInfo.pSampleLocations = state->pSampleLocations.data();
3758 			}
3759 			state->rasterizationSamples = pointerToCreateInfo->pMultisampleState->rasterizationSamples;
3760 			deUint32 count = (pointerToCreateInfo->pMultisampleState->rasterizationSamples > vk::VK_SAMPLE_COUNT_32_BIT) ? 2 : 1;
3761 			state->sampleMasks.resize(count, 0);
3762 			for (deUint32 i = 0; i < count; ++i)
3763 				if (pointerToCreateInfo->pMultisampleState->pSampleMask)
3764 					state->sampleMasks[i] = pointerToCreateInfo->pMultisampleState->pSampleMask[i];
3765 				else
3766 					state->sampleMasks[i] = 0xFF; // If pSampleMask is NULL, it is treated as if the mask has all bits set to 1
3767 		}
3768 		const auto representativeFragment = findStructure<VkPipelineRepresentativeFragmentTestStateCreateInfoNV>(pointerToCreateInfo->pNext);
3769 		if (representativeFragment)
3770 		{
3771 			state->representativeFragmentTestEnable = representativeFragment->representativeFragmentTestEnable;
3772 		}
3773 		const auto fragmentShadingRate = findStructure<VkPipelineFragmentShadingRateStateCreateInfoKHR>(pointerToCreateInfo->pNext);
3774 		if (fragmentShadingRate)
3775 		{
3776 			state->fragmentShadingRateSize = fragmentShadingRate->fragmentSize;
3777 			state->combinerOps[0] = fragmentShadingRate->combinerOps[0];
3778 			state->combinerOps[1] = fragmentShadingRate->combinerOps[1];
3779 		}
3780 		const auto exclusiveScissor = findStructure<VkPipelineViewportExclusiveScissorStateCreateInfoNV>(pointerToCreateInfo->pNext);
3781 		if (exclusiveScissor)
3782 		{
3783 			state->exclusiveScissorCount = exclusiveScissor->exclusiveScissorCount;
3784 			state->exclussiveScissors.resize(exclusiveScissor->exclusiveScissorCount);
3785 			for (deUint32 i = 0; i < exclusiveScissor->exclusiveScissorCount; ++i)
3786 				state->exclussiveScissors[i] = exclusiveScissor->pExclusiveScissors[i];
3787 		}
3788 		const auto discardRectangle = findStructure<VkPipelineDiscardRectangleStateCreateInfoEXT>(pointerToCreateInfo->pNext);
3789 		if (discardRectangle)
3790 		{
3791 			state->discardRectangleEnable = discardRectangle->discardRectangleCount > 0;
3792 			state->discardRectangles.resize(discardRectangle->discardRectangleCount);
3793 			for (deUint32 i = 0; i < discardRectangle->discardRectangleCount; ++i)
3794 				state->discardRectangles[i] = discardRectangle->pDiscardRectangles[i];
3795 			state->discardRectangleMode = discardRectangle->discardRectangleMode;
3796 		}
3797 		if (pointerToCreateInfo->flags & VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
3798 			state->attachmentFeedbackLoopEnable |= VK_IMAGE_ASPECT_COLOR_BIT;
3799 		if (pointerToCreateInfo->flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
3800 			state->attachmentFeedbackLoopEnable |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3801 
3802 		bool linked = m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV ||
3803 					  m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
3804 		bool binary = m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY ||
3805 					  m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
3806 		createShaders(linked, false);
3807 		if (binary)
3808 		{
3809 			createShaders(linked, true);
3810 		}
3811 #endif
3812 	}
3813 	else
3814 	{
3815 #ifndef CTS_USES_VULKANSC
3816 		VkGraphicsPipelineCreateInfo	linkedCreateInfo	= initVulkanStructure();
3817 		std::vector<VkPipeline>			rawPipelines;
3818 		VkPipelineLibraryCreateInfoKHR	linkingInfo
3819 		{
3820 			VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR,		// VkStructureType		sType;
3821 			creationFeedback.ptr,									// const void*			pNext;
3822 			0u,														// deUint32				libraryCount;
3823 			nullptr,												// const VkPipeline*	pLibraries;
3824 		};
3825 
3826 		if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3827 		{
3828 			for (const auto& pipelinePtr : m_pipelineParts)
3829 			{
3830 				const auto& pipeline = pipelinePtr.get();
3831 				if (pipeline != DE_NULL)
3832 					rawPipelines.push_back(pipeline);
3833 			}
3834 
3835 			linkingInfo.libraryCount	= static_cast<uint32_t>(rawPipelines.size());
3836 			linkingInfo.pLibraries		= de::dataOrNull(rawPipelines);
3837 
3838 			linkedCreateInfo.flags		= m_internalData->pipelineFlags;
3839 			linkedCreateInfo.layout		= m_internalData->monolithicPipelineCreateInfo.layout;
3840 			linkedCreateInfo.pNext		= &linkingInfo;
3841 
3842 			pointerToCreateInfo			= &linkedCreateInfo;
3843 
3844 			if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3845 				linkedCreateInfo.flags |= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
3846 
3847 			if (m_internalData->failOnCompileWhenLinking)
3848 				linkedCreateInfo.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
3849 		}
3850 		else
3851 		{
3852 			// note: there might be other structures in the chain already
3853 			void* firstStructInChain = static_cast<void*>(pointerToCreateInfo);
3854 			addToChain(&firstStructInChain, creationFeedback.ptr);
3855 			addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
3856 			addToChain(&firstStructInChain, pNext);
3857 		}
3858 
3859 		VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3860 		if (m_internalData->pipelineFlags2)
3861 		{
3862 			void* firstStructInChain = static_cast<void*>(pointerToCreateInfo);
3863 			pipelineFlags2CreateInfo.flags = m_internalData->pipelineFlags2 | translateCreateFlag(pointerToCreateInfo->flags);
3864 			addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3865 			pointerToCreateInfo->flags = 0u;
3866 		}
3867 #endif // CTS_USES_VULKANSC
3868 
3869 		pointerToCreateInfo->basePipelineHandle	= basePipelineHandle;
3870 		pointerToCreateInfo->basePipelineIndex	= basePipelineIndex;
3871 
3872 		m_pipelineFinal = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, pipelineCache, pointerToCreateInfo);
3873 	}
3874 }
3875 
isShaderObjectDynamic(vk::VkDynamicState dynamicState) const3876 bool GraphicsPipelineWrapper::isShaderObjectDynamic (vk::VkDynamicState dynamicState) const
3877 {
3878 	return std::find(m_internalData->shaderObjectDynamicStates.begin(), m_internalData->shaderObjectDynamicStates.end(), dynamicState) != m_internalData->shaderObjectDynamicStates.end();
3879 }
3880 
setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const3881 void GraphicsPipelineWrapper::setShaderObjectDynamicStates (vk::VkCommandBuffer cmdBuffer) const
3882 {
3883 	DE_UNREF(cmdBuffer);
3884 #ifndef CTS_USES_VULKANSC
3885 	const auto&	vk							= m_internalData->vk;
3886 	const auto	state						= &m_internalData->pipelineCreateState;
3887 
3888 	// Some dynamic state only need to be set when these conditions are met
3889 	const bool	meshOrTask					= m_internalData->meshShader.isSet() || m_internalData->taskShader.isSet();
3890 	const bool	tese						= m_internalData->tessellationEvaluationShader.isSet();
3891 	const bool	topologyPatchList			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY) || state->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
3892 	const bool	rasterizerDiscardDisabled	= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) || !state->rasterizerDiscardEnable;
3893 	const bool	polygonModeLine				= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT) || state->polygonMode == vk::VK_POLYGON_MODE_LINE;
3894 	const bool	topologyLine				= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY) ||
3895 											  state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST || state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ||
3896 											  state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP || state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
3897 	const bool	depthTestEnabled			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE) || state->depthTestEnable;
3898 	const bool	depthBoundsTestEnabled		= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE) || state->depthBoundsTestEnable;
3899 	const bool	depthBiasEnabled			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE) || state->depthBiasEnable;
3900 	const bool	stencilTestEnabled			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE) || state->stencilTestEnable;
3901 	const bool	logicOpEnabled				= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT) || state->logicOpEnable;
3902 	const bool	discardRectangle			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT) || state->discardRectangleEnable;
3903 	const bool	sampleLocationsEnabled		= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT) || state->sampleLocationsEnable;
3904 	const bool	stippledLineEnabled			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT) || state->stippledLineEnable;
3905 	bool		blendFactorConstant			= !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
3906 	for (const auto& blend : state->blendEquations)
3907 	{
3908 		if (blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR || blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
3909 			blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA || blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
3910 			blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR || blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
3911 			blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA || blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
3912 			blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR || blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
3913 			blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA || blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
3914 			blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR || blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
3915 			blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA || blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)
3916 
3917 			blendFactorConstant = true;
3918 	}
3919 
3920 	for (const auto dynamicState : m_internalData->shaderObjectDynamicStates)
3921 	{
3922 		switch (dynamicState)
3923 		{
3924 		case vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT:
3925 			if (!state->viewports.empty())
3926 				vk.cmdSetViewportWithCount(cmdBuffer, (deUint32)state->viewports.size(), state->viewports.data());
3927 			break;
3928 		case vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT:
3929 			if (!state->scissors.empty())
3930 				vk.cmdSetScissorWithCount(cmdBuffer, (deUint32)state->scissors.size(), state->scissors.data());
3931 			break;
3932 		case vk::VK_DYNAMIC_STATE_LINE_WIDTH:
3933 			if (polygonModeLine || topologyLine)
3934 				vk.cmdSetLineWidth(cmdBuffer, state->lineWidth);
3935 			break;
3936 		case vk::VK_DYNAMIC_STATE_DEPTH_BIAS:
3937 			if (rasterizerDiscardDisabled && depthBiasEnabled)
3938 			{
3939 				if (m_internalData->extensionEnabled("VK_EXT_depth_bias_control")) {
3940 					VkDepthBiasRepresentationInfoEXT depthBiasRepresentationInfo = vk::initVulkanStructure();
3941 					depthBiasRepresentationInfo.depthBiasRepresentation = state->depthBiasRepresentation;
3942 					depthBiasRepresentationInfo.depthBiasExact = state->depthBiasExact;
3943 
3944 					vk::VkDepthBiasInfoEXT depthBiasInfo = vk::initVulkanStructure(&depthBiasRepresentationInfo);
3945 					depthBiasInfo.depthBiasConstantFactor = state->depthBiasConstantFactor;
3946 					depthBiasInfo.depthBiasClamp = state->depthBiasClamp;
3947 					depthBiasInfo.depthBiasSlopeFactor = state->depthBiasSlopeFactor;
3948 					vk.cmdSetDepthBias2EXT(cmdBuffer, &depthBiasInfo);
3949 				}
3950 				else
3951 				{
3952 					vk.cmdSetDepthBias(cmdBuffer, state->depthBiasConstantFactor, state->depthBiasClamp, state->depthBiasSlopeFactor);
3953 				}
3954 			}
3955 			break;
3956 		case vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS:
3957 			if (rasterizerDiscardDisabled && blendFactorConstant)
3958 				vk.cmdSetBlendConstants(cmdBuffer, state->blendConstants);
3959 			break;
3960 		case vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS:
3961 			if (rasterizerDiscardDisabled && depthBoundsTestEnabled)
3962 				vk.cmdSetDepthBounds(cmdBuffer, state->minDepthBounds, state->maxDepthBounds);
3963 			break;
3964 		case vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
3965 			{
3966 				vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.compareMask);
3967 				vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.compareMask);
3968 			}
3969 			break;
3970 		case vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
3971 			{
3972 				vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.writeMask);
3973 				vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.writeMask);
3974 			}
3975 			break;
3976 		case vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE:
3977 			{
3978 				vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.reference);
3979 				vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.reference);
3980 			}
3981 			break;
3982 		case vk::VK_DYNAMIC_STATE_CULL_MODE_EXT:
3983 			vk.cmdSetCullMode(cmdBuffer, state->cullMode);
3984 			break;
3985 		case vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT:
3986 			if (rasterizerDiscardDisabled)
3987 				vk.cmdSetDepthBoundsTestEnable(cmdBuffer, state->depthBoundsTestEnable);
3988 			break;
3989 		case vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT:
3990 			if (rasterizerDiscardDisabled && depthTestEnabled)
3991 				vk.cmdSetDepthCompareOp(cmdBuffer, state->depthCompareOp);
3992 			break;
3993 		case vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT:
3994 			if (rasterizerDiscardDisabled)
3995 				vk.cmdSetDepthTestEnable(cmdBuffer, state->depthTestEnable);
3996 			break;
3997 		case vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT:
3998 			if (rasterizerDiscardDisabled)
3999 				vk.cmdSetDepthWriteEnable(cmdBuffer, state->depthWriteEnable);
4000 			break;
4001 		case vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT:
4002 			vk.cmdSetFrontFace(cmdBuffer, state->frontFace);
4003 			break;
4004 		case vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT:
4005 			if (!meshOrTask)
4006 				vk.cmdSetPrimitiveTopology(cmdBuffer, state->topology);
4007 			break;
4008 		case vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT:
4009 			if (rasterizerDiscardDisabled && stencilTestEnabled)
4010 			{
4011 				vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.failOp, state->stencilFront.passOp, state->stencilFront.depthFailOp, state->stencilFront.compareOp);
4012 				vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.failOp, state->stencilBack.passOp, state->stencilBack.depthFailOp, state->stencilBack.compareOp);
4013 			}
4014 			break;
4015 		case vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT:
4016 			if (rasterizerDiscardDisabled)
4017 				vk.cmdSetStencilTestEnable(cmdBuffer, state->stencilTestEnable);
4018 			break;
4019 		case vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT:
4020 			if (!meshOrTask)
4021 				vk.cmdSetVertexInputEXT(cmdBuffer, (deUint32)state->bindings.size(), state->bindings.data(), (deUint32)state->attributes.size(), state->attributes.data());
4022 			break;
4023 		case vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT:
4024 			if (rasterizerDiscardDisabled)
4025 				vk.cmdSetDepthBiasEnable(cmdBuffer, state->depthBiasEnable);
4026 			break;
4027 		case vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT:
4028 			if (rasterizerDiscardDisabled && logicOpEnabled)
4029 				vk.cmdSetLogicOpEXT(cmdBuffer, state->logicOp);
4030 			break;
4031 		case vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT:
4032 			if (topologyPatchList && !meshOrTask && tese)
4033 				vk.cmdSetPatchControlPointsEXT(cmdBuffer, state->patchControlPoints);
4034 			break;
4035 		case vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT:
4036 			if (!meshOrTask)
4037 				vk.cmdSetPrimitiveRestartEnable(cmdBuffer, state->primitiveRestartEnable);
4038 			break;
4039 		case vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT:
4040 			vk.cmdSetRasterizerDiscardEnable(cmdBuffer, state->rasterizerDiscardEnable);
4041 			break;
4042 		case vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT:
4043 			vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, state->alphaToCoverageEnable);
4044 			break;
4045 		case vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT:
4046 			vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, state->alphaToOneEnable);
4047 			break;
4048 		case vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT:
4049 			if (!state->colorBlendAdvanced.empty())
4050 			{
4051 				for (deUint32 i = 0; i < (deUint32)state->colorBlendAdvanced.size(); ++i)
4052 					if (!isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT) || state->colorBlendEnables[i])
4053 						vk.cmdSetColorBlendAdvancedEXT(cmdBuffer, i, 1, &state->colorBlendAdvanced[i]);
4054 			}
4055 			break;
4056 		case vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT:
4057 			if (rasterizerDiscardDisabled)
4058 			{
4059 				if (!state->colorBlendEnables.empty())
4060 				{
4061 					vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0, (deUint32)state->colorBlendEnables.size(), state->colorBlendEnables.data());
4062 				}
4063 				else
4064 				{
4065 					VkBool32 disable = VK_FALSE;
4066 					vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0, 1u, &disable);
4067 				}
4068 			}
4069 			break;
4070 		case vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT:
4071 			if (rasterizerDiscardDisabled)
4072 			{
4073 				if (!state->blendEquations.empty())
4074 				{
4075 					vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0, (deUint32)state->blendEquations.size(), state->blendEquations.data());
4076 				}
4077 				else
4078 				{
4079 					vk::VkColorBlendEquationEXT blendEquation = {
4080 						VK_BLEND_FACTOR_SRC_ALPHA,	// VkBlendFactor	srcColorBlendFactor;
4081 						VK_BLEND_FACTOR_DST_ALPHA,	// VkBlendFactor	dstColorBlendFactor;
4082 						VK_BLEND_OP_ADD,			// VkBlendOp		colorBlendOp;
4083 						VK_BLEND_FACTOR_SRC_ALPHA,	// VkBlendFactor	srcAlphaBlendFactor;
4084 						VK_BLEND_FACTOR_DST_ALPHA,	// VkBlendFactor	dstAlphaBlendFactor;
4085 						VK_BLEND_OP_ADD,			// VkBlendOp		alphaBlendOp;
4086 					};
4087 					vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0, 1u, &blendEquation);
4088 				}
4089 			}
4090 			break;
4091 		case vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT:
4092 			if (rasterizerDiscardDisabled)
4093 			{
4094 				if (!state->colorWriteMasks.empty())
4095 				{
4096 					vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0, (deUint32)state->colorWriteMasks.size(), state->colorWriteMasks.data());
4097 				}
4098 				else
4099 				{
4100 					VkColorComponentFlags colorWriteMask = 0u;
4101 					vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0, 1u, &colorWriteMask);
4102 				}
4103 			}
4104 			break;
4105 		case vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT:
4106 			vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer, state->conservativeRasterizationMode);
4107 			break;
4108 		case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV:
4109 			vk.cmdSetCoverageModulationModeNV(cmdBuffer, state->coverageModulationMode);
4110 			break;
4111 		case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV:
4112 			vk.cmdSetCoverageModulationTableEnableNV(cmdBuffer, state->coverageModulationTableEnable);
4113 			break;
4114 		case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV:
4115 			if (!state->coverageModulationTable.empty())
4116 				vk.cmdSetCoverageModulationTableNV(cmdBuffer, (deUint32)state->coverageModulationTable.size(), state->coverageModulationTable.data());
4117 			break;
4118 		case vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV:
4119 			vk.cmdSetCoverageReductionModeNV(cmdBuffer, state->coverageReductionMode);
4120 			break;
4121 		case vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV:
4122 			vk.cmdSetCoverageToColorEnableNV(cmdBuffer, state->coverageToColorEnable);
4123 			break;
4124 		case vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV:
4125 			vk.cmdSetCoverageToColorLocationNV(cmdBuffer, state->coverageToColorLocation);
4126 			break;
4127 		case vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT:
4128 			if (rasterizerDiscardDisabled)
4129 				vk.cmdSetDepthClampEnableEXT(cmdBuffer, state->depthClampEnable);
4130 			break;
4131 		case vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT:
4132 			vk.cmdSetDepthClipEnableEXT(cmdBuffer, state->depthClipEnable);
4133 			break;
4134 		case vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT:
4135 			vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, state->negativeOneToOne);
4136 			break;
4137 		case vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
4138 			if (state->colorWriteEnableAttachmentCount > 0)
4139 				vk.cmdSetColorWriteEnableEXT(cmdBuffer, state->colorWriteEnableAttachmentCount, state->colorWriteEnables.data());
4140 			else
4141 			{
4142 				std::vector<VkBool32> enable(state->colorBlendEnables.empty() ? 1u : state->colorBlendEnables.size(), VK_TRUE);
4143 				vk.cmdSetColorWriteEnableEXT(cmdBuffer, (deUint32)enable.size(), enable.data());
4144 			}
4145 			break;
4146 		case vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT:
4147 			vk.cmdSetExtraPrimitiveOverestimationSizeEXT(cmdBuffer, state->extraPrimitiveOverestimationSize);
4148 			break;
4149 		case vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT:
4150 			vk.cmdSetLineRasterizationModeEXT(cmdBuffer, state->lineRasterizationMode);
4151 			break;
4152 		case vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT:
4153 			vk.cmdSetLineStippleEnableEXT(cmdBuffer, state->stippledLineEnable);
4154 			break;
4155 		case vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
4156 			if (stippledLineEnabled)
4157 				vk.cmdSetLineStippleEXT(cmdBuffer, state->lineStippleFactor, state->lineStipplePattern);
4158 			break;
4159 		case vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT:
4160 			if (rasterizerDiscardDisabled)
4161 				vk.cmdSetLogicOpEnableEXT(cmdBuffer, state->logicOpEnable);
4162 			break;
4163 		case vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT:
4164 			vk.cmdSetPolygonModeEXT(cmdBuffer, state->polygonMode);
4165 			break;
4166 		case vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT:
4167 			vk.cmdSetProvokingVertexModeEXT(cmdBuffer, state->provokingVertexMode);
4168 			break;
4169 		case vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT:
4170 			vk.cmdSetRasterizationSamplesEXT(cmdBuffer, state->rasterizationSamples);
4171 			break;
4172 		case vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR:
4173 			vk.cmdSetFragmentShadingRateKHR(cmdBuffer, &state->fragmentShadingRateSize, state->combinerOps);
4174 			break;
4175 		case vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT:
4176 			vk.cmdSetRasterizationStreamEXT(cmdBuffer, state->rasterizationStream);
4177 			break;
4178 		case vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV:
4179 			vk.cmdSetRepresentativeFragmentTestEnableNV(cmdBuffer, state->representativeFragmentTestEnable);
4180 			break;
4181 		case vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT:
4182 			vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, state->sampleLocationsEnable);
4183 			break;
4184 		case vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
4185 			if (sampleLocationsEnabled)
4186 				vk.cmdSetSampleLocationsEXT(cmdBuffer, &state->sampleLocationsInfo);
4187 			break;
4188 		case vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT:
4189 			if (!state->sampleMasks.empty())
4190 				vk.cmdSetSampleMaskEXT(cmdBuffer, state->rasterizationSamples, state->sampleMasks.data());
4191 			break;
4192 		case vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV:
4193 			vk.cmdSetShadingRateImageEnableNV(cmdBuffer, state->shadingRateImageEnable);
4194 			break;
4195 		case vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT:
4196 			if (tese)
4197 				vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, state->domainOrigin);
4198 			break;
4199 		case vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV:
4200 			if (!state->viewportSwizzles.empty())
4201 			{
4202 				vk.cmdSetViewportSwizzleNV(cmdBuffer, 0, (deUint32)state->viewportSwizzles.size(), state->viewportSwizzles.data());
4203 			}
4204 			else
4205 			{
4206 				std::vector<vk::VkViewportSwizzleNV> idSwizzles(4u);
4207 				for (auto& swizzle : idSwizzles)
4208 				{
4209 					swizzle = {
4210 						vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV,
4211 						vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
4212 						vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV,
4213 						vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV,
4214 					};
4215 				}
4216 				vk.cmdSetViewportSwizzleNV(cmdBuffer, 0u, (deUint32)idSwizzles.size(), idSwizzles.data());
4217 			}
4218 			break;
4219 		case vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV:
4220 			vk.cmdSetViewportWScalingEnableNV(cmdBuffer, state->viewportWScalingEnable);
4221 			break;
4222 		case vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV:
4223 			if (state->viewportWScalingCount > 0)
4224 				vk.cmdSetViewportWScalingNV(cmdBuffer, 0, state->viewportWScalingCount, state->viewportWScalings.data());
4225 			break;
4226 		case vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
4227 			if (!meshOrTask)
4228 				vk.cmdSetVertexInputEXT(cmdBuffer, (deUint32)state->bindings.size(), state->bindings.data(), (deUint32)state->attributes.size(), state->attributes.data());
4229 			break;
4230 		case vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV:
4231 			vk.cmdSetCoarseSampleOrderNV(cmdBuffer, state->coarseSampleOrderType, state->coarseCustomSampleOrderCount, state->coarseCustomSampleOrders.data());
4232 			break;
4233 		case vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV:
4234 			if (state->shadingRatePaletteCount > 0)
4235 				vk.cmdSetViewportShadingRatePaletteNV(cmdBuffer, 0, state->shadingRatePaletteCount, state->shadingRatePalettes.data());
4236 			break;
4237 		case vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV:
4238 		{
4239 			if (state->exclusiveScissorCount > 0)
4240 			{
4241 				std::vector<VkBool32> exclusiveScissorEnable(state->exclusiveScissorCount, VK_TRUE);
4242 				vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, state->exclusiveScissorCount, exclusiveScissorEnable.data());
4243 			}
4244 			else
4245 			{
4246 				VkBool32 enable = VK_FALSE;
4247 				vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, 1u, &enable);
4248 			}
4249 			break;
4250 		}
4251 		case vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV:
4252 			if (state->exclusiveScissorCount > 0)
4253 				vk.cmdSetExclusiveScissorNV(cmdBuffer, 0u, state->exclusiveScissorCount, state->exclussiveScissors.data());
4254 			break;
4255 		case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT:
4256 			vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, state->discardRectangleEnable);
4257 			break;
4258 		case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT:
4259 			if (discardRectangle)
4260 				vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0, (deUint32)state->discardRectangles.size(), state->discardRectangles.data());
4261 			break;
4262 		case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT:
4263 			if (discardRectangle)
4264 				vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, state->discardRectangleMode);
4265 			break;
4266 		case vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT:
4267 			vk.cmdSetAttachmentFeedbackLoopEnableEXT(cmdBuffer, state->attachmentFeedbackLoopEnable);
4268 			break;
4269 		default:
4270 			break;
4271 		}
4272 	}
4273 #endif // CTS_USES_VULKANSC
4274 }
4275 
bind(vk::VkCommandBuffer cmdBuffer) const4276 void GraphicsPipelineWrapper::bind (vk::VkCommandBuffer cmdBuffer) const
4277 {
4278 	const auto& vk = m_internalData->vk;
4279 	if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
4280 	{
4281 		vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, getPipeline());
4282 	}
4283 	else
4284 	{
4285 #ifndef CTS_USES_VULKANSC
4286 		const VkShaderStageFlagBits vertStage = vk::VK_SHADER_STAGE_VERTEX_BIT;
4287 		VkShaderEXT vertShader = m_internalData->vertexShader.getShader();
4288 		vk.cmdBindShadersEXT(cmdBuffer, 1, &vertStage, &vertShader);
4289 		const VkShaderStageFlagBits tescStage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
4290 		VkShaderEXT tescShader = m_internalData->tessellationControlShader.getShader();
4291 		vk.cmdBindShadersEXT(cmdBuffer, 1, &tescStage, &tescShader);
4292 		const VkShaderStageFlagBits teseStage = vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
4293 		VkShaderEXT teseShader = m_internalData->tessellationEvaluationShader.getShader();
4294 		vk.cmdBindShadersEXT(cmdBuffer, 1, &teseStage, &teseShader);
4295 		const VkShaderStageFlagBits geomStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
4296 		VkShaderEXT geomShader = m_internalData->geometryShader.getShader();
4297 		vk.cmdBindShadersEXT(cmdBuffer, 1, &geomStage, &geomShader);
4298 		const VkShaderStageFlagBits fragStage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
4299 		VkShaderEXT fragShader = m_internalData->fragmentShader.getShader();
4300 		vk.cmdBindShadersEXT(cmdBuffer, 1, &fragStage, &fragShader);
4301 		if (m_internalData->meshShaderFeature)
4302 		{
4303 			const VkShaderStageFlagBits meshStage = vk::VK_SHADER_STAGE_MESH_BIT_EXT;
4304 			VkShaderEXT meshShader = m_internalData->meshShader.getShader();
4305 			vk.cmdBindShadersEXT(cmdBuffer, 1, &meshStage, &meshShader);
4306 		}
4307 		if (m_internalData->taskShaderFeature)
4308 		{
4309 			const VkShaderStageFlagBits taskStage = vk::VK_SHADER_STAGE_TASK_BIT_EXT;
4310 			VkShaderEXT taskShader = m_internalData->taskShader.getShader();
4311 			vk.cmdBindShadersEXT(cmdBuffer, 1, &taskStage, &taskShader);
4312 		}
4313 		// Set all dynamic state that would otherwise have been set with the pipeline
4314 		setShaderObjectDynamicStates(cmdBuffer);
4315 #endif
4316 	}
4317 }
4318 
wasBuild() const4319 deBool GraphicsPipelineWrapper::wasBuild() const
4320 {
4321 	return !!m_pipelineFinal.get();
4322 }
4323 
wasPipelineOrShaderObjectBuild(void) const4324 deBool GraphicsPipelineWrapper::wasPipelineOrShaderObjectBuild (void) const
4325 {
4326 	if (!!m_pipelineFinal.get())
4327 		return true;
4328 
4329 #ifndef CTS_USES_VULKANSC
4330 	if (!!m_internalData->vertexShader.getShader() ||
4331 		!!m_internalData->tessellationControlShader.getShader() ||
4332 		!!m_internalData->tessellationEvaluationShader.getShader() ||
4333 		!!m_internalData->geometryShader.getShader() ||
4334 		!!m_internalData->fragmentShader.getShader() ||
4335 		!!m_internalData->taskShader.getShader() ||
4336 		!!m_internalData->meshShader.getShader())
4337 		return true;
4338 #endif
4339 
4340 	return false;
4341 }
4342 
getPipeline(void) const4343 VkPipeline GraphicsPipelineWrapper::getPipeline (void) const
4344 {
4345 	DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
4346 	return m_pipelineFinal.get();
4347 }
4348 
destroyPipeline(void)4349 void GraphicsPipelineWrapper::destroyPipeline (void)
4350 {
4351 	DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
4352 
4353 	m_pipelineFinal = Move<VkPipeline>();
4354 }
4355 
4356 } // vk
4357