• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Intel Corporation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief VK_KHR_pipeline_executable_properties
23  *
24  * These tests creates compute and graphics pipelines with a variety of
25  * stages both with and without a pipeline cache and exercise the new
26  * queries provided by VK_KHR_pipeline_executable_properties.
27  *
28  * For each query type, it asserts that the query works and doesn't crash
29  * and returns consistent results:
30  *
31  *  - The tests assert that the same set of pipeline executables is
32  *    reported regardless of whether or not a pipeline cache is used.
33  *
34  *  - For each pipeline executable, the tests assert that the same set of
35  *    statistics is returned regardless of whether or not a pipeline cache
36  *    is used.
37  *
38  *  - For each pipeline executable, the tests assert that the same set of
39  *    statistics is returned regardless of whether or not
40  *    CAPTURE_INTERNAL_REPRESENTATIONS_BIT is set.
41  *
42  *  - For each pipeline executable, the tests assert that the same set of
43  *    internal representations is returned regardless of whether or not a
44  *    pipeline cache is used.
45  *
46  *  - For each string returned (statistic names, etc.) the tests assert
47  *    that the string is NULL terminated.
48  *
49  *  - For each statistic, the tests compare the results of the two
50  *    compilations and report any differences.  (Statistics differing
51  *    between two compilations is not considered a failure.)
52  *
53  *  - For each binary internal representation, the tests attempt to assert
54  *    that the amount of data returned by the implementation matches the
55  *    amount the implementation claims.  (It's impossible to exactly do
56  *    this but the tests give it a good try.)
57  *
58  * All of the returned data is recorded in the output file.
59  *
60  *//*--------------------------------------------------------------------*/
61 
62 #include "vktPipelineExecutablePropertiesTests.hpp"
63 #include "vktPipelineVertexUtil.hpp"
64 #include "vktTestCase.hpp"
65 #include "vktTestCaseUtil.hpp"
66 #include "vkMemUtil.hpp"
67 #include "vkBuilderUtil.hpp"
68 #include "vkRefUtil.hpp"
69 #include "vkTypeUtil.hpp"
70 #include "vkObjUtil.hpp"
71 #include "tcuTestLog.hpp"
72 
73 #include <sstream>
74 #include <vector>
75 
76 namespace vkt
77 {
78 namespace pipeline
79 {
80 
81 using namespace vk;
82 
83 namespace
84 {
85 enum
86 {
87 	VK_MAX_SHADER_STAGES = 6,
88 };
89 
90 enum
91 {
92 	PIPELINE_CACHE_NDX_INITIAL = 0,
93 	PIPELINE_CACHE_NDX_CACHED = 1,
94 	PIPELINE_CACHE_NDX_COUNT,
95 };
96 
97 // helper functions
98 
getShaderFlagStr(const VkShaderStageFlagBits shader,bool isDescription)99 std::string getShaderFlagStr (const VkShaderStageFlagBits	shader,
100 							  bool							isDescription)
101 {
102 	std::ostringstream desc;
103 	switch(shader)
104 	{
105 		case VK_SHADER_STAGE_VERTEX_BIT:
106 		{
107 			desc << ((isDescription) ? "vertex" : "vertex_stage");
108 			break;
109 		}
110 		case VK_SHADER_STAGE_FRAGMENT_BIT:
111 		{
112 			desc << ((isDescription) ? "fragment" : "fragment_stage");
113 			break;
114 		}
115 		case VK_SHADER_STAGE_GEOMETRY_BIT:
116 		{
117 			desc << ((isDescription) ? "geometry" : "geometry_stage");
118 			break;
119 		}
120 		case VK_SHADER_STAGE_COMPUTE_BIT:
121 		{
122 			desc << ((isDescription) ? "compute" : "compute_stage");
123 			break;
124 		}
125 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
126 		{
127 			desc << ((isDescription) ? "tessellation control" : "tessellation_control_stage");
128 			break;
129 		}
130 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
131 		{
132 			desc << ((isDescription) ? "tessellation evaluation" : "tessellation_evaluation_stage");
133 			break;
134 		}
135 	  default:
136 		desc << "unknown shader stage!";
137 		DE_FATAL("Unknown shader Stage!");
138 		break;
139 	}
140 
141 	return desc.str();
142 }
143 
getShaderFlagsStr(const VkShaderStageFlags flags)144 std::string getShaderFlagsStr (const VkShaderStageFlags	flags)
145 {
146 	std::ostringstream stream;
147 	bool empty = true;
148 	for (deUint32 b = 0; b < 8 * sizeof(flags); b++)
149 	{
150 		if (flags & (1u << b))
151 		{
152 			if (empty)
153 			{
154 				empty = false;
155 			}
156 			else
157 			{
158 				stream << ", ";
159 			}
160 
161 			stream << getShaderFlagStr((VkShaderStageFlagBits)(1u << b), true);
162 		}
163 	}
164 
165 	if (empty)
166 	{
167 		stream << "none";
168 	}
169 
170 	return stream.str();
171 }
172 
173 // helper classes
174 class ExecutablePropertiesTestParam
175 {
176 public:
177 								ExecutablePropertiesTestParam	(const VkShaderStageFlagBits*	shaders,
178 																 deUint32						count,
179 																 deBool							testStatistics,
180 																 deBool							testInternalRepresentations);
181 	virtual						~ExecutablePropertiesTestParam	(void);
182 	virtual const std::string	generateTestName				(void)			const;
183 	virtual const std::string	generateTestDescription			(void)			const;
getShaderFlag(deUint32 ndx) const184 	VkShaderStageFlagBits		getShaderFlag					(deUint32 ndx)	const	{ return m_shaders[ndx]; }
getShaderCount(void) const185 	deUint32					getShaderCount					(void)			const	{ return (deUint32)m_shaderCount; }
getTestStatistics(void) const186 	deBool						getTestStatistics				(void)			const	{ return m_testStatistics; }
getTestInternalRepresentations(void) const187 	deBool						getTestInternalRepresentations	(void)			const	{ return m_testInternalRepresentations; }
188 
189 protected:
190 	VkShaderStageFlagBits		m_shaders[VK_MAX_SHADER_STAGES];
191 	size_t						m_shaderCount;
192 	bool						m_testStatistics;
193 	bool						m_testInternalRepresentations;
194 };
195 
ExecutablePropertiesTestParam(const VkShaderStageFlagBits * shaders,deUint32 count,deBool testStatistics,deBool testInternalRepresentations)196 ExecutablePropertiesTestParam::ExecutablePropertiesTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, deBool testStatistics, deBool testInternalRepresentations)
197 {
198 	DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
199 	for (deUint32 ndx = 0; ndx < count; ndx++)
200 		m_shaders[ndx] = shaders[ndx];
201 	m_shaderCount					= count;
202 	m_testStatistics				= testStatistics;
203 	m_testInternalRepresentations	= testInternalRepresentations;
204 }
205 
~ExecutablePropertiesTestParam(void)206 ExecutablePropertiesTestParam::~ExecutablePropertiesTestParam (void)
207 {
208 }
209 
generateTestName(void) const210 const std::string ExecutablePropertiesTestParam::generateTestName (void) const
211 {
212 	std::string result(getShaderFlagStr(m_shaders[0], false));
213 
214 	for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
215 	{
216 		result += '_' + getShaderFlagStr(m_shaders[ndx], false);
217 	}
218 
219 	if (m_testStatistics)
220 	{
221 		result += "_statistics";
222 	}
223 
224 	if (m_testInternalRepresentations)
225 	{
226 		result += "_internal_representations";
227 	}
228 
229 	return result;
230 }
231 
generateTestDescription(void) const232 const std::string ExecutablePropertiesTestParam::generateTestDescription (void) const
233 {
234 	std::string result;
235 	if (m_testStatistics)
236 	{
237 		result += "Get pipeline executable statistics";
238 		if (m_testInternalRepresentations)
239 		{
240 			result += " and internal representations";
241 		}
242 	}
243 	else if (m_testInternalRepresentations)
244 	{
245 		result += "Get pipeline executable internal representations";
246 	}
247 	else
248 	{
249 		result += "Get pipeline executable properties";
250 	}
251 
252 	result += " with " + getShaderFlagStr(m_shaders[0], true);
253 
254 	return result;
255 }
256 
257 class SimpleGraphicsPipelineBuilder
258 {
259 public:
260 							SimpleGraphicsPipelineBuilder	(Context&						context);
~SimpleGraphicsPipelineBuilder(void)261 							~SimpleGraphicsPipelineBuilder	(void) { }
262 	void					bindShaderStage					(VkShaderStageFlagBits			stage,
263 															 const char*					sourceName,
264 															 const char*					entryName);
265 	void					enableTessellationStage			(deUint32						patchControlPoints);
266 	Move<VkPipeline>		buildPipeline					(tcu::UVec2						renderSize,
267 															 VkRenderPass					renderPass,
268 															 VkPipelineCache				cache,
269 															 VkPipelineLayout				pipelineLayout,
270 															 VkPipelineCreateFlags			flags);
271 	void					resetBuilder					(void);
272 
273 protected:
274 	Context&							m_context;
275 
276 	Move<VkShaderModule>				m_shaderModules[VK_MAX_SHADER_STAGES];
277 	deUint32							m_shaderStageCount;
278 	VkPipelineShaderStageCreateInfo	m_shaderStageInfo[VK_MAX_SHADER_STAGES];
279 
280 	deUint32							m_patchControlPoints;
281 };
282 
SimpleGraphicsPipelineBuilder(Context & context)283 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder (Context& context)
284 	: m_context(context)
285 {
286 	m_patchControlPoints = 0;
287 	m_shaderStageCount   = 0;
288 }
289 
resetBuilder(void)290 void SimpleGraphicsPipelineBuilder::resetBuilder (void)
291 {
292 	m_shaderStageCount = 0;
293 }
294 
bindShaderStage(VkShaderStageFlagBits stage,const char * sourceName,const char * entryName)295 void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits	stage,
296 													 const char*			sourceName,
297 													 const char*			entryName)
298 {
299 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
300 	const VkDevice			vkDevice	= m_context.getDevice();
301 
302 	// Create shader module
303 	deUint32*				code		= (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
304 	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
305 
306 	const VkShaderModuleCreateInfo moduleCreateInfo =
307 	{
308 		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,				// VkStructureType				sType;
309 		DE_NULL,													// const void*					pNext;
310 		0u,															// VkShaderModuleCreateFlags	flags;
311 		codeSize,													// deUintptr					codeSize;
312 		code,														// const deUint32*				pCode;
313 	};
314 
315 	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
316 
317 	// Prepare shader stage info
318 	m_shaderStageInfo[m_shaderStageCount].sType				= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
319 	m_shaderStageInfo[m_shaderStageCount].pNext				= DE_NULL;
320 	m_shaderStageInfo[m_shaderStageCount].flags				= 0u;
321 	m_shaderStageInfo[m_shaderStageCount].stage				= stage;
322 	m_shaderStageInfo[m_shaderStageCount].module				= *m_shaderModules[m_shaderStageCount];
323 	m_shaderStageInfo[m_shaderStageCount].pName				= entryName;
324 	m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo	= DE_NULL;
325 
326 	m_shaderStageCount++;
327 }
328 
buildPipeline(tcu::UVec2 renderSize,VkRenderPass renderPass,VkPipelineCache cache,VkPipelineLayout pipelineLayout,VkPipelineCreateFlags flags)329 Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass, VkPipelineCache cache,
330 															   VkPipelineLayout pipelineLayout, VkPipelineCreateFlags flags)
331 {
332 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
333 	const VkDevice				vkDevice			= m_context.getDevice();
334 
335 	// Create pipeline
336 	const VkVertexInputBindingDescription vertexInputBindingDescription =
337 	{
338 		0u,									// deUint32				binding;
339 		sizeof(Vertex4RGBA),				// deUint32				strideInBytes;
340 		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
341 	};
342 
343 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
344 	{
345 		{
346 			0u,									// deUint32 location;
347 			0u,									// deUint32 binding;
348 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
349 			0u									// deUint32 offsetInBytes;
350 		},
351 		{
352 			1u,									// deUint32 location;
353 			0u,									// deUint32 binding;
354 			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
355 			DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32 offsetInBytes;
356 		}
357 	};
358 
359 	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
360 	{
361 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
362 		DE_NULL,														// const void*								pNext;
363 		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
364 		1u,																// deUint32									vertexBindingDescriptionCount;
365 		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
366 		2u,																// deUint32									vertexAttributeDescriptionCount;
367 		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
368 	};
369 
370 	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
371 	{
372 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
373 		DE_NULL,														// const void*								pNext;
374 		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
375 		(m_patchControlPoints == 0 ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
376 								   : VK_PRIMITIVE_TOPOLOGY_PATCH_LIST), // VkPrimitiveTopology						topology;
377 		VK_FALSE,														// VkBool32									primitiveRestartEnable;
378 	};
379 
380 	const VkViewport	viewport	= makeViewport(renderSize);
381 	const VkRect2D		scissor	= makeRect2D(renderSize);
382 
383 	const VkPipelineViewportStateCreateInfo viewportStateParams =
384 	{
385 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
386 		DE_NULL,														// const void*							pNext;
387 		0u,																// VkPipelineViewportStateCreateFlags	flags;
388 		1u,																// deUint32								viewportCount;
389 		&viewport,														// const VkViewport*					pViewports;
390 		1u,																// deUint32								scissorCount;
391 		&scissor														// const VkRect2D*						pScissors;
392 	};
393 
394 	const VkPipelineRasterizationStateCreateInfo rasterStateParams =
395 	{
396 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
397 		DE_NULL,														// const void*								pNext;
398 		0u,																// VkPipelineRasterizationStateCreateFlags	flags;
399 		VK_FALSE,														// VkBool32									depthClampEnable;
400 		VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
401 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
402 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
403 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
404 		VK_FALSE,														// VkBool32									depthBiasEnable;
405 		0.0f,															// float									depthBiasConstantFactor;
406 		0.0f,															// float									depthBiasClamp;
407 		0.0f,															// float									depthBiasSlopeFactor;
408 		1.0f,															// float									lineWidth;
409 	};
410 
411 	const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
412 	{
413 		VK_FALSE,														// VkBool32		blendEnable;
414 		VK_BLEND_FACTOR_ONE,											// VkBlendFactor	srcColorBlendFactor;
415 		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor	dstColorBlendFactor;
416 		VK_BLEND_OP_ADD,												// VkBlendOp		colorBlendOp;
417 		VK_BLEND_FACTOR_ONE,											// VkBlendFactor	srcAlphaBlendFactor;
418 		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor	dstAlphaBlendFactor;
419 		VK_BLEND_OP_ADD,												// VkBlendOp		alphaBlendOp;
420 		VK_COLOR_COMPONENT_R_BIT |
421 		VK_COLOR_COMPONENT_G_BIT |
422 		VK_COLOR_COMPONENT_B_BIT |
423 		VK_COLOR_COMPONENT_A_BIT										// VkColorComponentFlags    colorWriteMask;
424 	};
425 
426 	const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
427 	{
428 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
429 		DE_NULL,													// const void*									pNext;
430 		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
431 		VK_FALSE,													// VkBool32										logicOpEnable;
432 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
433 		1u,															// deUint32										attachmentCount;
434 		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
435 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
436 	};
437 
438 	const VkPipelineMultisampleStateCreateInfo  multisampleStateParams	=
439 	{
440 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
441 		DE_NULL,													// const void*								pNext;
442 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
443 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
444 		VK_FALSE,													// VkBool32									sampleShadingEnable;
445 		0.0f,														// float									minSampleShading;
446 		DE_NULL,													// const VkSampleMask*						pSampleMask;
447 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
448 		VK_FALSE,													// VkBool32									alphaToOneEnable;
449 	};
450 
451 	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
452 	{
453 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType							sType;
454 		DE_NULL,													// const void*								pNext;
455 		0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
456 		VK_TRUE,													// VkBool32									depthTestEnable;
457 		VK_TRUE,													// VkBool32									depthWriteEnable;
458 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp;
459 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
460 		VK_FALSE,													// VkBool32									stencilTestEnable;
461 		// VkStencilOpState front;
462 		{
463 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
464 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
465 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
466 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
467 			0u,						// deUint32		compareMask;
468 			0u,						// deUint32		writeMask;
469 			0u,						// deUint32		reference;
470 		},
471 		// VkStencilOpState back;
472 		{
473 			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
474 			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
475 			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
476 			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
477 			0u,						// deUint32		compareMask;
478 			0u,						// deUint32		writeMask;
479 			0u,						// deUint32		reference;
480 		},
481 		0.0f,														// float									minDepthBounds;
482 		1.0f,														// float									maxDepthBounds;
483 	};
484 
485 	const VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
486 	{
487 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	// VkStructureType							sType;
488 		DE_NULL,													// const void*								pNext;
489 		0u,															// VkPipelineTesselationStateCreateFlags	flags;
490 		m_patchControlPoints,										// deUint32									patchControlPoints;
491 	};
492 	const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = (m_patchControlPoints > 0)
493 																  ? &tessStateCreateInfo
494 																  : DE_NULL;
495 
496 	const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
497 	{
498 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
499 		DE_NULL,											// const void*										pNext;
500 		flags,												// VkPipelineCreateFlags							flags;
501 		m_shaderStageCount,									// deUint32											stageCount;
502 		m_shaderStageInfo,									// const VkPipelineShaderStageCreateInfo*			pStages;
503 		&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
504 		&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
505 		pTessCreateInfo,									// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
506 		&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
507 		&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterState;
508 		&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
509 		&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
510 		&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
511 		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
512 		pipelineLayout,										// VkPipelineLayout									layout;
513 		renderPass,											// VkRenderPass										renderPass;
514 		0u,													// deUint32											subpass;
515 		DE_NULL,											// VkPipeline										basePipelineHandle;
516 		0,													// deInt32											basePipelineIndex;
517 	};
518 
519 	return createGraphicsPipeline(vk, vkDevice, cache, &graphicsPipelineParams, DE_NULL);
520 }
521 
enableTessellationStage(deUint32 patchControlPoints)522 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
523 {
524 	m_patchControlPoints = patchControlPoints;
525 }
526 
527 template <class Test>
newTestCase(tcu::TestContext & testContext,const ExecutablePropertiesTestParam * testParam)528 vkt::TestCase* newTestCase (tcu::TestContext&		testContext,
529 							const ExecutablePropertiesTestParam*	testParam)
530 {
531 	return new Test(testContext,
532 					testParam->generateTestName().c_str(),
533 					testParam->generateTestDescription().c_str(),
534 					testParam);
535 }
536 
537 // Test Classes
538 class ExecutablePropertiesTest : public vkt::TestCase
539 {
540 public:
ExecutablePropertiesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const ExecutablePropertiesTestParam * param)541 							ExecutablePropertiesTest(tcu::TestContext&		testContext,
542 										   const std::string&		name,
543 										   const std::string&		description,
544 										   const ExecutablePropertiesTestParam*	param)
545 								: vkt::TestCase (testContext, name, description)
546 								, m_param (*param)
547 								{ }
~ExecutablePropertiesTest(void)548 	virtual					~ExecutablePropertiesTest (void) { }
549 protected:
550 	const ExecutablePropertiesTestParam	m_param;
551 };
552 
553 class ExecutablePropertiesTestInstance : public vkt::TestInstance
554 {
555 public:
556 							ExecutablePropertiesTestInstance			(Context&				context,
557 															 const ExecutablePropertiesTestParam*	param);
558 	virtual					~ExecutablePropertiesTestInstance			(void);
559 	virtual tcu::TestStatus iterate							(void);
560 protected:
561 	virtual tcu::TestStatus verifyStatistics				(deUint32 binaryNdx);
562 	virtual tcu::TestStatus verifyInternalRepresentations	(deUint32 binaryNdx);
563 	virtual tcu::TestStatus verifyTestResult				(void);
564 protected:
565 	const ExecutablePropertiesTestParam*	m_param;
566 
567 	Move<VkPipelineCache>	m_cache;
568 	deBool					m_extensions;
569 
570 	Move<VkPipeline>		m_pipeline[PIPELINE_CACHE_NDX_COUNT];
571 };
572 
ExecutablePropertiesTestInstance(Context & context,const ExecutablePropertiesTestParam * param)573 ExecutablePropertiesTestInstance::ExecutablePropertiesTestInstance (Context&					context,
574 												const ExecutablePropertiesTestParam*	param)
575 	: TestInstance		(context)
576 	, m_param			(param)
577 	, m_extensions		(m_context.requireDeviceFunctionality("VK_KHR_pipeline_executable_properties"))
578 {
579 	const DeviceInterface&	vk				= m_context.getDeviceInterface();
580 	const VkDevice			vkDevice		= m_context.getDevice();
581 
582 	const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
583 	{
584 		VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,			// VkStructureType				sType;
585 		DE_NULL,												// const void*					pNext;
586 		0u,														// VkPipelineCacheCreateFlags	flags;
587 		0u,														// deUintptr					initialDataSize;
588 		DE_NULL,												// const void*					pInitialData;
589 	};
590 
591 	m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
592 }
593 
~ExecutablePropertiesTestInstance(void)594 ExecutablePropertiesTestInstance::~ExecutablePropertiesTestInstance (void)
595 {
596 }
597 
iterate(void)598 tcu::TestStatus ExecutablePropertiesTestInstance::iterate (void)
599 {
600 	return verifyTestResult();
601 }
602 
603 bool
checkString(const char * string,size_t size)604 checkString(const char *string, size_t size)
605 {
606 	size_t i = 0;
607 	for (; i < size; i++)
608 	{
609 		if (string[i] == 0)
610 		{
611 			break;
612 		}
613 	}
614 
615 	// The string needs to be non-empty and null terminated
616 	if (i == 0 || i >= size)
617 	{
618 		return false;
619 	}
620 
621 	return true;
622 }
623 
verifyStatistics(deUint32 executableNdx)624 tcu::TestStatus ExecutablePropertiesTestInstance::verifyStatistics (deUint32 executableNdx)
625 {
626 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
627 	const VkDevice				vkDevice	= m_context.getDevice();
628 	tcu::TestLog				&log		= m_context.getTestContext().getLog();
629 
630 	std::vector<VkPipelineExecutableStatisticKHR> statistics[PIPELINE_CACHE_NDX_COUNT];
631 
632 	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
633 	{
634 		const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
635 		{
636 			VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR,	// VkStructureType					sType;
637 			DE_NULL,										// const void*						pNext;
638 			*m_pipeline[ndx],								// VkPipeline						pipeline;
639 			executableNdx,									// uint32_t							executableIndex;
640 		};
641 
642 		deUint32 statisticCount = 0;
643 		VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, DE_NULL));
644 
645 		if (statisticCount == 0)
646 		{
647 			continue;
648 		}
649 
650 		statistics[ndx].resize(statisticCount);
651 		for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
652 		{
653 			deMemset(&statistics[ndx][statNdx], 0, sizeof(statistics[ndx][statNdx]));
654 			statistics[ndx][statNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
655 			statistics[ndx][statNdx].pNext = DE_NULL;
656 		}
657 		VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, &statistics[ndx][0]));
658 
659 		for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
660 		{
661 			if (!checkString(statistics[ndx][statNdx].name, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)))
662 			{
663 				return tcu::TestStatus::fail("Invalid statistic name string");
664 			}
665 
666 			for (deUint32 otherNdx = 0; otherNdx < statNdx; otherNdx++)
667 			{
668 				if (deMemCmp(statistics[ndx][statNdx].name, statistics[ndx][otherNdx].name,
669 							 DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)) == 0)
670 				{
671 					return tcu::TestStatus::fail("Statistic name string not unique within the executable");
672 				}
673 			}
674 
675 			if (!checkString(statistics[ndx][statNdx].description, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].description)))
676 			{
677 				return tcu::TestStatus::fail("Invalid statistic description string");
678 			}
679 
680 			if (statistics[ndx][statNdx].format == VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR)
681 			{
682 				if (statistics[ndx][statNdx].value.b32 != VK_TRUE && statistics[ndx][statNdx].value.b32 != VK_FALSE)
683 				{
684 					return tcu::TestStatus::fail("Boolean statistic is neither VK_TRUE nor VK_FALSE");
685 				}
686 			}
687 		}
688 	}
689 
690 	if (statistics[0].size() != statistics[1].size())
691 	{
692 		return tcu::TestStatus::fail("Identical pipelines have different numbers of statistics");
693 	}
694 
695 	if (statistics[0].size() == 0)
696 	{
697 		return tcu::TestStatus::pass("No statistics reported");
698 	}
699 
700 	// Both compiles had better have specified the same infos
701 	for (deUint32 statNdx0 = 0; statNdx0 < statistics[0].size(); statNdx0++)
702 	{
703 		deUint32 statNdx1 = 0;
704 		for (; statNdx1 < statistics[1].size(); statNdx1++)
705 		{
706 			if (deMemCmp(statistics[0][statNdx0].name, statistics[1][statNdx1].name,
707 						 DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].name)) == 0)
708 			{
709 				break;
710 			}
711 		}
712 		if (statNdx1 >= statistics[1].size())
713 		{
714 			return tcu::TestStatus::fail("Identical pipelines have different statistics");
715 		}
716 
717 		if (deMemCmp(statistics[0][statNdx0].description, statistics[1][statNdx1].description,
718 					 DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].description)) != 0)
719 		{
720 			return tcu::TestStatus::fail("Invalid binary description string");
721 		}
722 
723 		if (statistics[0][statNdx0].format != statistics[1][statNdx1].format)
724 		{
725 			return tcu::TestStatus::fail("Identical pipelines have statistics with different formats");
726 		}
727 
728 		switch (statistics[0][statNdx0].format)
729 		{
730 			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
731 			{
732 				bool match = statistics[0][statNdx0].value.b32 == statistics[1][statNdx1].value.b32;
733 				log << tcu::TestLog::Message
734 					<< statistics[0][statNdx0].name << ": "
735 					<< (statistics[0][statNdx0].value.b32 ? "VK_TRUE" : "VK_FALSE")
736 					<< (match ? "" : " (non-deterministic)")
737 					<< " (" << statistics[0][statNdx0].description << ")"
738 					<< tcu::TestLog::EndMessage;
739 				break;
740 			}
741 			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
742 			{
743 				bool match = statistics[0][statNdx0].value.i64 == statistics[1][statNdx1].value.i64;
744 				log << tcu::TestLog::Message
745 					<< statistics[0][statNdx0].name << ": "
746 					<< statistics[0][statNdx0].value.i64
747 					<< (match ? "" : " (non-deterministic)")
748 					<< " (" << statistics[0][statNdx0].description << ")"
749 					<< tcu::TestLog::EndMessage;
750 				break;
751 			}
752 			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
753 			{
754 				bool match = statistics[0][statNdx0].value.u64 == statistics[1][statNdx1].value.u64;
755 				log << tcu::TestLog::Message
756 					<< statistics[0][statNdx0].name << ": "
757 					<< statistics[0][statNdx0].value.u64
758 					<< (match ? "" : " (non-deterministic)")
759 					<< " (" << statistics[0][statNdx0].description << ")"
760 					<< tcu::TestLog::EndMessage;
761 				break;
762 			}
763 			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
764 			{
765 				bool match = statistics[0][statNdx0].value.f64 == statistics[1][statNdx1].value.f64;
766 				log << tcu::TestLog::Message
767 					<< statistics[0][statNdx0].name << ": "
768 					<< statistics[0][statNdx0].value.f64
769 					<< (match ? "" : " (non-deterministic)")
770 					<< " (" << statistics[0][statNdx0].description << ")"
771 					<< tcu::TestLog::EndMessage;
772 				break;
773 			}
774 			default:
775 				return tcu::TestStatus::fail("Invalid statistic format");
776 		}
777 	}
778 
779 	return tcu::TestStatus::pass("Pass");
780 }
781 
verifyInternalRepresentations(deUint32 executableNdx)782 tcu::TestStatus ExecutablePropertiesTestInstance::verifyInternalRepresentations (deUint32 executableNdx)
783 {
784 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
785 	const VkDevice				vkDevice	= m_context.getDevice();
786 	tcu::TestLog				&log		= m_context.getTestContext().getLog();
787 
788 	// We only care about internal representations on the second pipeline.
789 	// We still compile twice to ensure that we still get the right thing
790 	// even if the pipeline is hot in the cache.
791 	const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
792 	{
793 		VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR,	// VkStructureType					sType;
794 		DE_NULL,										// const void*						pNext;
795 		*m_pipeline[1],									// VkPipeline						pipeline;
796 		executableNdx,									// uint32_t							executableIndex;
797 	};
798 
799 	std::vector<VkPipelineExecutableInternalRepresentationKHR> irs;
800 	std::vector<std::vector<deUint8>> irDatas;
801 
802 	deUint32 irCount = 0;
803 	VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, DE_NULL));
804 
805 	if (irCount == 0)
806 	{
807 		return tcu::TestStatus::pass("No internal representations reported");
808 	}
809 
810 	irs.resize(irCount);
811 	irDatas.resize(irCount);
812 	for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
813 	{
814 		deMemset(&irs[irNdx], 0, sizeof(irs[irNdx]));
815 		irs[irNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR;
816 		irs[irNdx].pNext = DE_NULL;
817 	}
818 	VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));
819 
820 	for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
821 	{
822 		if (!checkString(irs[irNdx].name, DE_LENGTH_OF_ARRAY(irs[irNdx].name)))
823 		{
824 			return tcu::TestStatus::fail("Invalid internal representation name string");
825 		}
826 
827 		for (deUint32 otherNdx = 0; otherNdx < irNdx; otherNdx++)
828 		{
829 			if (deMemCmp(irs[irNdx].name, irs[otherNdx].name,
830 						 DE_LENGTH_OF_ARRAY(irs[irNdx].name)) == 0)
831 			{
832 				return tcu::TestStatus::fail("Internal representation name string not unique within the executable");
833 			}
834 		}
835 
836 		if (!checkString(irs[irNdx].description, DE_LENGTH_OF_ARRAY(irs[irNdx].description)))
837 		{
838 			return tcu::TestStatus::fail("Invalid binary description string");
839 		}
840 
841 		if (irs[irNdx].dataSize == 0)
842 		{
843 			return tcu::TestStatus::fail("Internal representation has no data");
844 		}
845 
846 		irDatas[irNdx].resize(irs[irNdx].dataSize);
847 		irs[irNdx].pData = &irDatas[irNdx][0];
848 		if (irs[irNdx].isText)
849 		{
850 			// For binary data the size is important.  We check that the
851 			// implementation fills the whole buffer by filling it with
852 			// garbage first and then looking for that same garbage later.
853 			for (size_t i = 0; i < irs[irNdx].dataSize; i++)
854 			{
855 				irDatas[irNdx][i] = (deUint8)(37 * (17 + i));
856 			}
857 		}
858 	}
859 
860 	VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));
861 
862 	for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
863 	{
864 		if (irs[irNdx].isText)
865 		{
866 			if (!checkString((char *)irs[irNdx].pData, irs[irNdx].dataSize))
867 			{
868 				return tcu::TestStatus::fail("Textual internal representation isn't a valid string");
869 			}
870 			log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
871 				<< tcu::LogKernelSource((char *)irs[irNdx].pData)
872 				<< tcu::TestLog::EndSection;
873 		}
874 		else
875 		{
876 			size_t maxMatchingChunkSize = 0;
877 			size_t matchingChunkSize = 0;
878 			for (size_t i = 0; i < irs[irNdx].dataSize; i++)
879 			{
880 				if (irDatas[irNdx][i] == (deUint8)(37 * (17 + i)))
881 				{
882 					matchingChunkSize++;
883 					if (matchingChunkSize > maxMatchingChunkSize)
884 					{
885 						maxMatchingChunkSize = matchingChunkSize;
886 					}
887 				}
888 				else
889 				{
890 					matchingChunkSize = 0;
891 				}
892 			}
893 
894 			// 64 bytes of our random data still being in the buffer probably
895 			// isn't a coincidence
896 			if (matchingChunkSize == irs[irNdx].dataSize || matchingChunkSize >= 64)
897 			{
898 				return tcu::TestStatus::fail("Implementation didn't fill the whole internal representation data buffer");
899 			}
900 
901 			log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
902 				<< tcu::TestLog::Message << "Received " << irs[irNdx].dataSize << "B of binary data" << tcu::TestLog::EndMessage
903 				<< tcu::TestLog::EndSection;
904 		}
905 	}
906 
907 	return tcu::TestStatus::pass("Pass");
908 }
909 
verifyTestResult(void)910 tcu::TestStatus ExecutablePropertiesTestInstance::verifyTestResult (void)
911 {
912 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
913 	const VkDevice				vkDevice	= m_context.getDevice();
914 	tcu::TestLog				&log		= m_context.getTestContext().getLog();
915 
916 	std::vector<VkPipelineExecutablePropertiesKHR> props[PIPELINE_CACHE_NDX_COUNT];
917 
918 	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
919 	{
920 		const VkPipelineInfoKHR pipelineInfo =
921 		{
922 			VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR,	// VkStructureType					sType;
923 			DE_NULL,								// const void*						pNext;
924 			*m_pipeline[ndx],						// VkPipeline						pipeline;
925 
926 		};
927 		deUint32 executableCount = 0;
928 		VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, DE_NULL));
929 
930 		if (executableCount == 0)
931 		{
932 			continue;
933 		}
934 
935 		props[ndx].resize(executableCount);
936 		for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
937 		{
938 			deMemset(&props[ndx][execNdx], 0, sizeof(props[ndx][execNdx]));
939 			props[ndx][execNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
940 			props[ndx][execNdx].pNext = DE_NULL;
941 		}
942 		VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, &props[ndx][0]));
943 
944 		for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
945 		{
946 			if (!checkString(props[ndx][execNdx].name, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)))
947 			{
948 				return tcu::TestStatus::fail("Invalid binary name string");
949 			}
950 
951 			for (deUint32 otherNdx = 0; otherNdx < execNdx; otherNdx++)
952 			{
953 				if (deMemCmp(props[ndx][execNdx].name, props[ndx][otherNdx].name,
954 							 DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)) == 0)
955 				{
956 					return tcu::TestStatus::fail("Binary name string not unique within the pipeline");
957 				}
958 			}
959 
960 			if (!checkString(props[ndx][execNdx].description, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].description)))
961 			{
962 				return tcu::TestStatus::fail("Invalid binary description string");
963 			}
964 
965 			// Check that the binary only contains stages actually used to
966 			// compile the pipeline
967 			VkShaderStageFlags stages = props[ndx][execNdx].stages;
968 			for (deUint32 stageNdx = 0; stageNdx < m_param->getShaderCount(); stageNdx++)
969 			{
970 				stages &= ~m_param->getShaderFlag(stageNdx);
971 			}
972 			if (stages != 0)
973 			{
974 				return tcu::TestStatus::fail("Binary uses unprovided stage");
975 			}
976 		}
977 	}
978 
979 	if (props[0].size() != props[1].size())
980 	{
981 		return tcu::TestStatus::fail("Identical pipelines have different numbers of props");
982 	}
983 
984 	if (props[0].size() == 0)
985 	{
986 		return tcu::TestStatus::pass("No executables reported");
987 	}
988 
989 	// Both compiles had better have specified the same infos
990 	for (deUint32 execNdx0 = 0; execNdx0 < props[0].size(); execNdx0++)
991 	{
992 		deUint32 execNdx1 = 0;
993 		for (; execNdx1 < props[1].size(); execNdx1++)
994 		{
995 			if (deMemCmp(props[0][execNdx0].name, props[1][execNdx1].name,
996 						 DE_LENGTH_OF_ARRAY(props[0][execNdx0].name)) == 0)
997 			{
998 				break;
999 			}
1000 		}
1001 		if (execNdx1 >= props[1].size())
1002 		{
1003 			return tcu::TestStatus::fail("Identical pipelines have different sets of executables");
1004 		}
1005 
1006 		if (deMemCmp(props[0][execNdx0].description, props[1][execNdx1].description,
1007 					 DE_LENGTH_OF_ARRAY(props[0][execNdx0].description)) != 0)
1008 		{
1009 			return tcu::TestStatus::fail("Same binary has different descriptions");
1010 		}
1011 
1012 		if (props[0][execNdx0].stages != props[1][execNdx1].stages)
1013 		{
1014 			return tcu::TestStatus::fail("Same binary has different stages");
1015 		}
1016 
1017 		if (props[0][execNdx0].subgroupSize != props[1][execNdx1].subgroupSize)
1018 		{
1019 			return tcu::TestStatus::fail("Same binary has different subgroup sizes");
1020 		}
1021 	}
1022 
1023 	log << tcu::TestLog::Section("Binaries", "Binaries reported for this pipeline");
1024 	log << tcu::TestLog::Message << "Pipeline reported " << props[0].size() << " props" << tcu::TestLog::EndMessage;
1025 
1026 	tcu::TestStatus status = tcu::TestStatus::pass("Pass");
1027 	for (deUint32 execNdx = 0; execNdx < props[0].size(); execNdx++)
1028 	{
1029 		log << tcu::TestLog::Section(props[0][execNdx].name, props[0][execNdx].description);
1030 		log << tcu::TestLog::Message << "Name: " << props[0][execNdx].name << tcu::TestLog::EndMessage;
1031 		log << tcu::TestLog::Message << "Description: " << props[0][execNdx].description << tcu::TestLog::EndMessage;
1032 		log << tcu::TestLog::Message << "Stages: " << getShaderFlagsStr(props[0][execNdx].stages) << tcu::TestLog::EndMessage;
1033 		log << tcu::TestLog::Message << "Subgroup Size: " << props[0][execNdx].subgroupSize << tcu::TestLog::EndMessage;
1034 
1035 		if (m_param->getTestStatistics())
1036 		{
1037 			status = verifyStatistics(execNdx);
1038 			if (status.getCode() != QP_TEST_RESULT_PASS)
1039 			{
1040 				log << tcu::TestLog::EndSection;
1041 				break;
1042 			}
1043 		}
1044 
1045 		if (m_param->getTestInternalRepresentations())
1046 		{
1047 			status = verifyInternalRepresentations(execNdx);
1048 			if (status.getCode() != QP_TEST_RESULT_PASS)
1049 			{
1050 				log << tcu::TestLog::EndSection;
1051 				break;
1052 			}
1053 		}
1054 
1055 		log << tcu::TestLog::EndSection;
1056 	}
1057 
1058 	log << tcu::TestLog::EndSection;
1059 
1060 	return status;
1061 }
1062 
1063 class GraphicsExecutablePropertiesTest : public ExecutablePropertiesTest
1064 {
1065 public:
GraphicsExecutablePropertiesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const ExecutablePropertiesTestParam * param)1066 							GraphicsExecutablePropertiesTest	(tcu::TestContext&		testContext,
1067 													 const std::string&	name,
1068 													 const std::string&	description,
1069 													 const ExecutablePropertiesTestParam*	param)
1070 								: ExecutablePropertiesTest (testContext, name, description, param)
1071 								{ }
~GraphicsExecutablePropertiesTest(void)1072 	virtual					~GraphicsExecutablePropertiesTest	(void) { }
1073 	virtual void			initPrograms		(SourceCollections&	programCollection) const;
1074 	virtual TestInstance*	createInstance		(Context&				context) const;
1075 };
1076 
1077 class GraphicsExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
1078 {
1079 public:
1080 							GraphicsExecutablePropertiesTestInstance	(Context&				context,
1081 															 const ExecutablePropertiesTestParam*	param);
1082 	virtual					~GraphicsExecutablePropertiesTestInstance	(void);
1083 protected:
1084 	const tcu::UVec2					m_renderSize;
1085 	const VkFormat						m_colorFormat;
1086 	const VkFormat						m_depthFormat;
1087 	Move<VkPipelineLayout>				m_pipelineLayout;
1088 
1089 	SimpleGraphicsPipelineBuilder		m_pipelineBuilder;
1090 	SimpleGraphicsPipelineBuilder		m_missPipelineBuilder;
1091 	Move<VkRenderPass>					m_renderPass;
1092 };
1093 
initPrograms(SourceCollections & programCollection) const1094 void GraphicsExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
1095 {
1096 	for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
1097 	{
1098 		switch(m_param.getShaderFlag(shaderNdx))
1099 		{
1100 		case VK_SHADER_STAGE_VERTEX_BIT:
1101 			programCollection.glslSources.add("color_vert") << glu::VertexSource(
1102 						"#version 310 es\n"
1103 						"layout(location = 0) in vec4 position;\n"
1104 						"layout(location = 1) in vec4 color;\n"
1105 						"layout(location = 0) out highp vec4 vtxColor;\n"
1106 						"void main (void)\n"
1107 						"{\n"
1108 						"  gl_Position = position;\n"
1109 						"  vtxColor = color;\n"
1110 						"}\n");
1111 					break;
1112 		case VK_SHADER_STAGE_FRAGMENT_BIT:
1113 			programCollection.glslSources.add("color_frag") << glu::FragmentSource(
1114 						"#version 310 es\n"
1115 						"layout(location = 0) in highp vec4 vtxColor;\n"
1116 						"layout(location = 0) out highp vec4 fragColor;\n"
1117 						"void main (void)\n"
1118 						"{\n"
1119 						"  fragColor = vtxColor;\n"
1120 						"}\n");
1121 			break;
1122 
1123 		case VK_SHADER_STAGE_GEOMETRY_BIT:
1124 			programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1125 						"#version 450 \n"
1126 						"layout(triangles) in;\n"
1127 						"layout(triangle_strip, max_vertices = 3) out;\n"
1128 						"layout(location = 0) in highp vec4 in_vtxColor[];\n"
1129 						"layout(location = 0) out highp vec4 vtxColor;\n"
1130 						"out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
1131 						"in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[];\n"
1132 						"void main (void)\n"
1133 						"{\n"
1134 						"  for(int ndx=0; ndx<3; ndx++)\n"
1135 						"  {\n"
1136 						"    gl_Position = gl_in[ndx].gl_Position;\n"
1137 						"    gl_PointSize = gl_in[ndx].gl_PointSize;\n"
1138 						"    vtxColor    = in_vtxColor[ndx];\n"
1139 						"    EmitVertex();\n"
1140 						"  }\n"
1141 						"  EndPrimitive();\n"
1142 						"}\n");
1143 			break;
1144 
1145 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1146 			programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1147 						"#version 450 \n"
1148 						"layout(vertices = 3) out;\n"
1149 						"layout(location = 0) in highp vec4 color[];\n"
1150 						"layout(location = 0) out highp vec4 vtxColor[];\n"
1151 						"out gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_out[3];\n"
1152 						"in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
1153 						"void main()\n"
1154 						"{\n"
1155 						"  gl_TessLevelOuter[0] = 4.0;\n"
1156 						"  gl_TessLevelOuter[1] = 4.0;\n"
1157 						"  gl_TessLevelOuter[2] = 4.0;\n"
1158 						"  gl_TessLevelInner[0] = 4.0;\n"
1159 						"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1160 						"  gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
1161 						"  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1162 						"}\n");
1163 					break;
1164 
1165 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1166 					programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1167 						"#version 450 \n"
1168 						"layout(triangles, fractional_even_spacing, ccw) in;\n"
1169 						"layout(location = 0) in highp vec4 colors[];\n"
1170 						"layout(location = 0) out highp vec4 vtxColor;\n"
1171 						"out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
1172 						"in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
1173 						"void main() \n"
1174 						"{\n"
1175 						"  float u = gl_TessCoord.x;\n"
1176 						"  float v = gl_TessCoord.y;\n"
1177 						"  float w = gl_TessCoord.z;\n"
1178 						"  vec4 pos = vec4(0);\n"
1179 						"  vec4 color = vec4(0);\n"
1180 						"  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1181 						"  color.xyz += u * colors[0].xyz;\n"
1182 						"  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1183 						"  color.xyz += v * colors[1].xyz;\n"
1184 						"  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1185 						"  color.xyz += w * colors[2].xyz;\n"
1186 						"  pos.w = 1.0;\n"
1187 						"  color.w = 1.0;\n"
1188 						"  gl_Position = pos;\n"
1189 						"  gl_PointSize = gl_in[0].gl_PointSize;"
1190 						"  vtxColor = color;\n"
1191 						"}\n");
1192 					break;
1193 
1194 				default:
1195 					DE_FATAL("Unknown Shader Stage!");
1196 					break;
1197 		}
1198 	}
1199 }
1200 
createInstance(Context & context) const1201 TestInstance* GraphicsExecutablePropertiesTest::createInstance (Context& context) const
1202 {
1203 	return new GraphicsExecutablePropertiesTestInstance(context, &m_param);
1204 }
1205 
GraphicsExecutablePropertiesTestInstance(Context & context,const ExecutablePropertiesTestParam * param)1206 GraphicsExecutablePropertiesTestInstance::GraphicsExecutablePropertiesTestInstance (Context&					context,
1207 																const ExecutablePropertiesTestParam*	param)
1208 	: ExecutablePropertiesTestInstance		(context, param)
1209 	, m_renderSize			(32u, 32u)
1210 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
1211 	, m_depthFormat			(VK_FORMAT_D16_UNORM)
1212 	, m_pipelineBuilder		(context)
1213 	, m_missPipelineBuilder	(context)
1214 {
1215 	const DeviceInterface&	vk				= m_context.getDeviceInterface();
1216 	const VkDevice			vkDevice		= m_context.getDevice();
1217 
1218 	// Create pipeline layout
1219 	{
1220 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1221 		{
1222 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
1223 			DE_NULL,											// const void*						pNext;
1224 			0u,													// VkPipelineLayoutCreateFlags		flags;
1225 			0u,													// deUint32							setLayoutCount;
1226 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
1227 			0u,													// deUint32							pushConstantRangeCount;
1228 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
1229 		};
1230 
1231 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1232 	}
1233 
1234 	// Create render pass
1235 	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
1236 
1237 	// Bind shader stages
1238 
1239 	VkPhysicalDeviceFeatures	features = m_context.getDeviceFeatures();
1240 	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1241 	{
1242 		for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
1243 		{
1244 			switch(m_param->getShaderFlag(shaderNdx))
1245 			{
1246 			case VK_SHADER_STAGE_VERTEX_BIT:
1247 				m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
1248 				break;
1249 			case VK_SHADER_STAGE_FRAGMENT_BIT:
1250 				m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
1251 				break;
1252 			case VK_SHADER_STAGE_GEOMETRY_BIT:
1253 				if (features.geometryShader == VK_FALSE)
1254 				{
1255 					TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1256 				}
1257 				else
1258 				{
1259 					m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
1260 				}
1261 				break;
1262 			case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1263 				if (features.tessellationShader == VK_FALSE)
1264 				{
1265 					TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1266 				}
1267 				else
1268 				{
1269 					m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
1270 					m_pipelineBuilder.enableTessellationStage(3);
1271 				}
1272 				break;
1273 			case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1274 				if (features.tessellationShader == VK_FALSE)
1275 				{
1276 					TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1277 				}
1278 				else
1279 				{
1280 					m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
1281 					m_pipelineBuilder.enableTessellationStage(3);
1282 				}
1283 				break;
1284 			default:
1285 				DE_FATAL("Unknown Shader Stage!");
1286 				break;
1287 			}
1288 
1289 		}
1290 
1291 		VkPipelineCreateFlags flags = 0;
1292 		if (param->getTestStatistics())
1293 		{
1294 			flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
1295 		}
1296 
1297 		// Only check gather internal representations on the second
1298 		// pipeline.  This way, it's more obvious if they failed to capture
1299 		// due to the pipeline being cached.
1300 		if (ndx == PIPELINE_CACHE_NDX_CACHED && param->getTestInternalRepresentations())
1301 		{
1302 			flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1303 		}
1304 
1305 		m_pipeline[ndx] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout, flags);
1306 		m_pipelineBuilder.resetBuilder();
1307 	}
1308 }
1309 
~GraphicsExecutablePropertiesTestInstance(void)1310 GraphicsExecutablePropertiesTestInstance::~GraphicsExecutablePropertiesTestInstance (void)
1311 {
1312 }
1313 
1314 class ComputeExecutablePropertiesTest : public ExecutablePropertiesTest
1315 {
1316 public:
ComputeExecutablePropertiesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const ExecutablePropertiesTestParam * param)1317 							ComputeExecutablePropertiesTest	(tcu::TestContext&		testContext,
1318 													 const std::string&		name,
1319 													 const std::string&		description,
1320 													 const ExecutablePropertiesTestParam*	param)
1321 								: ExecutablePropertiesTest	(testContext, name, description, param)
1322 								{ }
~ComputeExecutablePropertiesTest(void)1323 	virtual					~ComputeExecutablePropertiesTest	(void) { }
1324 	virtual void			initPrograms			(SourceCollections&	programCollection) const;
1325 	virtual TestInstance*	createInstance			(Context&				context) const;
1326 };
1327 
1328 class ComputeExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
1329 {
1330 public:
1331 							ComputeExecutablePropertiesTestInstance	(Context&				context,
1332 															 const ExecutablePropertiesTestParam*	param);
1333 	virtual					~ComputeExecutablePropertiesTestInstance	(void);
1334 protected:
1335 	void					buildDescriptorSets				(deUint32 ndx);
1336 	void					buildShader						(deUint32 ndx);
1337 	void					buildPipeline					(deUint32 ndx);
1338 protected:
1339 	Move<VkBuffer>					m_inputBuf;
1340 	de::MovePtr<Allocation>			m_inputBufferAlloc;
1341 	Move<VkShaderModule>			m_computeShaderModule[PIPELINE_CACHE_NDX_COUNT];
1342 
1343 	Move<VkBuffer>					m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
1344 	de::MovePtr<Allocation>			m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
1345 
1346 	Move<VkDescriptorPool>			m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
1347 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
1348 	Move<VkDescriptorSet>			m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
1349 
1350 	Move<VkPipelineLayout>			m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
1351 };
1352 
initPrograms(SourceCollections & programCollection) const1353 void ComputeExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
1354 {
1355 	programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1356 		"#version 310 es\n"
1357 		"layout(local_size_x = 1) in;\n"
1358 		"layout(std430) buffer;\n"
1359 		"layout(binding = 0) readonly buffer Input0\n"
1360 		"{\n"
1361 		"  vec4 elements[];\n"
1362 		"} input_data0;\n"
1363 		"layout(binding = 1) writeonly buffer Output\n"
1364 		"{\n"
1365 		"  vec4 elements[];\n"
1366 		"} output_data;\n"
1367 		"void main()\n"
1368 		"{\n"
1369 		"  uint ident = gl_GlobalInvocationID.x;\n"
1370 		"  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1371 		"}");
1372 }
1373 
createInstance(Context & context) const1374 TestInstance* ComputeExecutablePropertiesTest::createInstance (Context& context) const
1375 {
1376 	return new ComputeExecutablePropertiesTestInstance(context, &m_param);
1377 }
1378 
buildDescriptorSets(deUint32 ndx)1379 void ComputeExecutablePropertiesTestInstance::buildDescriptorSets (deUint32 ndx)
1380 {
1381 	const DeviceInterface&	vk				= m_context.getDeviceInterface();
1382 	const VkDevice			vkDevice		= m_context.getDevice();
1383 
1384 	// Create descriptor set layout
1385 	DescriptorSetLayoutBuilder descLayoutBuilder;
1386 	for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1387 		descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1388 	m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
1389 }
1390 
buildShader(deUint32 ndx)1391 void ComputeExecutablePropertiesTestInstance::buildShader (deUint32 ndx)
1392 {
1393 	const DeviceInterface&	vk				= m_context.getDeviceInterface();
1394 	const VkDevice			vkDevice		= m_context.getDevice();
1395 
1396 	// Create compute shader
1397 	VkShaderModuleCreateInfo shaderModuleCreateInfo =
1398 	{
1399 		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,									// VkStructureType				sType;
1400 		DE_NULL,																		// const void*					pNext;
1401 		0u,																				// VkShaderModuleCreateFlags	flags;
1402 		m_context.getBinaryCollection().get("basic_compute").getSize(),					// deUintptr					codeSize;
1403 		(deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),	// const deUint32*				pCode;
1404 	};
1405 	m_computeShaderModule[ndx] = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1406 }
1407 
buildPipeline(deUint32 ndx)1408 void ComputeExecutablePropertiesTestInstance::buildPipeline (deUint32 ndx)
1409 {
1410 	const DeviceInterface&	vk				 = m_context.getDeviceInterface();
1411 	const VkDevice			vkDevice		 = m_context.getDevice();
1412 
1413 	// Create compute pipeline layout
1414 	const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1415 	{
1416 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,					// VkStructureType					sType;
1417 		DE_NULL,														// const void*						pNext;
1418 		0u,																// VkPipelineLayoutCreateFlags		flags;
1419 		1u,																// deUint32							setLayoutCount;
1420 		&m_descriptorSetLayout[ndx].get(),								// const VkDescriptorSetLayout*		pSetLayouts;
1421 		0u,																// deUint32							pushConstantRangeCount;
1422 		DE_NULL,														// const VkPushConstantRange*		pPushConstantRanges;
1423 	};
1424 
1425 	m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1426 
1427 	const VkPipelineShaderStageCreateInfo stageCreateInfo =
1428 	{
1429 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,			// VkStructureType					sType;
1430 		DE_NULL,														// const void*						pNext;
1431 		0u,																// VkPipelineShaderStageCreateFlags	flags;
1432 		VK_SHADER_STAGE_COMPUTE_BIT,									// VkShaderStageFlagBits			stage;
1433 		*m_computeShaderModule[ndx],									// VkShaderModule					module;
1434 		"main",															// const char*						pName;
1435 		DE_NULL,														// const VkSpecializationInfo*		pSpecializationInfo;
1436 	};
1437 
1438 	VkPipelineCreateFlags flags = 0;
1439 	if (m_param->getTestStatistics())
1440 	{
1441 		flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
1442 	}
1443 
1444 	// Only check gather internal representations on the second
1445 	// pipeline.  This way, it's more obvious if they failed to capture
1446 	// due to the pipeline being cached.
1447 	if (ndx == PIPELINE_CACHE_NDX_CACHED && m_param->getTestInternalRepresentations())
1448 	{
1449 		flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1450 	}
1451 
1452 	const VkComputePipelineCreateInfo pipelineCreateInfo =
1453 	{
1454 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,				// VkStructureType					sType;
1455 		DE_NULL,													// const void*						pNext;
1456 		flags,														// VkPipelineCreateFlags			flags;
1457 		stageCreateInfo,											// VkPipelineShaderStageCreateInfo	stage;
1458 		*m_pipelineLayout[ndx],										// VkPipelineLayout					layout;
1459 		(VkPipeline)0,												// VkPipeline						basePipelineHandle;
1460 		0u,															// deInt32							basePipelineIndex;
1461 	};
1462 
1463 	m_pipeline[ndx] = createComputePipeline(vk, vkDevice, *m_cache, &pipelineCreateInfo, DE_NULL);
1464 }
1465 
ComputeExecutablePropertiesTestInstance(Context & context,const ExecutablePropertiesTestParam * param)1466 ComputeExecutablePropertiesTestInstance::ComputeExecutablePropertiesTestInstance (Context&				context,
1467 													const ExecutablePropertiesTestParam*	param)
1468 	: ExecutablePropertiesTestInstance (context, param)
1469 {
1470 	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1471 	{
1472 		buildDescriptorSets(ndx);
1473 		buildShader(ndx);
1474 		buildPipeline(ndx);
1475 	}
1476 }
1477 
~ComputeExecutablePropertiesTestInstance(void)1478 ComputeExecutablePropertiesTestInstance::~ComputeExecutablePropertiesTestInstance (void)
1479 {
1480 }
1481 
1482 } // anonymous
1483 
createExecutablePropertiesTests(tcu::TestContext & testCtx)1484 tcu::TestCaseGroup* createExecutablePropertiesTests (tcu::TestContext& testCtx)
1485 {
1486 
1487 	de::MovePtr<tcu::TestCaseGroup> binaryInfoTests (new tcu::TestCaseGroup(testCtx, "executable_properties", "pipeline binary statistics tests"));
1488 
1489 	// Graphics Pipeline Tests
1490 	{
1491 		de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics", "Test pipeline binary info with graphics pipeline."));
1492 
1493 		const VkShaderStageFlagBits testParamShaders0[] =
1494 		{
1495 			VK_SHADER_STAGE_VERTEX_BIT,
1496 			VK_SHADER_STAGE_FRAGMENT_BIT,
1497 		};
1498 		const VkShaderStageFlagBits testParamShaders1[] =
1499 		{
1500 			VK_SHADER_STAGE_VERTEX_BIT,
1501 			VK_SHADER_STAGE_GEOMETRY_BIT,
1502 			VK_SHADER_STAGE_FRAGMENT_BIT,
1503 		};
1504 		const VkShaderStageFlagBits testParamShaders2[] =
1505 		{
1506 			VK_SHADER_STAGE_VERTEX_BIT,
1507 			VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1508 			VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1509 			VK_SHADER_STAGE_FRAGMENT_BIT,
1510 		};
1511 		const ExecutablePropertiesTestParam testParams[] =
1512 		{
1513 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1514 			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_FALSE),
1515 			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_FALSE),
1516 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1517 			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_FALSE),
1518 			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_FALSE),
1519 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1520 			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_TRUE),
1521 			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_TRUE),
1522 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
1523 			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_TRUE),
1524 			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_TRUE),
1525 		};
1526 
1527 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1528 			graphicsTests->addChild(newTestCase<GraphicsExecutablePropertiesTest>(testCtx, &testParams[i]));
1529 
1530 		binaryInfoTests->addChild(graphicsTests.release());
1531 	}
1532 
1533 	// Compute Pipeline Tests
1534 	{
1535 		de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute", "Test pipeline binary info with compute pipeline."));
1536 
1537 		const VkShaderStageFlagBits testParamShaders0[] =
1538 		{
1539 			VK_SHADER_STAGE_COMPUTE_BIT,
1540 		};
1541 		const ExecutablePropertiesTestParam testParams[] =
1542 		{
1543 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1544 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1545 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1546 			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
1547 		};
1548 
1549 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1550 			computeTests->addChild(newTestCase<ComputeExecutablePropertiesTest>(testCtx, &testParams[i]));
1551 
1552 		binaryInfoTests->addChild(computeTests.release());
1553 	}
1554 
1555 	return binaryInfoTests.release();
1556 }
1557 
1558 } // pipeline
1559 
1560 } // vkt
1561