• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKPIPELINECONSTRUCTIONUTIL_HPP
2 #define _VKPIPELINECONSTRUCTIONUTIL_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2021 The Khronos Group Inc.
8  * Copyright (c) 2023 LunarG, Inc.
9  * Copyright (c) 2023 Nintendo
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  *//*!
24  * \file
25  * \brief Wrapper that can construct monolithic pipeline or use
26           VK_EXT_graphics_pipeline_library for pipeline construction or use
27 		  VK_EXT_shader_object for shader objects.
28  *//*--------------------------------------------------------------------*/
29 
30 #include "vkRef.hpp"
31 #include "vkDefs.hpp"
32 #include "tcuDefs.hpp"
33 #include "deSharedPtr.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkShaderObjectUtil.hpp"
36 #include <vector>
37 #include <stdexcept>
38 
39 namespace vk
40 {
41 
42 enum PipelineConstructionType
43 {
44 	PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC			= 0,		// Construct legacy - monolithic pipeline
45 	PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY,		// Use VK_EXT_graphics_pipeline_library and construct pipeline out of several pipeline parts.
46 	PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY,				// Same as PIPELINE_CONSTRUCTION_TYPE_OPTIMISED_LIBRARY but with fast linking
47 	PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_SPIRV,	// Use VK_EXT_shader_object unlinked shader objects from spirv
48 	PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY,	// Use VK_EXT_shader_object unlinked shader objects from binary
49 	PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV,		// Use VK_EXT_shader_object linked shader objects from spirv
50 	PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY,		// Use VK_EXT_shader_object linked shader objects from binary
51 };
52 
53 bool isConstructionTypeLibrary (PipelineConstructionType pipelineConstructionType);
54 bool isConstructionTypeShaderObject (PipelineConstructionType pipelineConstructionType);
55 void checkPipelineConstructionRequirements (const InstanceInterface&		vki,
56 											VkPhysicalDevice				physicalDevice,
57 											PipelineConstructionType		pipelineConstructionType);
58 
59 // This exception may be raised in one of the intermediate steps when using shader module IDs instead of normal module objects.
60 class PipelineCompileRequiredError : public std::runtime_error
61 {
62 public:
PipelineCompileRequiredError(const std::string & msg)63 	PipelineCompileRequiredError (const std::string& msg)
64 		: std::runtime_error(msg)
65 		{}
66 };
67 
68 // PointerWrapper template is used to hide structures that should not be visible for Vulkan SC
69 template <typename T>
70 class PointerWrapper
71 {
72 public:
PointerWrapper()73 	PointerWrapper(): ptr(DE_NULL)	{}
PointerWrapper(T * p0)74 	PointerWrapper(T* p0) : ptr(p0) {}
75 	T* ptr;
76 };
77 
78 template <typename T>
79 class ConstPointerWrapper
80 {
81 public:
ConstPointerWrapper()82 	ConstPointerWrapper(): ptr(DE_NULL)  {}
ConstPointerWrapper(const T * p0)83 	ConstPointerWrapper(const T* p0) : ptr(p0) {}
84 	const T* ptr;
85 };
86 
87 #ifndef CTS_USES_VULKANSC
88 typedef PointerWrapper<VkPipelineViewportDepthClipControlCreateInfoEXT> PipelineViewportDepthClipControlCreateInfoWrapper;
89 typedef PointerWrapper<VkPipelineRenderingCreateInfoKHR> PipelineRenderingCreateInfoWrapper;
90 typedef PointerWrapper<VkPipelineCreationFeedbackCreateInfoEXT> PipelineCreationFeedbackCreateInfoWrapper;
91 typedef ConstPointerWrapper<VkPipelineShaderStageModuleIdentifierCreateInfoEXT> PipelineShaderStageModuleIdentifierCreateInfoWrapper;
92 typedef PointerWrapper<VkPipelineRepresentativeFragmentTestStateCreateInfoNV> PipelineRepresentativeFragmentTestCreateInfoWrapper;
93 typedef VkPipelineCreateFlags2KHR PipelineCreateFlags2;
94 #else
95 typedef PointerWrapper<void> PipelineViewportDepthClipControlCreateInfoWrapper;
96 typedef PointerWrapper<void> PipelineRenderingCreateInfoWrapper;
97 typedef PointerWrapper<void> PipelineCreationFeedbackCreateInfoWrapper;
98 typedef ConstPointerWrapper<void> PipelineShaderStageModuleIdentifierCreateInfoWrapper;
99 typedef PointerWrapper<void> PipelineRepresentativeFragmentTestCreateInfoWrapper;
100 typedef uint64_t PipelineCreateFlags2;
101 #endif
102 
103 PipelineCreateFlags2 translateCreateFlag(VkPipelineCreateFlags flagToTranslate);
104 
105 class PipelineLayoutWrapper
106 {
107 public:
108 									PipelineLayoutWrapper			() = default;
109 									PipelineLayoutWrapper			(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkDescriptorSetLayout descriptorSetLayout = DE_NULL, const VkPushConstantRange* pushConstantRange = DE_NULL);
110 									PipelineLayoutWrapper			(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const std::vector<vk::Move<VkDescriptorSetLayout>>& descriptorSetLayout);
111 									PipelineLayoutWrapper			(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, deUint32 setLayoutCount, const VkDescriptorSetLayout* descriptorSetLayout);
112 									PipelineLayoutWrapper			(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* = DE_NULL);
113 									PipelineLayoutWrapper			(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, const VkDevice device, const deUint32 setLayoutCount, const VkDescriptorSetLayout* descriptorSetLayout, const deUint32 pushConstantRangeCount, const VkPushConstantRange* pPushConstantRanges, const VkPipelineLayoutCreateFlags flags = (VkPipelineLayoutCreateFlags)0u);
114 									PipelineLayoutWrapper			(const PipelineLayoutWrapper& rhs) = delete;
115 									~PipelineLayoutWrapper			() = default;
116 
operator *(void) const117 	const VkPipelineLayout			operator*						(void) const { return *m_pipelineLayout; }
get(void) const118 	const VkPipelineLayout			get								(void) const { return *m_pipelineLayout; }
119 	PipelineLayoutWrapper&			operator=						(PipelineLayoutWrapper&& rhs);
destroy(void)120 	void							destroy							(void) { m_pipelineLayout = vk::Move<VkPipelineLayout>{}; }
121 
getSetLayoutCount(void) const122 	deUint32						getSetLayoutCount				(void) const { return m_setLayoutCount; }
getSetLayouts(void) const123 	const VkDescriptorSetLayout*	getSetLayouts					(void) const { return m_setLayouts.data(); }
getSetLayout(deUint32 i)124 	VkDescriptorSetLayout*			getSetLayout					(deUint32 i) { return &m_setLayouts[i]; }
getPushConstantRangeCount(void) const125 	deUint32						getPushConstantRangeCount		(void) const { return m_pushConstantRangeCount; }
getPushConstantRanges(void) const126 	const VkPushConstantRange*		getPushConstantRanges			(void) const { return m_pushConstantRanges.data(); }
127 
128 	void							bindDescriptorSets				(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) const;
129 private:
130 	PipelineConstructionType			m_pipelineConstructionType;
131 	const DeviceInterface*				m_vk;
132 	VkDevice							m_device;
133 	VkPipelineLayoutCreateFlags			m_flags;
134 	deUint32							m_setLayoutCount;
135 	std::vector<VkDescriptorSetLayout>	m_setLayouts;
136 	deUint32							m_pushConstantRangeCount;
137 	std::vector<VkPushConstantRange>	m_pushConstantRanges;
138 	vk::Move<VkPipelineLayout>			m_pipelineLayout;
139 };
140 
141 class RenderPassWrapper
142 {
143 public:
144 									RenderPassWrapper				() = default;
145 									RenderPassWrapper				(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo* pCreateInfo);
146 									RenderPassWrapper				(PipelineConstructionType pipelineConstructionType, const DeviceInterface& vk, VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo);
147 									RenderPassWrapper				(PipelineConstructionType			pipelineConstructionType,
148 																	 const DeviceInterface&				vk,
149 																	 const VkDevice						device,
150 																	 const VkFormat						colorFormat					= VK_FORMAT_UNDEFINED,
151 																	 const VkFormat						depthStencilFormat			= VK_FORMAT_UNDEFINED,
152 																	 const VkAttachmentLoadOp			loadOperation				= VK_ATTACHMENT_LOAD_OP_CLEAR,
153 																	 const VkImageLayout				finalLayoutColor			= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
154 																	 const VkImageLayout				finalLayoutDepthStencil		= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
155 																	 const VkImageLayout				subpassLayoutColor			= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
156 																	 const VkImageLayout				subpassLayoutDepthStencil	= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
157 																	 const VkAllocationCallbacks* const	allocationCallbacks			= DE_NULL);
158 
159 									RenderPassWrapper				(RenderPassWrapper&& rhs) noexcept;
160 	RenderPassWrapper&				operator=						(RenderPassWrapper&& rhs) noexcept;
161 
162 									~RenderPassWrapper				() = default;
163 
operator *(void) const164 	const VkRenderPass				operator*						(void) const { return *m_renderPass; }
get(void) const165 	const VkRenderPass				get								(void) const { return *m_renderPass; }
getFramebuffer(void) const166 	const VkFramebuffer				getFramebuffer					(void) const { return m_framebuffer ? *m_framebuffer : VK_NULL_HANDLE; }
167 
168 	void							begin							(const DeviceInterface&		vk,
169 																	 const VkCommandBuffer		commandBuffer,
170 																	 const VkRect2D&			renderArea,
171 																	 const deUint32				clearValueCount,
172 																	 const VkClearValue*		clearValues,
173 																	 const VkSubpassContents	contents		= VK_SUBPASS_CONTENTS_INLINE,
174 																	 const void*				pNext			= DE_NULL) const;
175 	void							begin							(const DeviceInterface&		vk,
176 																	 const VkCommandBuffer		commandBuffer,
177 																	 const VkRect2D&			renderArea,
178 																	 const VkClearValue&		clearValue,
179 																	 const VkSubpassContents	contents = VK_SUBPASS_CONTENTS_INLINE) const;
180 	void							begin							(const DeviceInterface&		vk,
181 																	 const VkCommandBuffer		commandBuffer,
182 																	 const VkRect2D&			renderArea,
183 																	 const tcu::Vec4&			clearColor,
184 																	 const VkSubpassContents	contents = VK_SUBPASS_CONTENTS_INLINE) const;
185 	void							begin							(const DeviceInterface&		vk,
186 																	 const VkCommandBuffer		commandBuffer,
187 																	 const VkRect2D&			renderArea,
188 																	 const tcu::Vec4&			clearColor,
189 																	 const float				clearDepth,
190 																	 const deUint32				clearStencil,
191 																	 const VkSubpassContents	contents = VK_SUBPASS_CONTENTS_INLINE) const;
192 	void							begin							(const DeviceInterface&		vk,
193 																	 const VkCommandBuffer		commandBuffer,
194 																	 const VkRect2D&			renderArea,
195 																	 const VkSubpassContents	contents = VK_SUBPASS_CONTENTS_INLINE) const;
196 	void							begin							(const DeviceInterface&		vk,
197 																	 const VkCommandBuffer		commandBuffer,
198 																	 const VkRect2D&			renderArea,
199 																	 const tcu::UVec4&			clearColor,
200 																	 const VkSubpassContents	contents = VK_SUBPASS_CONTENTS_INLINE) const;
201 
202 	void							end								(const DeviceInterface& vk, const VkCommandBuffer commandBuffer) const;
203 	void							nextSubpass						(const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const VkSubpassContents contents) const;
204 
205 	void							createFramebuffer				(const DeviceInterface& vk, const VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const std::vector<vk::VkImage>& images);
206 	void							createFramebuffer				(const DeviceInterface& vk, const VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, vk::VkImage colorImage, vk::VkImage depthStencilImage = VK_NULL_HANDLE);
207 	void							createFramebuffer				(const DeviceInterface& vk, const VkDevice device, const VkImage colorImage, const VkImageView colorAttachment, const deUint32 width, const deUint32 height, const deUint32 layers = 1u);
208 	void							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 = 1u);
209 
210 private:
211 	void							beginRendering					(const DeviceInterface& vk, const VkCommandBuffer commandBuffer) const;
212 
213 	PipelineConstructionType			m_pipelineConstructionType;
214 	vk::Move<vk::VkRenderPass>			m_renderPass;
215 	vk::Move<vk::VkFramebuffer>			m_framebuffer;
216 
217 #ifndef CTS_USES_VULKANSC
218 	struct Subpass {
219 		struct Attachment {
220 			deUint32							index = VK_ATTACHMENT_UNUSED;
221 			vk::VkRenderingAttachmentInfo		attachmentInfo = {};
222 			vk::VkFormat						format;
223 			vk::VkAttachmentLoadOp				stencilLoadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
224 			vk::VkAttachmentStoreOp				stencilStoreOp = vk::VK_ATTACHMENT_STORE_OP_STORE;
225 		};
226 		mutable std::vector<Attachment>		m_colorAttachments;
227 		mutable Attachment					m_depthStencilAttachment;
228 		mutable std::vector<Attachment>		m_resolveAttachments;
229 		mutable VkMultisampledRenderToSingleSampledInfoEXT m_msrtss = {};
230 		mutable VkSubpassDescriptionDepthStencilResolve m_dsr = {};
231 		mutable VkAttachmentReference2		m_depthStencilResolveAttachment = {};
232 	};
233 	struct SubpassDependency
234 	{
235 		SubpassDependency (const VkSubpassDependency& dependency);
236 		SubpassDependency (const VkSubpassDependency2& dependency);
237 
238 		uint32_t				srcSubpass;
239 		uint32_t				dstSubpass;
240 		VkPipelineStageFlags2	srcStageMask;
241 		VkPipelineStageFlags2	dstStageMask;
242 		VkAccessFlags2			srcAccessMask;
243 		VkAccessFlags2			dstAccessMask;
244 		VkDependencyFlags		dependencyFlags;
245 		bool					sync2;
246 	};
247 	std::vector<Subpass>					m_subpasses;
248 	std::vector<SubpassDependency>			m_dependencies;
249 	std::vector<vk::VkAttachmentDescription2> m_attachments;
250 	std::vector<vk::VkImage>				m_images;
251 	std::vector<vk::VkImageView>			m_imageViews;
252 	mutable std::vector<vk::VkClearValue>	m_clearValues;
253 	mutable std::vector<vk::VkImageLayout>	m_layouts;
254 	mutable uint32_t						m_activeSubpass = 0;
255 	mutable vk::VkRenderingInfo				m_renderingInfo;
256 	deUint32								m_layers = 1;
257 	std::vector<deUint32>					m_viewMasks;
258 	mutable bool							m_secondaryCommandBuffers;
259 
260 	void									clearAttachments				(const DeviceInterface& vk, const VkCommandBuffer commandBuffer) const;
261 	void									updateLayout					(VkImage updatedImage, VkImageLayout newLayout) const;
262 	void									transitionLayouts				(const DeviceInterface& vk, const VkCommandBuffer commandBuffer, const Subpass& subpass, bool renderPassBegin) const;
263 	void									insertDependencies				(const DeviceInterface& vk, const VkCommandBuffer commandBuffer, uint32_t subpassIdx) const;
264 
265 public:
266 	void									fillInheritanceRenderingInfo	(deUint32 subpassIndex, std::vector<vk::VkFormat>* colorFormats, vk::VkCommandBufferInheritanceRenderingInfo* inheritanceRenderingInfo) const;
267 private:
268 #endif
269 
270 };
271 
272 class ShaderWrapper
273 {
274 public:
275 									ShaderWrapper					();
276 
277 									ShaderWrapper					(const DeviceInterface&					vk,
278 																	 VkDevice								device,
279 																	 const vk::ProgramBinary&				binary,
280 																	 const vk::VkShaderModuleCreateFlags	createFlags = 0u);
281 
282 									ShaderWrapper					(const ShaderWrapper& rhs) noexcept;
283 
284 									~ShaderWrapper					() = default;
285 
286 	ShaderWrapper&					operator=						(const ShaderWrapper& rhs) noexcept;
287 
isSet(void) const288 	bool							isSet							(void) const { return m_binary != DE_NULL; }
289 
290 	vk::VkShaderModule				getModule						(void) const;
291 
292 	size_t							getCodeSize						(void) const;
293 	void*							getBinary						(void) const;
294 
295 	void							createModule					(void);
296 	void							setLayoutAndSpecialization		(const PipelineLayoutWrapper* layout, const VkSpecializationInfo* specializationInfo);
297 
getPipelineLayout(void) const298 	const PipelineLayoutWrapper*	getPipelineLayout				(void) const { return m_layout; }
getSpecializationInfo(void) const299 	const VkSpecializationInfo*		getSpecializationInfo			(void) const { return m_specializationInfo; }
300 
301 #ifndef CTS_USES_VULKANSC
getShader(void) const302 	vk::VkShaderEXT					getShader						(void) const { return m_shader ? *m_shader : VK_NULL_HANDLE; }
setShader(Move<VkShaderEXT> shader)303 	void							setShader						(Move<VkShaderEXT> shader) { m_shader = shader; }
304 
addFlags(const VkShaderCreateFlagsEXT flags)305 	void							addFlags						(const VkShaderCreateFlagsEXT flags)
306 																	{
307 																		m_shaderCreateFlags |= flags;
308 																	}
309 	void							getShaderBinary					(void);
getShaderBinaryDataSize(void)310 	size_t							getShaderBinaryDataSize			(void) { return m_binaryDataSize; }
getShaderBinaryData(void)311 	void*							getShaderBinaryData				(void) { return m_binaryData.data(); }
312 #endif
313 
314 private:
315 	const DeviceInterface*					m_vk;
316 	VkDevice								m_device;
317 	const vk::ProgramBinary*				m_binary;
318 	vk::VkShaderModuleCreateFlags			m_moduleCreateFlags;
319 	mutable vk::Move<vk::VkShaderModule>	m_module;
320 	const PipelineLayoutWrapper*			m_layout;
321 	const VkSpecializationInfo*				m_specializationInfo;
322 #ifndef CTS_USES_VULKANSC
323 	vk::Move<vk::VkShaderEXT>				m_shader;
324 	VkShaderCreateFlagsEXT					m_shaderCreateFlags;
325 	size_t									m_binaryDataSize;
326 	std::vector<deUint8>					m_binaryData;
327 #endif
328 };
329 
330 // Class that can build monolithic pipeline or fully separated pipeline libraries
331 // depending on PipelineType specified in the constructor.
332 // Rarely needed configuration was extracted to setDefault*/disable* functions while common
333 // state setup is provided as arguments of four setup* functions - one for each state group.
334 class GraphicsPipelineWrapper
335 {
336 public:
337 								GraphicsPipelineWrapper				(const InstanceInterface&			vki,
338 																	 const DeviceInterface&				vk,
339 																	 VkPhysicalDevice					physicalDevice,
340 																	 VkDevice							device,
341 																	 const std::vector<std::string>&	deviceExtensions,
342 																	 const PipelineConstructionType		pipelineConstructionType,
343 																	 const VkPipelineCreateFlags		flags = 0u);
344 
345 								GraphicsPipelineWrapper				(GraphicsPipelineWrapper&&) noexcept;
346 
347 								~GraphicsPipelineWrapper			(void) = default;
348 
349 
350 	// By default pipelineLayout used for monotlithic pipeline is taken from layout specified
351 	// in setupPreRasterizationShaderState but when there are also descriptor sets needed for fragment
352 	// shader bindings then separate pipeline layout for monolithic pipeline must be provided
353 	GraphicsPipelineWrapper&	setMonolithicPipelineLayout			(const PipelineLayoutWrapper& layout);
354 
355 
356 	// By default dynamic state has to be specified before specifying other CreateInfo structures
357 	GraphicsPipelineWrapper&	setDynamicState						(const VkPipelineDynamicStateCreateInfo* dynamicState);
358 
359 	// Specify the representative fragment test state.
360 	GraphicsPipelineWrapper&	setRepresentativeFragmentTestState	(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState);
361 
362 	// Specifying how a pipeline is created using VkPipelineCreateFlags2CreateInfoKHR.
363 	GraphicsPipelineWrapper&	setPipelineCreateFlags2				(PipelineCreateFlags2 pipelineFlags2);
364 
365 
366 	// Specify topology that is used by default InputAssemblyState in vertex input state. This needs to be
367 	// specified only when there is no custom InputAssemblyState provided in setupVertexInputState and when
368 	// topology is diferent then VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST which is used by default.
369 	GraphicsPipelineWrapper&	setDefaultTopology					(const VkPrimitiveTopology topology);
370 
371 	// Specify patch control points that is used by default TessellationState in pre-rasterization shader state.
372 	// This can to be specified only when there is no custom TessellationState provided in
373 	// setupPreRasterizationShaderState and when patchControlPoints is diferent then 3 which is used by default.
374 	// A value of std::numeric_limits<uint32_t>::max() forces the tessellation state to be null.
375 	GraphicsPipelineWrapper&	setDefaultPatchControlPoints		(const deUint32 patchControlPoints);
376 
377 	// Specify tesellation domain origin, used by the tessellation state in pre-rasterization shader state.
378 	GraphicsPipelineWrapper&	setDefaultTessellationDomainOrigin	(const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct = false);
379 
380 	// Enable discarding of primitives that is used by default RasterizationState in pre-rasterization shader state.
381 	// This can be specified only when there is no custom RasterizationState provided in setupPreRasterizationShaderState.
382 	GraphicsPipelineWrapper&	setDefaultRasterizerDiscardEnable	(const deBool rasterizerDiscardEnable = DE_TRUE);
383 
384 	// When some states are not provided then default structures can be used. This behaviour can be turned on by one of below methods.
385 	// Some tests require those states to be NULL so we can't assume using default versions.
386 	GraphicsPipelineWrapper&	setDefaultRasterizationState		(void);
387 	GraphicsPipelineWrapper&	setDefaultDepthStencilState			(void);
388 	GraphicsPipelineWrapper&	setDefaultColorBlendState			(void);
389 	GraphicsPipelineWrapper&	setDefaultMultisampleState			(void);
390 	GraphicsPipelineWrapper&	setDefaultVertexInputState			(const deBool useDefaultVertexInputState);
391 
392 	// Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. By default
393 	// number of viewports and scissors is same as number of items in vector but when vectors are empty then by
394 	// default count of viewports/scissors is set to 1. This can be changed by below functions.
395 	GraphicsPipelineWrapper&	setDefaultViewportsCount			(deUint32 viewportCount = 0u);
396 	GraphicsPipelineWrapper&	setDefaultScissorsCount				(deUint32 scissorCount = 0u);
397 
398 	// Pre-rasterization shader state uses default ViewportState, this method extends the internal structure.
399 	GraphicsPipelineWrapper&	setViewportStatePnext				(const void* pNext);
400 
401 #ifndef CTS_USES_VULKANSC
402 	GraphicsPipelineWrapper&	setRenderingColorAttachmentsInfo	(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo);
403 #endif
404 
405 	// Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. When disableViewportState
406 	// is used then ViewportState won't be constructed and NULL will be used.
407 	GraphicsPipelineWrapper&	disableViewportState				(const bool disable = true);
408 
409 
410 	// Setup vertex input state. When VertexInputState or InputAssemblyState are not provided then default structures will be used.
411 	GraphicsPipelineWrapper&	setupVertexInputState				(const VkPipelineVertexInputStateCreateInfo*		vertexInputState = nullptr,
412 																	 const VkPipelineInputAssemblyStateCreateInfo*		inputAssemblyState = nullptr,
413 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
414 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
415 																	 const bool											useNullPtrs = false);
416 
417 	// Setup pre-rasterization shader state.
418 	GraphicsPipelineWrapper&	setupPreRasterizationShaderState	(const std::vector<VkViewport>&						viewports,
419 																	 const std::vector<VkRect2D>&						scissors,
420 																	 const PipelineLayoutWrapper&						layout,
421 																	 const VkRenderPass									renderPass,
422 																	 const deUint32										subpass,
423 																	 const ShaderWrapper								vertexShaderModule,
424 																	 const VkPipelineRasterizationStateCreateInfo*		rasterizationState = DE_NULL,
425 																	 const ShaderWrapper								tessellationControlShader = ShaderWrapper(),
426 																	 const ShaderWrapper								tessellationEvalShader = ShaderWrapper(),
427 																	 const ShaderWrapper								geometryShader = ShaderWrapper(),
428 																	 const VkSpecializationInfo*						specializationInfo = DE_NULL,
429 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState = nullptr,
430 																	 PipelineRenderingCreateInfoWrapper					rendering = PipelineRenderingCreateInfoWrapper(),
431 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
432 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
433 
434 	GraphicsPipelineWrapper&	setupPreRasterizationShaderState2	(const std::vector<VkViewport>&						viewports,
435 																	 const std::vector<VkRect2D>&						scissors,
436 																	 const PipelineLayoutWrapper&						layout,
437 																	 const VkRenderPass									renderPass,
438 																	 const deUint32										subpass,
439 																	 const ShaderWrapper								vertexShaderModule,
440 																	 const VkPipelineRasterizationStateCreateInfo*		rasterizationState = nullptr,
441 																	 const ShaderWrapper								tessellationControlShader = ShaderWrapper(),
442 																	 const ShaderWrapper								tessellationEvalShader = ShaderWrapper(),
443 																	 const ShaderWrapper								geometryShader = ShaderWrapper(),
444 																	 const VkSpecializationInfo*						vertSpecializationInfo = nullptr,
445 																	 const VkSpecializationInfo*						tescSpecializationInfo = nullptr,
446 																	 const VkSpecializationInfo*						teseSpecializationInfo = nullptr,
447 																	 const VkSpecializationInfo*						geomSpecializationInfo = nullptr,
448 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState = nullptr,
449 																	 PipelineRenderingCreateInfoWrapper					rendering = PipelineRenderingCreateInfoWrapper(),
450 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
451 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
452 
453 	// Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
454 	GraphicsPipelineWrapper&	setupPreRasterizationShaderState3	(const std::vector<VkViewport>&								viewports,
455 																	 const std::vector<VkRect2D>&								scissors,
456 																	 const PipelineLayoutWrapper&								layout,
457 																	 const VkRenderPass											renderPass,
458 																	 const deUint32												subpass,
459 																	 const ShaderWrapper										vertexShaderModule,
460 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		vertShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
461 																	 const VkPipelineRasterizationStateCreateInfo*				rasterizationState = nullptr,
462 																	 const ShaderWrapper										tessellationControlShader = ShaderWrapper(),
463 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		tescShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
464 																	 const ShaderWrapper										tessellationEvalShader = ShaderWrapper(),
465 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		teseShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
466 																	 const ShaderWrapper										geometryShader = ShaderWrapper(),
467 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		geomShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
468 																	 const VkSpecializationInfo*								vertSpecializationInfo = nullptr,
469 																	 const VkSpecializationInfo*								tescSpecializationInfo = nullptr,
470 																	 const VkSpecializationInfo*								teseSpecializationInfo = nullptr,
471 																	 const VkSpecializationInfo*								geomSpecializationInfo = nullptr,
472 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*			fragmentShadingRateState = nullptr,
473 																	 PipelineRenderingCreateInfoWrapper							rendering = PipelineRenderingCreateInfoWrapper(),
474 																	 const VkPipelineCache										partPipelineCache = DE_NULL,
475 																	 PipelineCreationFeedbackCreateInfoWrapper					partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
476 
477 #ifndef CTS_USES_VULKANSC
478 	// Setup pre-rasterization shader state, mesh shading version.
479 	GraphicsPipelineWrapper&	setupPreRasterizationMeshShaderState(const std::vector<VkViewport>&						viewports,
480 																	 const std::vector<VkRect2D>&						scissors,
481 																	 const PipelineLayoutWrapper&						layout,
482 																	 const VkRenderPass									renderPass,
483 																	 const deUint32										subpass,
484 																	 const ShaderWrapper								taskShader,
485 																	 const ShaderWrapper								meshShader,
486 																	 const VkPipelineRasterizationStateCreateInfo*		rasterizationState = nullptr,
487 																	 const VkSpecializationInfo*						taskSpecializationInfo = nullptr,
488 																	 const VkSpecializationInfo*						meshSpecializationInfo = nullptr,
489 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState = nullptr,
490 																	 PipelineRenderingCreateInfoWrapper					rendering = PipelineRenderingCreateInfoWrapper(),
491 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
492 																	 VkPipelineCreationFeedbackCreateInfoEXT*			partCreationFeedback = nullptr);
493 #endif // CTS_USES_VULKANSC
494 
495 	// Setup fragment shader state.
496 	GraphicsPipelineWrapper&	setupFragmentShaderState			(const PipelineLayoutWrapper&						layout,
497 																	 const VkRenderPass									renderPass,
498 																	 const deUint32										subpass,
499 																	 const ShaderWrapper								fragmentShaderModule,
500 																	 const VkPipelineDepthStencilStateCreateInfo*		depthStencilState = DE_NULL,
501 																	 const VkPipelineMultisampleStateCreateInfo*		multisampleState = DE_NULL,
502 																	 const VkSpecializationInfo*						specializationInfo = DE_NULL,
503 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
504 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
505 
506 	// Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
507 	GraphicsPipelineWrapper&	setupFragmentShaderState2			(const PipelineLayoutWrapper&								layout,
508 																	 const VkRenderPass											renderPass,
509 																	 const deUint32												subpass,
510 																	 const ShaderWrapper										fragmentShaderModule,
511 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		fragmentShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
512 																	 const VkPipelineDepthStencilStateCreateInfo*				depthStencilState = nullptr,
513 																	 const VkPipelineMultisampleStateCreateInfo*				multisampleState = nullptr,
514 																	 const VkSpecializationInfo*								specializationInfo = nullptr,
515 																	 const VkPipelineCache										partPipelineCache = DE_NULL,
516 																	 PipelineCreationFeedbackCreateInfoWrapper					partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
517 
518 	// Setup fragment output state.
519 	GraphicsPipelineWrapper&	setupFragmentOutputState			(const VkRenderPass									renderPass,
520 																	 const deUint32										subpass = 0u,
521 																	 const VkPipelineColorBlendStateCreateInfo*			colorBlendState = DE_NULL,
522 																	 const VkPipelineMultisampleStateCreateInfo*		multisampleState = DE_NULL,
523 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
524 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
525 
526 	// Build pipeline object out of provided state.
527 	void						buildPipeline						(const VkPipelineCache								pipelineCache = DE_NULL,
528 																	 const VkPipeline									basePipelineHandle = DE_NULL,
529 																	 const deInt32										basePipelineIndex = 0,
530 																	 PipelineCreationFeedbackCreateInfoWrapper			creationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
531 																	 void*												pNext = DE_NULL);
532 	// Create shader objects if used
533 #ifndef CTS_USES_VULKANSC
534 	vk::VkShaderStageFlags		getNextStages						(vk::VkShaderStageFlagBits shaderStage, bool tessellationShaders, bool geometryShaders, bool link);
535 	vk::VkShaderCreateInfoEXT	makeShaderCreateInfo				(VkShaderStageFlagBits stage, ShaderWrapper& shader, bool link, bool binary, ShaderWrapper& other);
536 	void						createShaders						(bool linked, bool binary);
537 #endif
538 
539 	// Bind pipeline or shader objects
540 	void						bind								(vk::VkCommandBuffer cmdBuffer) const;
541 
542 	// Returns true when pipeline was build using buildPipeline method.
543 	deBool						wasBuild							(void) const;
544 	// Returns true when pipeline or shader objects was built.
545 	deBool						wasPipelineOrShaderObjectBuild		(void) const;
546 
547 	// Get compleate pipeline. GraphicsPipelineWrapper preserves ovnership and will destroy pipeline in its destructor.
548 	vk::VkPipeline				getPipeline							(void) const;
549 
550 	// Destroy compleate pipeline - pipeline parts are not destroyed.
551 	void						destroyPipeline						(void);
552 
553 protected:
554 
555 	// No default constructor - use parametrized constructor or emplace_back in case of vectors.
556 	GraphicsPipelineWrapper() = default;
557 
558 	// Dynamic states that are only dynamic in shader objects
559 	bool						isShaderObjectDynamic				(vk::VkDynamicState dynamicState) const;
560 	void						setShaderObjectDynamicStates		(vk::VkCommandBuffer cmdBuffer) const;
561 
562 	struct InternalData;
563 
564 protected:
565 
566 	static constexpr size_t kMaxPipelineParts = 4u;
567 
568 	// Store partial pipelines when non monolithic construction was used.
569 	Move<VkPipeline>				m_pipelineParts[kMaxPipelineParts];
570 
571 	// Store monolithic pipeline or linked pipeline libraries.
572 	Move<VkPipeline>				m_pipelineFinal;
573 
574 	// Store internal data that is needed only for pipeline construction.
575 	de::SharedPtr<InternalData>		m_internalData;
576 };
577 
578 } // vk
579 
580 #endif // _VKPIPELINECONSTRUCTIONUTIL_HPP
581