• 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  *
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.
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vkRef.hpp"
28 #include "vkDefs.hpp"
29 #include "tcuDefs.hpp"
30 #include "deSharedPtr.hpp"
31 #include <vector>
32 #include <stdexcept>
33 
34 namespace vk
35 {
36 
37 enum PipelineConstructionType
38 {
39 	PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC			= 0,	// Construct legacy - monolithic pipeline
40 	PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY,	// Use VK_EXT_graphics_pipeline_library and construct pipeline out of several pipeline parts.
41 	PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY			// Same as PIPELINE_CONSTRUCTION_TYPE_OPTIMISED_LIBRARY but with fast linking
42 };
43 
44 void checkPipelineLibraryRequirements (const InstanceInterface&		vki,
45 									   VkPhysicalDevice				physicalDevice,
46 									   PipelineConstructionType		pipelineConstructionType);
47 
48 // This exception may be raised in one of the intermediate steps when using shader module IDs instead of normal module objects.
49 class PipelineCompileRequiredError : public std::runtime_error
50 {
51 public:
PipelineCompileRequiredError(const std::string & msg)52 	PipelineCompileRequiredError (const std::string& msg)
53 		: std::runtime_error(msg)
54 		{}
55 };
56 
57 // PointerWrapper template is used to hide structures that should not be visible for Vulkan SC
58 template <typename T>
59 class PointerWrapper
60 {
61 public:
PointerWrapper()62 	PointerWrapper(): ptr(DE_NULL)	{}
PointerWrapper(T * p0)63 	PointerWrapper(T* p0) : ptr(p0) {}
64 	T* ptr;
65 };
66 
67 template <typename T>
68 class ConstPointerWrapper
69 {
70 public:
ConstPointerWrapper()71 	ConstPointerWrapper(): ptr(DE_NULL)  {}
ConstPointerWrapper(const T * p0)72 	ConstPointerWrapper(const T* p0) : ptr(p0) {}
73 	const T* ptr;
74 };
75 
76 #ifndef CTS_USES_VULKANSC
77 typedef PointerWrapper<VkPipelineViewportDepthClipControlCreateInfoEXT> PipelineViewportDepthClipControlCreateInfoWrapper;
78 typedef PointerWrapper<VkPipelineRenderingCreateInfoKHR> PipelineRenderingCreateInfoWrapper;
79 typedef PointerWrapper<VkPipelineCreationFeedbackCreateInfoEXT> PipelineCreationFeedbackCreateInfoWrapper;
80 typedef ConstPointerWrapper<VkPipelineShaderStageModuleIdentifierCreateInfoEXT> PipelineShaderStageModuleIdentifierCreateInfoWrapper;
81 typedef PointerWrapper<VkPipelineRepresentativeFragmentTestStateCreateInfoNV> PipelineRepresentativeFragmentTestCreateInfoWrapper;
82 #else
83 typedef PointerWrapper<void> PipelineViewportDepthClipControlCreateInfoWrapper;
84 typedef PointerWrapper<void> PipelineRenderingCreateInfoWrapper;
85 typedef PointerWrapper<void> PipelineCreationFeedbackCreateInfoWrapper;
86 typedef ConstPointerWrapper<void> PipelineShaderStageModuleIdentifierCreateInfoWrapper;
87 typedef PointerWrapper<void> PipelineRepresentativeFragmentTestCreateInfoWrapper;
88 #endif
89 
90 // Class that can build monolithic pipeline or fully separated pipeline libraries
91 // depending on PipelineType specified in the constructor.
92 // Rarely needed configuration was extracted to setDefault*/disable* functions while common
93 // state setup is provided as arguments of four setup* functions - one for each state group.
94 class GraphicsPipelineWrapper
95 {
96 public:
97 								GraphicsPipelineWrapper				(const DeviceInterface&				vk,
98 																	 VkDevice							device,
99 																	 const PipelineConstructionType		pipelineConstructionType,
100 																	 const VkPipelineCreateFlags		flags = 0u);
101 
102 								GraphicsPipelineWrapper				(GraphicsPipelineWrapper&&) noexcept;
103 
104 								~GraphicsPipelineWrapper			(void) = default;
105 
106 
107 	// By default pipelineLayout used for monotlithic pipeline is taken from layout specified
108 	// in setupPreRasterizationShaderState but when there are also descriptor sets needed for fragment
109 	// shader bindings then separate pipeline layout for monolithic pipeline must be provided
110 	GraphicsPipelineWrapper&	setMonolithicPipelineLayout			(const VkPipelineLayout layout);
111 
112 
113 	// By default dynamic state has to be specified before specifying other CreateInfo structures
114 	GraphicsPipelineWrapper&	setDynamicState						(const VkPipelineDynamicStateCreateInfo* dynamicState);
115 
116 	// Specify the representative fragment test state.
117 	GraphicsPipelineWrapper&	setRepresentativeFragmentTestState	(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState);
118 
119 	// Specify topology that is used by default InputAssemblyState in vertex input state. This needs to be
120 	// specified only when there is no custom InputAssemblyState provided in setupVertexInputState and when
121 	// topology is diferent then VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST which is used by default.
122 	GraphicsPipelineWrapper&	setDefaultTopology					(const VkPrimitiveTopology topology);
123 
124 	// Specify patch control points that is used by default TessellationState in pre-rasterization shader state.
125 	// This can to be specified only when there is no custom TessellationState provided in
126 	// setupPreRasterizationShaderState and when patchControlPoints is diferent then 3 which is used by default.
127 	GraphicsPipelineWrapper&	setDefaultPatchControlPoints		(const deUint32 patchControlPoints);
128 
129 	// Specify tesellation domain origin, used by the tessellation state in pre-rasterization shader state.
130 	GraphicsPipelineWrapper&	setDefaultTessellationDomainOrigin	(const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct = false);
131 
132 	// Enable discarding of primitives that is used by default RasterizationState in pre-rasterization shader state.
133 	// This can be specified only when there is no custom RasterizationState provided in setupPreRasterizationShaderState.
134 	GraphicsPipelineWrapper&	setDefaultRasterizerDiscardEnable	(const deBool rasterizerDiscardEnable = DE_TRUE);
135 
136 	// When some states are not provided then default structures can be used. This behaviour can be turned on by one of below methods.
137 	// Some tests require those states to be NULL so we can't assume using default versions.
138 	GraphicsPipelineWrapper&	setDefaultRasterizationState		(void);
139 	GraphicsPipelineWrapper&	setDefaultDepthStencilState			(void);
140 	GraphicsPipelineWrapper&	setDefaultColorBlendState			(void);
141 	GraphicsPipelineWrapper&	setDefaultMultisampleState			(void);
142 
143 	// Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. By default
144 	// number of viewports and scissors is same as number of items in vector but when vectors are empty then by
145 	// default count of viewports/scissors is set to 1. This can be changed by below functions.
146 	GraphicsPipelineWrapper&	setDefaultViewportsCount			(deUint32 viewportCount = 0u);
147 	GraphicsPipelineWrapper&	setDefaultScissorsCount				(deUint32 scissorCount = 0u);
148 
149 	// Pre-rasterization shader state uses default ViewportState, this method extends the internal structure.
150 	GraphicsPipelineWrapper&	setViewportStatePnext				(const void* pNext);
151 
152 #ifndef CTS_USES_VULKANSC
153 	GraphicsPipelineWrapper&	setRenderingColorAttachmentsInfo	(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo);
154 #endif
155 
156 	// Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. When disableViewportState
157 	// is used then ViewportState won't be constructed and NULL will be used.
158 	GraphicsPipelineWrapper&	disableViewportState				(void);
159 
160 
161 	// Setup vertex input state. When VertexInputState or InputAssemblyState are not provided then default structures will be used.
162 	GraphicsPipelineWrapper&	setupVertexInputState				(const VkPipelineVertexInputStateCreateInfo*		vertexInputState = DE_NULL,
163 																	 const VkPipelineInputAssemblyStateCreateInfo*		inputAssemblyState = DE_NULL,
164 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
165 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
166 
167 	// Setup pre-rasterization shader state.
168 	GraphicsPipelineWrapper&	setupPreRasterizationShaderState	(const std::vector<VkViewport>&						viewports,
169 																	 const std::vector<VkRect2D>&						scissors,
170 																	 const VkPipelineLayout								layout,
171 																	 const VkRenderPass									renderPass,
172 																	 const deUint32										subpass,
173 																	 const VkShaderModule								vertexShaderModule,
174 																	 const VkPipelineRasterizationStateCreateInfo*		rasterizationState = DE_NULL,
175 																	 const VkShaderModule								tessellationControlShaderModule = DE_NULL,
176 																	 const VkShaderModule								tessellationEvalShaderModule = DE_NULL,
177 																	 const VkShaderModule								geometryShaderModule = DE_NULL,
178 																	 const VkSpecializationInfo*						specializationInfo = DE_NULL,
179 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState = nullptr,
180 																	 PipelineRenderingCreateInfoWrapper					rendering = PipelineRenderingCreateInfoWrapper(),
181 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
182 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
183 
184 	GraphicsPipelineWrapper&	setupPreRasterizationShaderState2	(const std::vector<VkViewport>&						viewports,
185 																	 const std::vector<VkRect2D>&						scissors,
186 																	 const VkPipelineLayout								layout,
187 																	 const VkRenderPass									renderPass,
188 																	 const deUint32										subpass,
189 																	 const VkShaderModule								vertexShaderModule,
190 																	 const VkPipelineRasterizationStateCreateInfo*		rasterizationState = nullptr,
191 																	 const VkShaderModule								tessellationControlShaderModulnullptre = DE_NULL,
192 																	 const VkShaderModule								tessellationEvalShaderModule = DE_NULL,
193 																	 const VkShaderModule								geometryShaderModule = DE_NULL,
194 																	 const VkSpecializationInfo*						vertSpecializationInfo = nullptr,
195 																	 const VkSpecializationInfo*						tescSpecializationInfo = nullptr,
196 																	 const VkSpecializationInfo*						teseSpecializationInfo = nullptr,
197 																	 const VkSpecializationInfo*						geomSpecializationInfo = nullptr,
198 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState = nullptr,
199 																	 PipelineRenderingCreateInfoWrapper					rendering = PipelineRenderingCreateInfoWrapper(),
200 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
201 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
202 
203 	// Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
204 	GraphicsPipelineWrapper&	setupPreRasterizationShaderState3	(const std::vector<VkViewport>&								viewports,
205 																	 const std::vector<VkRect2D>&								scissors,
206 																	 const VkPipelineLayout										layout,
207 																	 const VkRenderPass											renderPass,
208 																	 const deUint32												subpass,
209 																	 const VkShaderModule										vertexShaderModule,
210 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		vertShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
211 																	 const VkPipelineRasterizationStateCreateInfo*				rasterizationState = nullptr,
212 																	 const VkShaderModule										tessellationControlShaderModule = DE_NULL,
213 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		tescShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
214 																	 const VkShaderModule										tessellationEvalShaderModule = DE_NULL,
215 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		teseShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
216 																	 const VkShaderModule										geometryShaderModule = DE_NULL,
217 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		geomShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
218 																	 const VkSpecializationInfo*								vertSpecializationInfo = nullptr,
219 																	 const VkSpecializationInfo*								tescSpecializationInfo = nullptr,
220 																	 const VkSpecializationInfo*								teseSpecializationInfo = nullptr,
221 																	 const VkSpecializationInfo*								geomSpecializationInfo = nullptr,
222 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*			fragmentShadingRateState = nullptr,
223 																	 PipelineRenderingCreateInfoWrapper							rendering = PipelineRenderingCreateInfoWrapper(),
224 																	 const VkPipelineCache										partPipelineCache = DE_NULL,
225 																	 PipelineCreationFeedbackCreateInfoWrapper					partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
226 
227 #ifndef CTS_USES_VULKANSC
228 	// Setup pre-rasterization shader state, mesh shading version.
229 	GraphicsPipelineWrapper&	setupPreRasterizationMeshShaderState(const std::vector<VkViewport>&						viewports,
230 																	 const std::vector<VkRect2D>&						scissors,
231 																	 const VkPipelineLayout								layout,
232 																	 const VkRenderPass									renderPass,
233 																	 const deUint32										subpass,
234 																	 const VkShaderModule								taskShaderModule,
235 																	 const VkShaderModule								meshShaderModule,
236 																	 const VkPipelineRasterizationStateCreateInfo*		rasterizationState = nullptr,
237 																	 const VkSpecializationInfo*						taskSpecializationInfo = nullptr,
238 																	 const VkSpecializationInfo*						meshSpecializationInfo = nullptr,
239 																	 VkPipelineFragmentShadingRateStateCreateInfoKHR*	fragmentShadingRateState = nullptr,
240 																	 PipelineRenderingCreateInfoWrapper					rendering = PipelineRenderingCreateInfoWrapper(),
241 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
242 																	 VkPipelineCreationFeedbackCreateInfoEXT*			partCreationFeedback = nullptr);
243 #endif // CTS_USES_VULKANSC
244 
245 	// Setup fragment shader state.
246 	GraphicsPipelineWrapper&	setupFragmentShaderState			(const VkPipelineLayout								layout,
247 																	 const VkRenderPass									renderPass,
248 																	 const deUint32										subpass,
249 																	 const VkShaderModule								fragmentShaderModule,
250 																	 const VkPipelineDepthStencilStateCreateInfo*		depthStencilState = DE_NULL,
251 																	 const VkPipelineMultisampleStateCreateInfo*		multisampleState = DE_NULL,
252 																	 const VkSpecializationInfo*						specializationInfo = DE_NULL,
253 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
254 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
255 
256 	// Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
257 	GraphicsPipelineWrapper&	setupFragmentShaderState2			(const VkPipelineLayout										layout,
258 																	 const VkRenderPass											renderPass,
259 																	 const deUint32												subpass,
260 																	 const VkShaderModule										fragmentShaderModule,
261 																	 PipelineShaderStageModuleIdentifierCreateInfoWrapper		fragmentShaderModuleId = PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
262 																	 const VkPipelineDepthStencilStateCreateInfo*				depthStencilState = nullptr,
263 																	 const VkPipelineMultisampleStateCreateInfo*				multisampleState = nullptr,
264 																	 const VkSpecializationInfo*								specializationInfo = nullptr,
265 																	 const VkPipelineCache										partPipelineCache = DE_NULL,
266 																	 PipelineCreationFeedbackCreateInfoWrapper					partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
267 
268 	// Setup fragment output state.
269 	GraphicsPipelineWrapper&	setupFragmentOutputState			(const VkRenderPass									renderPass,
270 																	 const deUint32										subpass = 0u,
271 																	 const VkPipelineColorBlendStateCreateInfo*			colorBlendState = DE_NULL,
272 																	 const VkPipelineMultisampleStateCreateInfo*		multisampleState = DE_NULL,
273 																	 const VkPipelineCache								partPipelineCache = DE_NULL,
274 																	 PipelineCreationFeedbackCreateInfoWrapper			partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
275 
276 	// Build pipeline object out of provided state.
277 	void						buildPipeline						(const VkPipelineCache								pipelineCache = DE_NULL,
278 																	 const VkPipeline									basePipelineHandle = DE_NULL,
279 																	 const deInt32										basePipelineIndex = 0,
280 																	 PipelineCreationFeedbackCreateInfoWrapper			creationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
281 
282 	// Returns true when pipeline was build using buildPipeline method.
283 	deBool						wasBuild							(void) const;
284 
285 	// Get compleate pipeline. GraphicsPipelineWrapper preserves ovnership and will desroy pipeline in its destructor.
286 	vk::VkPipeline				getPipeline							(void) const;
287 
288 	// Destroy compleate pipeline - pipeline parts are not destroyed.
289 	void						destroyPipeline						(void);
290 
291 protected:
292 
293 	// No default constructor - use parametrized constructor or emplace_back in case of vectors.
294 	GraphicsPipelineWrapper() = default;
295 
296 	struct InternalData;
297 
298 protected:
299 
300 	static constexpr size_t kMaxPipelineParts = 4u;
301 
302 	// Store partial pipelines when non monolithic construction was used.
303 	Move<VkPipeline>				m_pipelineParts[kMaxPipelineParts];
304 
305 	// Store monolithic pipeline or linked pipeline libraries.
306 	Move<VkPipeline>				m_pipelineFinal;
307 
308 	// Store internal data that is needed only for pipeline construction.
309 	de::SharedPtr<InternalData>		m_internalData;
310 };
311 
312 } // vk
313 
314 #endif // _VKPIPELINECONSTRUCTIONUTIL_HPP
315