• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Pipeline specialization constants test utilities
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktPipelineSpecConstantUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include <vector>
27 
28 namespace vkt
29 {
30 namespace pipeline
31 {
32 using namespace vk;
33 
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)34 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&			vk,
35 															 const VkDevice					device,
36 															 const VkShaderStageFlagBits	stage,
37 															 const ProgramBinary&			binary,
38 															 const VkSpecializationInfo*	specInfo)
39 {
40 	VkShaderModule module;
41 	switch (stage)
42 	{
43 		case (VK_SHADER_STAGE_VERTEX_BIT):
44 			DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
45 			m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
46 			module = *m_vertexShaderModule;
47 			break;
48 
49 		case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
50 			DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
51 			m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
52 			module = *m_tessControlShaderModule;
53 			break;
54 
55 		case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
56 			DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
57 			m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
58 			module = *m_tessEvaluationShaderModule;
59 			break;
60 
61 		case (VK_SHADER_STAGE_GEOMETRY_BIT):
62 			DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
63 			m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
64 			module = *m_geometryShaderModule;
65 			break;
66 
67 		case (VK_SHADER_STAGE_FRAGMENT_BIT):
68 			DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
69 			m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
70 			module = *m_fragmentShaderModule;
71 			break;
72 
73 		default:
74 			DE_FATAL("Invalid shader stage");
75 			return *this;
76 	}
77 
78 	const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
79 	{
80 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
81 		DE_NULL,												// const void*							pNext;
82 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
83 		stage,													// VkShaderStageFlagBits				stage;
84 		module,													// VkShaderModule						module;
85 		"main",													// const char*							pName;
86 		specInfo,												// const VkSpecializationInfo*			pSpecializationInfo;
87 	};
88 
89 	m_shaderStageFlags |= stage;
90 	m_shaderStages.push_back(pipelineShaderStageInfo);
91 
92 	return *this;
93 }
94 
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass)95 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&	vk,
96 												 const VkDevice			device,
97 												 const VkPipelineLayout	pipelineLayout,
98 												 const VkRenderPass		renderPass)
99 {
100 	const VkVertexInputBindingDescription vertexInputBindingDescription =
101 	{
102 		0u,								// uint32_t				binding;
103 		sizeof(tcu::Vec4),				// uint32_t				stride;		// Vertex is a 4-element vector XYZW, position only
104 		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate	inputRate;
105 	};
106 
107 	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
108 	{
109 		0u,									// uint32_t			location;
110 		0u,									// uint32_t			binding;
111 		VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat			format;
112 		0u,									// uint32_t			offset;
113 	};
114 
115 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
116 	{
117 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
118 		DE_NULL,													// const void*                                 pNext;
119 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
120 		1u,															// uint32_t                                    vertexBindingDescriptionCount;
121 		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
122 		1u,															// uint32_t                                    vertexAttributeDescriptionCount;
123 		&vertexInputAttributeDescription,							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
124 	};
125 
126 	const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
127 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
128 	{
129 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
130 		DE_NULL,														// const void*                                 pNext;
131 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
132 		topology,														// VkPrimitiveTopology                         topology;
133 		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
134 	};
135 
136 	const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
137 	{
138 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
139 		DE_NULL,														// const void*                                 pNext;
140 		(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
141 		3u,																// uint32_t                                    patchControlPoints;
142 	};
143 
144 	const VkViewport viewport = makeViewport(
145 		0.0f, 0.0f,
146 		static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
147 		0.0f, 1.0f);
148 
149 	const VkRect2D scissor = {
150 		makeOffset2D(0, 0),
151 		makeExtent2D(m_renderSize.x(), m_renderSize.y()),
152 	};
153 
154 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
155 	{
156 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
157 		DE_NULL,												// const void*                                 pNext;
158 		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
159 		1u,														// uint32_t                                    viewportCount;
160 		&viewport,												// const VkViewport*                           pViewports;
161 		1u,														// uint32_t                                    scissorCount;
162 		&scissor,												// const VkRect2D*                             pScissors;
163 	};
164 
165 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
166 	{
167 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
168 		DE_NULL,														// const void*                              pNext;
169 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
170 		VK_FALSE,														// VkBool32                                 depthClampEnable;
171 		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
172 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
173 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
174 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
175 		VK_FALSE,														// VkBool32									depthBiasEnable;
176 		0.0f,															// float									depthBiasConstantFactor;
177 		0.0f,															// float									depthBiasClamp;
178 		0.0f,															// float									depthBiasSlopeFactor;
179 		1.0f,															// float									lineWidth;
180 	};
181 
182 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
183 	{
184 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
185 		DE_NULL,													// const void*								pNext;
186 		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
187 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
188 		VK_FALSE,													// VkBool32									sampleShadingEnable;
189 		0.0f,														// float									minSampleShading;
190 		DE_NULL,													// const VkSampleMask*						pSampleMask;
191 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
192 		VK_FALSE													// VkBool32									alphaToOneEnable;
193 	};
194 
195 	const VkStencilOpState stencilOpStateBasic = makeStencilOpState(
196 		VK_STENCIL_OP_KEEP,		// stencil fail
197 		VK_STENCIL_OP_KEEP,		// depth & stencil pass
198 		VK_STENCIL_OP_KEEP,		// depth only fail
199 		VK_COMPARE_OP_NEVER,	// compare op
200 		0u,						// compare mask
201 		0u,						// write mask
202 		0u);					// reference
203 
204 	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
205 	{
206 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
207 		DE_NULL,													// const void*								pNext;
208 		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
209 		VK_FALSE,													// VkBool32									depthTestEnable;
210 		VK_FALSE,													// VkBool32									depthWriteEnable;
211 		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
212 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
213 		VK_FALSE,													// VkBool32									stencilTestEnable;
214 		stencilOpStateBasic,										// VkStencilOpState							front;
215 		stencilOpStateBasic,										// VkStencilOpState							back;
216 		0.0f,														// float									minDepthBounds;
217 		1.0f,														// float									maxDepthBounds;
218 	};
219 
220 	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
221 	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
222 	{
223 		VK_FALSE,							// VkBool32					blendEnable;
224 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			srcColorBlendFactor;
225 		VK_BLEND_FACTOR_ZERO,				// VkBlendFactor			dstColorBlendFactor;
226 		VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
227 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			srcAlphaBlendFactor;
228 		VK_BLEND_FACTOR_ZERO,				// VkBlendFactor			dstAlphaBlendFactor;
229 		VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
230 		colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
231 	};
232 
233 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
234 	{
235 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
236 		DE_NULL,													// const void*									pNext;
237 		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
238 		VK_FALSE,													// VkBool32										logicOpEnable;
239 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
240 		1u,															// deUint32										attachmentCount;
241 		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
242 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
243 	};
244 
245 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
246 	{
247 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
248 		DE_NULL,											// const void*										pNext;
249 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
250 		static_cast<deUint32>(m_shaderStages.size()),		// deUint32											stageCount;
251 		&m_shaderStages[0],									// const VkPipelineShaderStageCreateInfo*			pStages;
252 		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
253 		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
254 		(m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*		pTessellationState;
255 		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
256 		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
257 		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
258 		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
259 		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
260 		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
261 		pipelineLayout,										// VkPipelineLayout									layout;
262 		renderPass,											// VkRenderPass										renderPass;
263 		0u,													// deUint32											subpass;
264 		DE_NULL,											// VkPipeline										basePipelineHandle;
265 		0,													// deInt32											basePipelineIndex;
266 	};
267 
268 	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
269 }
270 
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat)271 Move<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
272 								   const VkDevice			device,
273 								   const VkFormat			colorFormat)
274 {
275 	const VkAttachmentDescription colorAttachmentDescription =
276 	{
277 		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
278 		colorFormat,										// VkFormat							format;
279 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
280 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
281 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
282 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
283 		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
284 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
285 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
286 	};
287 
288 	const VkAttachmentReference colorAttachmentReference =
289 	{
290 		0u,													// deUint32			attachment;
291 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
292 	};
293 
294 	const VkAttachmentReference depthAttachmentReference =
295 	{
296 		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
297 		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
298 	};
299 
300 	const VkSubpassDescription subpassDescription =
301 	{
302 		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
303 		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
304 		0u,													// deUint32							inputAttachmentCount;
305 		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
306 		1u,													// deUint32							colorAttachmentCount;
307 		&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
308 		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
309 		&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
310 		0u,													// deUint32							preserveAttachmentCount;
311 		DE_NULL												// const deUint32*					pPreserveAttachments;
312 	};
313 
314 	const VkRenderPassCreateInfo renderPassInfo =
315 	{
316 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
317 		DE_NULL,											// const void*						pNext;
318 		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
319 		1u,													// deUint32							attachmentCount;
320 		&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
321 		1u,													// deUint32							subpassCount;
322 		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
323 		0u,													// deUint32							dependencyCount;
324 		DE_NULL												// const VkSubpassDependency*		pDependencies;
325 	};
326 
327 	return createRenderPass(vk, device, &renderPassInfo);
328 }
329 
beginRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor)330 void beginRenderPass (const DeviceInterface&	vk,
331 					  const VkCommandBuffer		commandBuffer,
332 					  const VkRenderPass		renderPass,
333 					  const VkFramebuffer		framebuffer,
334 					  const VkRect2D&			renderArea,
335 					  const tcu::Vec4&			clearColor)
336 {
337 	const VkClearValue clearValue = makeClearValueColor(clearColor);
338 
339 	const VkRenderPassBeginInfo renderPassBeginInfo = {
340 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
341 		DE_NULL,										// const void*             pNext;
342 		renderPass,										// VkRenderPass            renderPass;
343 		framebuffer,									// VkFramebuffer           framebuffer;
344 		renderArea,										// VkRect2D                renderArea;
345 		1u,												// uint32_t                clearValueCount;
346 		&clearValue,									// const VkClearValue*     pClearValues;
347 	};
348 
349 	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
350 }
351 
makeImageCreateInfo(const tcu::IVec2 & size,const VkFormat format,const VkImageUsageFlags usage)352 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
353 {
354 	const VkImageCreateInfo imageInfo =
355 	{
356 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
357 		DE_NULL,									// const void*              pNext;
358 		(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
359 		VK_IMAGE_TYPE_2D,							// VkImageType              imageType;
360 		format,										// VkFormat                 format;
361 		makeExtent3D(size.x(), size.y(), 1),		// VkExtent3D               extent;
362 		1u,											// uint32_t                 mipLevels;
363 		1u,											// uint32_t                 arrayLayers;
364 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
365 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
366 		usage,										// VkImageUsageFlags        usage;
367 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
368 		0u,											// uint32_t                 queueFamilyIndexCount;
369 		DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
370 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
371 	};
372 	return imageInfo;
373 }
374 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)375 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
376 {
377 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
378 
379 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
380 		throw tcu::NotSupportedError("Tessellation shader not supported");
381 
382 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
383 		throw tcu::NotSupportedError("Geometry shader not supported");
384 
385 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
386 		throw tcu::NotSupportedError("Double-precision floats not supported");
387 
388 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
389 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
390 
391 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
392 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
393 }
394 
395 } // pipeline
396 } // vkt
397