• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2023 LunarG, Inc.
6  * Copyright (c) 2023 Nintendo
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 Shader Object Binary Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktShaderObjectBinaryTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vktShaderObjectCreateUtil.hpp"
30 #include "vktCustomInstancesDevices.hpp"
31 #include "tcuTestLog.hpp"
32 #include "deRandom.hpp"
33 #include "tcuCommandLine.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 
37 #include <cmath>
38 
39 namespace vkt
40 {
41 namespace ShaderObject
42 {
43 
44 namespace {
45 
46 enum QueryType {
47 	SAME_SHADER,
48 	NEW_SHADER,
49 	SHADER_FROM_BINARY,
50 	NEW_DEVICE,
51 	DEVICE_NO_EXTS_FEATURES,
52 	ALL_FEATURE_COMBINATIONS,
53 };
54 
55 struct TestParams {
56 	vk::VkShaderStageFlagBits	stage;
57 	bool						linked;
58 	QueryType					queryType;
59 };
60 
61 enum IncompleteBinaryTestType
62 {
63 	HALF_DATA_SIZE,
64 	GARBAGE_DATA,
65 	GARBAGE_SECOND_HALF,
66 	CREATE_FROM_HALF_SIZE,
67 	CREATE_FROM_HALF_SIZE_GARBAGE,
68 };
69 
getNextStage(vk::VkShaderStageFlagBits shaderStage,bool tessellationShaderFeature,bool geometryShaderFeature)70 vk::VkShaderStageFlags getNextStage (vk::VkShaderStageFlagBits shaderStage, bool tessellationShaderFeature, bool geometryShaderFeature)
71 {
72 	if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
73 	{
74 		if (tessellationShaderFeature)
75 			return vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
76 		else if (geometryShaderFeature)
77 			return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
78 		return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
79 	}
80 	else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
81 	{
82 		return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
83 	}
84 	else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
85 	{
86 		if (geometryShaderFeature)
87 			return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
88 		return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
89 	}
90 	else if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
91 	{
92 		return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
93 	}
94 	return 0u;
95 }
96 
createShader(const vk::DeviceInterface & vk,const vk::BinaryCollection & binaries,const vk::VkDevice device,vk::VkPhysicalDeviceFeatures features,vk::VkDescriptorSetLayout descriptorSetLayout,bool linked,vk::VkShaderStageFlagBits stage)97 vk::Move<vk::VkShaderEXT> createShader (const vk::DeviceInterface& vk, const vk::BinaryCollection& binaries, const vk::VkDevice device, vk::VkPhysicalDeviceFeatures features, vk::VkDescriptorSetLayout descriptorSetLayout, bool linked, vk::VkShaderStageFlagBits stage)
98 {
99 	vk::VkShaderEXT				shader;
100 
101 	if (!linked)
102 	{
103 		const auto&						src					= binaries.get(vk::getShaderName(stage));
104 		const vk::VkShaderCreateInfoEXT shaderCreateInfo	=
105 		{
106 			vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,								// VkStructureType				sType;
107 			DE_NULL,																	// const void*					pNext;
108 			0u,																			// VkShaderCreateFlagsEXT		flags;
109 			stage,																		// VkShaderStageFlagBits		stage;
110 			getNextStage(stage, features.tessellationShader, features.geometryShader),	// VkShaderStageFlags			nextStage;
111 			vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,											// VkShaderCodeTypeEXT			codeType;
112 			src.getSize(),																// size_t						codeSize;
113 			src.getBinary(),															// const void*					pCode;
114 			"main",																		// const char*					pName;
115 			(descriptorSetLayout != VK_NULL_HANDLE) ? 1u : 0u,							// uint32_t						setLayoutCount;
116 			(descriptorSetLayout != VK_NULL_HANDLE) ? &descriptorSetLayout : DE_NULL,	// VkDescriptorSetLayout*		pSetLayouts;
117 			0u,																			// uint32_t						pushConstantRangeCount;
118 			DE_NULL,																	// const VkPushConstantRange*	pPushConstantRanges;
119 			DE_NULL,																	// const VkSpecializationInfo*	pSpecializationInfo;
120 		};
121 
122 		vk.createShadersEXT(device, 1u, &shaderCreateInfo, DE_NULL, &shader);
123 	}
124 	else
125 	{
126 		const auto& vert = binaries.get("vert");
127 		const auto& tesc = binaries.get("tesc");
128 		const auto& tese = binaries.get("tese");
129 		const auto& geom = binaries.get("geom");
130 		const auto& frag = binaries.get("frag");
131 
132 		std::vector<vk::VkShaderCreateInfoEXT> shaderCreateInfos =
133 		{
134 			{
135 				vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
136 				DE_NULL,										// const void*					pNext;
137 				vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,		// VkShaderCreateFlagsEXT		flags;
138 				vk::VK_SHADER_STAGE_VERTEX_BIT,					// VkShaderStageFlagBits		stage;
139 				getNextStage(vk::VK_SHADER_STAGE_VERTEX_BIT, features.tessellationShader, features.geometryShader),	// VkShaderStageFlags			nextStage;
140 				vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,				// VkShaderCodeTypeEXT			codeType;
141 				vert.getSize(),									// size_t						codeSize;
142 				vert.getBinary(),								// const void*					pCode;
143 				"main",											// const char*					pName;
144 				0u,												// uint32_t						setLayoutCount;
145 				DE_NULL,										// VkDescriptorSetLayout*		pSetLayouts;
146 				0u,												// uint32_t						pushConstantRangeCount;
147 				DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
148 				DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
149 			},
150 			{
151 				vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
152 				DE_NULL,										// const void*					pNext;
153 				vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,		// VkShaderCreateFlagsEXT		flags;
154 				vk::VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlagBits		stage;
155 				getNextStage(vk::VK_SHADER_STAGE_FRAGMENT_BIT, features.tessellationShader, features.geometryShader),	// VkShaderStageFlags			nextStage;
156 				vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,				// VkShaderCodeTypeEXT			codeType;
157 				frag.getSize(),									// size_t						codeSize;
158 				frag.getBinary(),								// const void*					pCode;
159 				"main",											// const char*					pName;
160 				0u,												// uint32_t						setLayoutCount;
161 				DE_NULL,										// VkDescriptorSetLayout*		pSetLayouts;
162 				0u,												// uint32_t						pushConstantRangeCount;
163 				DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
164 				DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
165 			},
166 		};
167 		if (features.tessellationShader)
168 		{
169 			shaderCreateInfos.push_back(
170 				{
171 					vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
172 					DE_NULL,										// const void*					pNext;
173 					vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,		// VkShaderCreateFlagsEXT		flags;
174 					vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,	// VkShaderStageFlagBits		stage;
175 					getNextStage(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, features.tessellationShader, features.geometryShader),	// VkShaderStageFlags			nextStage;
176 					vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,				// VkShaderCodeTypeEXT			codeType;
177 					tesc.getSize(),									// size_t						codeSize;
178 					tesc.getBinary(),								// const void*					pCode;
179 					"main",											// const char*					pName;
180 					0u,												// uint32_t						setLayoutCount;
181 					DE_NULL,										// VkDescriptorSetLayout*		pSetLayouts;
182 					0u,												// uint32_t						pushConstantRangeCount;
183 					DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
184 					DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
185 				}
186 			);
187 			shaderCreateInfos.push_back(
188 				{
189 					vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
190 					DE_NULL,										// const void*					pNext;
191 					vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,		// VkShaderCreateFlagsEXT		flags;
192 					vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,// VkShaderStageFlagBits		stage;
193 					getNextStage(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, features.tessellationShader, features.geometryShader),	// VkShaderStageFlags			nextStage;
194 					vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,				// VkShaderCodeTypeEXT			codeType;
195 					tese.getSize(),									// size_t						codeSize;
196 					tese.getBinary(),								// const void*					pCode;
197 					"main",											// const char*					pName;
198 					0u,												// uint32_t						setLayoutCount;
199 					DE_NULL,										// VkDescriptorSetLayout*		pSetLayouts;
200 					0u,												// uint32_t						pushConstantRangeCount;
201 					DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
202 					DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
203 				}
204 			);
205 		}
206 		if (features.geometryShader)
207 		{
208 			shaderCreateInfos.push_back(
209 				{
210 					vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
211 					DE_NULL,										// const void*					pNext;
212 					vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,		// VkShaderCreateFlagsEXT		flags;
213 					vk::VK_SHADER_STAGE_GEOMETRY_BIT,				// VkShaderStageFlagBits		stage;
214 					getNextStage(vk::VK_SHADER_STAGE_GEOMETRY_BIT, features.tessellationShader, features.geometryShader),	// VkShaderStageFlags			nextStage;
215 					vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,				// VkShaderCodeTypeEXT			codeType;
216 					geom.getSize(),									// size_t						codeSize;
217 					geom.getBinary(),								// const void*					pCode;
218 					"main",											// const char*					pName;
219 					0u,												// uint32_t						setLayoutCount;
220 					DE_NULL,										// VkDescriptorSetLayout*		pSetLayouts;
221 					0u,												// uint32_t						pushConstantRangeCount;
222 					DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
223 					DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
224 				}
225 			);
226 		}
227 		std::vector<vk::VkShaderEXT> shaders(shaderCreateInfos.size());
228 		vk.createShadersEXT(device, (deUint32)shaderCreateInfos.size(), &shaderCreateInfos[0], DE_NULL, &shaders[0]);
229 
230 		for (deUint32 i = 0; i < (deUint32)shaderCreateInfos.size(); ++i)
231 		{
232 			if (shaderCreateInfos[i].stage == stage)
233 			{
234 				shader = shaders[i];
235 			}
236 			else
237 			{
238 				vk.destroyShaderEXT(device, shaders[i], DE_NULL);
239 			}
240 		}
241 	}
242 
243 	return vk::Move<vk::VkShaderEXT>(vk::check<vk::VkShaderEXT>(shader), vk::Deleter<vk::VkShaderEXT>(vk, device, DE_NULL));
244 }
245 
246 class ShaderObjectBinaryQueryInstance : public vkt::TestInstance
247 {
248 public:
ShaderObjectBinaryQueryInstance(Context & context,const TestParams params)249 								ShaderObjectBinaryQueryInstance		(Context& context, const TestParams params)
250 																	: vkt::TestInstance	(context)
251 																	, m_params			(params)
252 																	{}
~ShaderObjectBinaryQueryInstance(void)253 	virtual						~ShaderObjectBinaryQueryInstance	(void) {}
254 
255 	tcu::TestStatus				iterate								(void) override;
256 
257 private:
258 	TestParams					m_params;
259 };
260 
iterate(void)261 tcu::TestStatus ShaderObjectBinaryQueryInstance::iterate (void)
262 {
263 	const auto&					vkp						= m_context.getPlatformInterface();
264 	const vk::VkInstance		instance				= m_context.getInstance();
265 	const vk::InstanceDriver	instanceDriver			(m_context.getPlatformInterface(), instance);
266 	const vk::VkPhysicalDevice	physicalDevice			= m_context.getPhysicalDevice();
267 	const vk::DeviceInterface&	vk						= m_context.getDeviceInterface();
268 	const vk::VkDevice			device					= m_context.getDevice();
269 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
270 	const bool					tessellationSupported	= m_context.getDeviceFeatures().tessellationShader;
271 	const bool					geometrySupported		= m_context.getDeviceFeatures().geometryShader;
272 
273 	const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
274 		vk::DescriptorSetLayoutBuilder()
275 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
276 		.build(vk, device));
277 
278 	vk::VkDescriptorSetLayout	layout				= (m_params.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *descriptorSetLayout : VK_NULL_HANDLE;
279 
280 	const auto&					binaries			= m_context.getBinaryCollection();
281 	vk::Move<vk::VkShaderEXT>	shader				= createShader(vk, binaries, device, m_context.getDeviceFeatures(), layout, m_params.linked, m_params.stage);
282 
283 	size_t						dataSize			= 0;
284 	vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
285 	std::vector<deUint8>		data				(dataSize);
286 	vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
287 
288 	for (deUint32 i = 0; i < 10; ++i)
289 	{
290 		size_t					otherDataSize = 0;
291 		std::vector<deUint8>	otherData;
292 		if (m_params.queryType == SAME_SHADER)
293 		{
294 			vk.getShaderBinaryDataEXT(device, *shader, &otherDataSize, DE_NULL);
295 			otherData.resize(otherDataSize);
296 			vk.getShaderBinaryDataEXT(device, *shader, &otherDataSize, otherData.data());
297 		}
298 		else if (m_params.queryType == NEW_SHADER)
299 		{
300 			vk::Move<vk::VkShaderEXT> otherShader = createShader(vk, binaries, device, m_context.getDeviceFeatures(), layout, m_params.linked, m_params.stage);
301 			vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, DE_NULL);
302 			otherData.resize(otherDataSize);
303 			vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, otherData.data());
304 		}
305 		else if (m_params.queryType == SHADER_FROM_BINARY)
306 		{
307 			vk::Move<vk::VkShaderEXT> otherShader = vk::createShaderFromBinary(vk, device, m_params.stage, dataSize, data.data(), tessellationSupported, geometrySupported, layout);
308 			vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, DE_NULL);
309 			otherData.resize(otherDataSize);
310 			vk.getShaderBinaryDataEXT(device, *otherShader, &otherDataSize, otherData.data());
311 		}
312 		else if (m_params.queryType == NEW_DEVICE || m_params.queryType == DEVICE_NO_EXTS_FEATURES)
313 		{
314 			vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures	= m_context.getShaderObjectFeaturesEXT();
315 			vk::VkPhysicalDeviceFeatures2				features2;
316 			std::vector<const char*>					extensions;
317 
318 			if (m_params.queryType == DEVICE_NO_EXTS_FEATURES)
319 			{
320 				features2 = vk::initVulkanStructure(&shaderObjectFeatures);
321 				features2.features.tessellationShader = tessellationSupported;
322 				features2.features.geometryShader = geometrySupported;
323 				extensions.push_back("VK_EXT_shader_object");
324 			}
325 			else
326 			{
327 				features2 = m_context.getDeviceFeatures2();
328 				extensions = m_context.getDeviceCreationExtensions();
329 			}
330 			const float							queuePriority		= 1.0f;
331 
332 			const vk::VkDeviceQueueCreateInfo	deviceQueueCI		=
333 			{
334 				vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// sType
335 				DE_NULL,															// pNext
336 				(vk::VkDeviceQueueCreateFlags)0u,									// flags
337 				queueFamilyIndex,													// queueFamilyIndex;
338 				1,																	// queueCount;
339 				&queuePriority,														// pQueuePriorities;
340 			};
341 
342 			const vk::VkDeviceCreateInfo		deviceCreateInfo	=
343 			{
344 				vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,				// sType;
345 				&features2,												// pNext;
346 				0u,														// flags
347 				1u,														// queueCreateInfoCount;
348 				&deviceQueueCI,											// pQueueCreateInfos;
349 				0u,														// layerCount;
350 				DE_NULL,												// ppEnabledLayerNames;
351 				(deUint32)extensions.size(),							// deUint32							enabledExtensionCount;
352 				extensions.data(),										// const char* const*				ppEnabledExtensionNames;
353 				DE_NULL,												// pEnabledFeatures;
354 			};
355 
356 			vk::Move<vk::VkDevice>		otherDevice		= createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, instanceDriver, physicalDevice, &deviceCreateInfo);
357 
358 			vk::Move<vk::VkShaderEXT>	otherShader		= createShader(vk, binaries, *otherDevice, features2.features, layout, m_params.linked, m_params.stage);
359 			vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, DE_NULL);
360 			otherData.resize(otherDataSize);
361 			vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, otherData.data());
362 		}
363 
364 		if (dataSize != otherDataSize)
365 			return tcu::TestStatus::fail("Size not matching");
366 
367 		for (deUint32 j = 0; j < dataSize; ++j)
368 			if (data[j] != otherData[j])
369 				return tcu::TestStatus::fail("Data not matching");
370 	}
371 
372 	return tcu::TestStatus::pass("Pass");
373 }
374 
375 class ShaderObjectBinaryQueryCase : public vkt::TestCase
376 {
377 public:
ShaderObjectBinaryQueryCase(tcu::TestContext & testCtx,const std::string & name,TestParams params)378 					ShaderObjectBinaryQueryCase		(tcu::TestContext& testCtx, const std::string& name, TestParams params)
379 													: vkt::TestCase		(testCtx, name)
380 													, m_params			(params)
381 													{}
~ShaderObjectBinaryQueryCase(void)382 	virtual			~ShaderObjectBinaryQueryCase	(void) {}
383 
384 	void			checkSupport					(vkt::Context& context) const override;
385 	virtual void	initPrograms					(vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const386 	TestInstance*	createInstance					(Context& context) const override { return new ShaderObjectBinaryQueryInstance(context, m_params); }
387 
388 private:
389 	TestParams		m_params;
390 };
391 
checkSupport(Context & context) const392 void ShaderObjectBinaryQueryCase::checkSupport(Context& context) const
393 {
394 	context.requireDeviceFunctionality("VK_EXT_shader_object");
395 
396 	if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
397 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
398 	if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
399 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
400 }
401 
initPrograms(vk::SourceCollections & programCollection) const402 void ShaderObjectBinaryQueryCase::initPrograms(vk::SourceCollections& programCollection) const
403 {
404 	vk::addBasicShaderObjectShaders(programCollection);
405 }
406 
407 class ShaderObjectIncompatibleBinaryInstance : public vkt::TestInstance
408 {
409 public:
ShaderObjectIncompatibleBinaryInstance(Context & context,vk::VkShaderStageFlagBits shaderStage,const IncompleteBinaryTestType testType)410 						ShaderObjectIncompatibleBinaryInstance	(Context& context, vk::VkShaderStageFlagBits shaderStage, const IncompleteBinaryTestType testType)
411 																: vkt::TestInstance	(context)
412 																, m_shaderStage		(shaderStage)
413 																, m_testType		(testType)
414 																{}
~ShaderObjectIncompatibleBinaryInstance(void)415 	virtual				~ShaderObjectIncompatibleBinaryInstance	(void) {}
416 
417 	tcu::TestStatus		iterate									(void) override;
418 
419 private:
420 	const vk::VkShaderStageFlagBits	m_shaderStage;
421 	const IncompleteBinaryTestType	m_testType;
422 };
423 
iterate(void)424 tcu::TestStatus ShaderObjectIncompatibleBinaryInstance::iterate (void)
425 {
426 	const vk::VkInstance			instance				= m_context.getInstance();
427 	const vk::InstanceDriver		instanceDriver			(m_context.getPlatformInterface(), instance);
428 	const vk::DeviceInterface&		vk						= m_context.getDeviceInterface();
429 	const vk::VkDevice				device					= m_context.getDevice();
430 	const bool						tessellationSupported	= m_context.getDeviceFeatures().tessellationShader;
431 	const bool						geometrySupported		= m_context.getDeviceFeatures().geometryShader;
432 
433 	const auto&						binaries				= m_context.getBinaryCollection();
434 
435 	const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
436 		vk::DescriptorSetLayoutBuilder()
437 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
438 		.build(vk, device));
439 
440 	vk::VkDescriptorSetLayout		layout				= (m_shaderStage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *descriptorSetLayout : VK_NULL_HANDLE;
441 
442 	const auto&						src					= binaries.get(getShaderName(m_shaderStage));
443 	const vk::VkShaderCreateInfoEXT shaderCreateInfo	=
444 	{
445 		vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
446 		DE_NULL,										// const void*					pNext;
447 		0u,												// VkShaderCreateFlagsEXT		flags;
448 		m_shaderStage,									// VkShaderStageFlagBits		stage;
449 		vk::getShaderObjectNextStages(m_shaderStage, tessellationSupported, geometrySupported),	// VkShaderStageFlags			nextStage;
450 		vk::VK_SHADER_CODE_TYPE_SPIRV_EXT,				// VkShaderCodeTypeEXT			codeType;
451 		src.getSize(),									// size_t						codeSize;
452 		src.getBinary(),								// const void*					pCode;
453 		"main",											// const char*					pName;
454 		(layout != VK_NULL_HANDLE) ? 1u : 0u,			// uint32_t						setLayoutCount;
455 		(layout != VK_NULL_HANDLE) ? &layout : DE_NULL,	// VkDescriptorSetLayout*		pSetLayouts;
456 		0u,												// uint32_t						pushConstantRangeCount;
457 		DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
458 		DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
459 	};
460 
461 	vk::Move<vk::VkShaderEXT>		shader				= vk::createShader(vk, device, shaderCreateInfo);
462 	size_t							dataSize			= 0;
463 	vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
464 	std::vector<deUint8>			data				(dataSize, 123);
465 
466 	if (m_testType == HALF_DATA_SIZE)
467 	{
468 		dataSize /= 2;
469 		vk::VkResult result = vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
470 
471 		if (result != vk::VK_INCOMPLETE)
472 			return tcu::TestStatus::fail("Result was not VK_INCOMPLETE");
473 
474 		for (const auto& byte : data)
475 			if (byte != 123)
476 				return tcu::TestStatus::fail("Data was modified");
477 
478 		if (dataSize != 0)
479 			return tcu::TestStatus::fail("Data size was not 0");
480 	}
481 	else
482 	{
483 		de::Random					random				(102030);
484 		// Generate random garbage data
485 		if (m_testType != CREATE_FROM_HALF_SIZE)
486 		{
487 			deUint32 i = m_testType == GARBAGE_DATA ? 0u : (deUint32)dataSize / 2u;
488 			for (; i < dataSize; ++i)
489 				data[i] = random.getUint8();
490 		}
491 
492 		if (m_testType == CREATE_FROM_HALF_SIZE || m_testType == CREATE_FROM_HALF_SIZE_GARBAGE)
493 			dataSize /= 2;
494 
495 		const vk::VkShaderCreateInfoEXT invalidShaderCreateInfo =
496 		{
497 			vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,	// VkStructureType				sType;
498 			DE_NULL,										// const void*					pNext;
499 			0u,												// VkShaderCreateFlagsEXT		flags;
500 			m_shaderStage,									// VkShaderStageFlagBits		stage;
501 			vk::getShaderObjectNextStages(m_shaderStage, tessellationSupported, geometrySupported),	// VkShaderStageFlags			nextStage;
502 			vk::VK_SHADER_CODE_TYPE_BINARY_EXT,				// VkShaderCodeTypeEXT			codeType;
503 			dataSize,										// size_t						codeSize;
504 			data.data(),									// const void*					pCode;
505 			"main",											// const char*					pName;
506 			(layout != VK_NULL_HANDLE) ? 1u : 0u,			// uint32_t						setLayoutCount;
507 			(layout != VK_NULL_HANDLE) ? &layout : DE_NULL,	// VkDescriptorSetLayout*		pSetLayouts;
508 			0u,												// uint32_t						pushConstantRangeCount;
509 			DE_NULL,										// const VkPushConstantRange*	pPushConstantRanges;
510 			DE_NULL,										// const VkSpecializationInfo*	pSpecializationInfo;
511 		};
512 
513 		vk::VkShaderEXT dstShader;
514 		vk::VkResult	result		= vk.createShadersEXT(device, 1u, &invalidShaderCreateInfo, DE_NULL, &dstShader);
515 
516 		if (result != vk::VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT)
517 			return tcu::TestStatus::fail("Fail");
518 	}
519 
520 	return tcu::TestStatus::pass("Pass");
521 }
522 
523 class ShaderObjectIncompatibleBinaryCase : public vkt::TestCase
524 {
525 public:
ShaderObjectIncompatibleBinaryCase(tcu::TestContext & testCtx,const std::string & name,const vk::VkShaderStageFlagBits shaderStage,const IncompleteBinaryTestType testType)526 					ShaderObjectIncompatibleBinaryCase	(tcu::TestContext& testCtx, const std::string& name, const vk::VkShaderStageFlagBits shaderStage, const IncompleteBinaryTestType testType)
527 														: vkt::TestCase		(testCtx, name)
528 														, m_shaderStage		(shaderStage)
529 														, m_testType		(testType)
530 														{}
~ShaderObjectIncompatibleBinaryCase(void)531 	virtual			~ShaderObjectIncompatibleBinaryCase	(void) {}
532 
533 	void			checkSupport						(vkt::Context& context) const override;
534 	virtual void	initPrograms						(vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const535 	TestInstance*	createInstance						(Context& context) const override { return new ShaderObjectIncompatibleBinaryInstance(context, m_shaderStage, m_testType); }
536 
537 private:
538 	const vk::VkShaderStageFlagBits	m_shaderStage;
539 	const IncompleteBinaryTestType	m_testType;
540 };
541 
checkSupport(Context & context) const542 void ShaderObjectIncompatibleBinaryCase::checkSupport (Context& context) const
543 {
544 	context.requireDeviceFunctionality("VK_EXT_shader_object");
545 
546 	if (m_shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
547 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
548 	if (m_shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
549 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
550 }
551 
initPrograms(vk::SourceCollections & programCollection) const552 void ShaderObjectIncompatibleBinaryCase::initPrograms (vk::SourceCollections& programCollection) const
553 {
554 	vk::addBasicShaderObjectShaders(programCollection);
555 }
556 
557 class ShaderObjectDeviceFeaturesBinaryInstance : public vkt::TestInstance
558 {
559 public:
ShaderObjectDeviceFeaturesBinaryInstance(Context & context,const bool linked,const vk::VkShaderStageFlagBits stage,const deUint32 index)560 								ShaderObjectDeviceFeaturesBinaryInstance	(Context& context, const bool linked, const vk::VkShaderStageFlagBits stage, const deUint32 index)
561 																			: vkt::TestInstance	(context)
562 																			, m_linked			(linked)
563 																			, m_stage			(stage)
564 																			, m_index			(index)
565 																			{}
~ShaderObjectDeviceFeaturesBinaryInstance(void)566 	virtual						~ShaderObjectDeviceFeaturesBinaryInstance	(void) {}
567 
568 	tcu::TestStatus				iterate										(void) override;
569 
570 private:
571 	const bool						m_linked;
572 	const vk::VkShaderStageFlagBits	m_stage;
573 	const deUint32					m_index;
574 };
575 
findPNext(const void * pNext,vk::VkStructureType sType)576 const void* findPNext(const void* pNext, vk::VkStructureType sType) {
577 	while (pNext != DE_NULL)
578 	{
579 		if (((vk::VkBaseOutStructure*)pNext)->sType == sType)
580 			return (const void*)pNext;
581 		pNext = ((vk::VkBaseOutStructure*)pNext)->pNext;
582 	}
583 	return (const void*)DE_NULL;
584 }
585 
iterate(void)586 tcu::TestStatus ShaderObjectDeviceFeaturesBinaryInstance::iterate (void)
587 {
588 	const auto&					vkp						= m_context.getPlatformInterface();
589 	const vk::VkInstance		instance				= m_context.getInstance();
590 	const vk::InstanceDriver	instanceDriver			(m_context.getPlatformInterface(), instance);
591 	const vk::VkPhysicalDevice	physicalDevice			= m_context.getPhysicalDevice();
592 	const vk::DeviceInterface&	vk						= m_context.getDeviceInterface();
593 	const vk::VkDevice			device					= m_context.getDevice();
594 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
595 	const auto&					binaries				= m_context.getBinaryCollection();
596 
597 	const vk::VkPhysicalDeviceFeatures	features		= m_context.getDeviceFeatures();
598 
599 	const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
600 		vk::DescriptorSetLayoutBuilder()
601 		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
602 		.build(vk, device));
603 
604 	vk::VkDescriptorSetLayout	layout				= (m_stage == vk::VK_SHADER_STAGE_COMPUTE_BIT) ? *descriptorSetLayout : VK_NULL_HANDLE;
605 
606 	vk::Move<vk::VkShaderEXT>	shader				= createShader(vk, binaries, device, features, layout, m_linked, m_stage);
607 
608 	size_t						dataSize			= 0;
609 	vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
610 	std::vector<deUint8>		data				(dataSize);
611 	vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
612 
613 	size_t						otherDataSize = 0;
614 	std::vector<deUint8>		otherData;
615 
616 	const vk::VkPhysicalDeviceFeatures2	features2				= m_context.getDeviceFeatures2();
617 	vk::VkPhysicalDeviceFeatures2		testFeatures			= m_context.getDeviceFeatures2();
618 	std::vector<const char*>			extensions				= m_context.getDeviceCreationExtensions();
619 
620 	auto shaderObjectFeatures						= m_context.getShaderObjectFeaturesEXT();
621 	auto vulkan11features							= m_context.getDeviceVulkan11Features();
622 	auto vulkan12features							= m_context.getDeviceVulkan12Features();
623 	auto vulkan13features							= m_context.getDeviceVulkan13Features();
624 	auto transformFeedbackFeatures					= m_context.getTransformFeedbackFeaturesEXT();
625 	auto dynamicRenderingFeatures					= m_context.getDynamicRenderingFeatures();
626 	auto cornerSampledImageFeatures					= m_context.getCornerSampledImageFeatures();
627 	auto multiviewFeatures							= m_context.getMultiviewFeatures();
628 	auto shaderDrawParametersFeatures				= m_context.getShaderDrawParametersFeatures();
629 	auto textureCompressionAstrHdrFeatures			= m_context.getTextureCompressionASTCHDRFeatures();
630 	auto pipelineRobustnessFeatures					= m_context.getPipelineRobustnessFeaturesEXT();
631 	auto conditionalRenderingFeatures				= m_context.getConditionalRenderingFeaturesEXT();
632 	auto shaderFloat16Int8Features					= m_context.getShaderFloat16Int8Features();
633 	auto f16BitStorageFeatures						= m_context.get16BitStorageFeatures();
634 	auto depthCilpEnableFeatures					= m_context.getDepthClipEnableFeaturesEXT();
635 	auto imagelessFramebufferFeatures				= m_context.getImagelessFramebufferFeatures();
636 	auto performanceQueryFeatures					= m_context.getPerformanceQueryFeatures();
637 	auto variablePointersFeatures					= m_context.getVariablePointersFeatures();
638 	auto inlineUniformBlockFeatures					= m_context.getInlineUniformBlockFeatures();
639 	auto protectedMemoryFeatures					= m_context.getProtectedMemoryFeatures();
640 	auto blendOperationAdvancedFeatures				= m_context.getBlendOperationAdvancedFeaturesEXT();
641 	auto accelerationStructureFeatures				= m_context.getAccelerationStructureFeatures();
642 	auto smBuiltinFeatures							= m_context.getShaderSMBuiltinsFeatures();
643 	auto samplerYcbcrConversionFeatures				= m_context.getSamplerYcbcrConversionFeatures();
644 	auto descriptorIndexingFeatures					= m_context.getDescriptorIndexingFeatures();
645 	auto portabilitySubsetFeatures					= m_context.getPortabilitySubsetFeatures();
646 	auto shadingRateImageFeatures					= m_context.getShadingRateImageFeatures();
647 	auto representativeFragmentTestFeatures			= m_context.getRepresentativeFragmentTestFeatures();
648 	auto shaderSubgroupExtnededTypesFeatures		= m_context.getShaderSubgroupExtendedTypesFeatures();
649 	auto f8BitStorageFeatures						= m_context.get8BitStorageFeatures();
650 	auto shaderAtomicInt64Features					= m_context.getShaderAtomicInt64Features();
651 	auto shaderClockFeatures						= m_context.getShaderClockFeatures();
652 	auto vertexAttributeDivisorFeatures				= m_context.getVertexAttributeDivisorFeaturesEXT();
653 	auto computeShaderDerivativesFeatures			= m_context.getComputeShaderDerivativesFeatures();
654 	auto meshShaderFeatures							= m_context.getMeshShaderFeaturesEXT();
655 	auto fragmentShaderBarycentricFeatures			= m_context.getFragmentShaderBarycentricFeatures();
656 	auto shaderImageFootprintFeatures				= m_context.getShaderImageFootprintFeatures();
657 	auto exclusiveScissorFeatures					= m_context.getExclusiveScissorFeatures();
658 	auto timelineSemaphoreFeatures					= m_context.getTimelineSemaphoreFeatures();
659 	auto shaderIntegerFunctions2Features			= m_context.getShaderIntegerFunctions2FeaturesINTEL();
660 	auto vulkanMemoryModelFeatures					= m_context.getVulkanMemoryModelFeatures();
661 	auto shaderTerminateInvocationFeatures			= m_context.getShaderTerminateInvocationFeatures();
662 	auto fragmentDensityMapFeatures					= m_context.getFragmentDensityMapFeaturesEXT();
663 	auto scalarBlockLayoutFeatures					= m_context.getScalarBlockLayoutFeatures();
664 	auto subgroupSizeControlFeatures				= m_context.getSubgroupSizeControlFeatures();
665 	auto coherentMemoryFeatures						= m_context.getCoherentMemoryFeaturesAMD();
666 	auto shaderImageAtomicInt64Features				= m_context.getShaderImageAtomicInt64FeaturesEXT();
667 	auto memoryPriorityFeatures						= m_context.getMemoryPriorityFeaturesEXT();
668 	auto dedicatedAllocationImageAliasingFeatures	= m_context.getDedicatedAllocationImageAliasingFeatures();
669 	auto separateDepthStencilLayoutFeatures			= m_context.getSeparateDepthStencilLayoutsFeatures();
670 	auto bufferDeviceAddressFeatures				= m_context.getBufferDeviceAddressFeatures();
671 	auto presentWaitFeatures						= m_context.getPresentWaitFeatures();
672 	auto cooperativeMatrixFeatures					= m_context.getCooperativeMatrixFeatures();
673 	auto coverageReductionModeFeatures				= m_context.getCoverageReductionModeFeatures();
674 	auto fragmentShaderInterlockFeatures			= m_context.getFragmentShaderInterlockFeaturesEXT();
675 	auto ycbcrImageArraysFeatures					= m_context.getYcbcrImageArraysFeaturesEXT();
676 	auto uniformBufferStandardLayoutFeatures		= m_context.getUniformBufferStandardLayoutFeatures();
677 	auto provokingVertexFeatures					= m_context.getProvokingVertexFeaturesEXT();
678 	auto lineRasterizationFeatures					= m_context.getLineRasterizationFeaturesEXT();
679 	auto shaderAtomicFloatFeatures					= m_context.getShaderAtomicFloatFeaturesEXT();
680 	auto hostQueryResetFeatures						= m_context.getHostQueryResetFeatures();
681 	auto indexTypeUint8Features						= m_context.getIndexTypeUint8FeaturesEXT();
682 	auto extendedDynamicStateFeatures				= m_context.getExtendedDynamicStateFeaturesEXT();
683 	auto pipelineExecutablePropertiesFeatures		= m_context.getPipelineExecutablePropertiesFeatures();
684 	auto shaderAtomicFloat2Features					= m_context.getShaderAtomicFloat2FeaturesEXT();
685 	auto swapchainMaitenance1Features				= m_context.getSwapchainMaintenance1FeaturesEXT();
686 	auto shaderDemoteToHelperInvocationFeatures		= m_context.getShaderDemoteToHelperInvocationFeatures();
687 	auto deviceGeneratedCommandsFeatures			= m_context.getDeviceGeneratedCommandsFeatures();
688 	auto inheritedViewportScissorFeatures			= m_context.getInheritedViewportScissorFeatures();
689 	auto shaderIntegerDotProductFeatures			= m_context.getShaderIntegerDotProductFeatures();
690 	auto texelBufferAlignmentFeatures				= m_context.getTexelBufferAlignmentFeaturesEXT();
691 	auto deviceMemoryReportFeatures					= m_context.getDeviceMemoryReportFeaturesEXT();
692 	auto robustness2Features						= m_context.getRobustness2FeaturesEXT();
693 	auto customBorderColorFeatures					= m_context.getCustomBorderColorFeaturesEXT();
694 	auto presentBarrierFeatures						= m_context.getPresentBarrierFeatures();
695 	auto presentIdFeatures							= m_context.getPresentIdFeatures();
696 	auto privateDataFeatures						= m_context.getPrivateDataFeatures();
697 	auto pipelineCreationCacheControlFeatures		= m_context.getPipelineCreationCacheControlFeatures();
698 	auto diagnosticConfigFeatures					= m_context.getDiagnosticsConfigFeatures();
699 	auto synchronization2Features					= m_context.getSynchronization2Features();
700 	auto descriptorBufferFeatures					= m_context.getDescriptorBufferFeaturesEXT();
701 	auto graphicsPipelineLibraryFeatures			= m_context.getGraphicsPipelineLibraryFeaturesEXT();
702 	auto shaderEarlyAndLateFragmentTestsFeatures	= m_context.getShaderEarlyAndLateFragmentTestsFeaturesAMD();
703 	auto shaderSubgroupUniformControlFlowFeatures	= m_context.getShaderSubgroupUniformControlFlowFeatures();
704 	auto zeroInitializeWorkgroupMemoryFeatures		= m_context.getZeroInitializeWorkgroupMemoryFeatures();
705 	auto fragmentShadingRateEnumsFeatures			= m_context.getFragmentShadingRateEnumsFeatures();
706 	auto rayTracingMotionBlurFeatures				= m_context.getRayTracingMotionBlurFeatures();
707 	auto ycbcr2Plane444FormatsFeatures				= m_context.getYcbcr2Plane444FormatsFeaturesEXT();
708 	auto fragmentDensityMap2Features				= m_context.getFragmentDensityMap2FeaturesEXT();
709 	auto imageRobustnessFeatures					= m_context.getImageRobustnessFeatures();
710 	auto workgroupMemoryExplicitLayoutFeatures		= m_context.getWorkgroupMemoryExplicitLayoutFeatures();
711 	auto ImageCompressionControlFeatures			= m_context.getImageCompressionControlFeaturesEXT();
712 	auto attachmentFeedbackLoopFeatures				= m_context.getAttachmentFeedbackLoopLayoutFeaturesEXT();
713 	auto f4444FormatsFeatures						= m_context.get4444FormatsFeaturesEXT();
714 	auto faultFeatures								= m_context.getFaultFeaturesEXT();
715 	auto rasterizationOrderAttachmentAccessFeatures = m_context.getRasterizationOrderAttachmentAccessFeaturesEXT();
716 	auto rgba10x6FormatsFeatures					= m_context.getRGBA10X6FormatsFeaturesEXT();
717 	auto rayTracingPipelineFeatures					= m_context.getRayTracingPipelineFeatures();
718 	auto rayQueryFeatures							= m_context.getRayQueryFeatures();
719 	auto mutableDescriptorTypeFeatures				= m_context.getMutableDescriptorTypeFeaturesEXT();
720 	auto vertexInputDynamicStateFeatures			= m_context.getVertexInputDynamicStateFeaturesEXT();
721 	auto addressBindingReportFeatures				= m_context.getAddressBindingReportFeaturesEXT();
722 	auto depthClipControlFeatures					= m_context.getDepthClipControlFeaturesEXT();
723 	auto primitiveTopologyListRestartFeatures		= m_context.getPrimitiveTopologyListRestartFeaturesEXT();
724 	auto subpassShadingFeatures						= m_context.getSubpassShadingFeaturesHUAWEI();
725 	auto invocationMaskFeatures						= m_context.getInvocationMaskFeaturesHUAWEI();
726 	auto externalMemoryRDMAFeatures					= m_context.getExternalMemoryRDMAFeatures();
727 	auto pipelinePropertiesFeatures					= m_context.getPipelinePropertiesFeaturesEXT();
728 	auto multisampledRenderToSingleSampledFeatures	= m_context.getMultisampledRenderToSingleSampledFeaturesEXT();
729 	auto extendedDynamicState2Features				= m_context.getExtendedDynamicState2FeaturesEXT();
730 	auto colorWriteEnableFeatures					= m_context.getColorWriteEnableFeaturesEXT();
731 	auto primitivesGeneratedQueryFeatures			= m_context.getPrimitivesGeneratedQueryFeaturesEXT();
732 	auto rayTracingMaintenance1Features				= m_context.getRayTracingMaintenance1Features();
733 	auto globalPriorityQueryFeatures				= m_context.getGlobalPriorityQueryFeatures();
734 	auto imageViewMinLodFeatures					= m_context.getImageViewMinLodFeaturesEXT();
735 	auto multiDrawFeatures							= m_context.getMultiDrawFeaturesEXT();
736 	auto image2DViewOf3DFeatures					= m_context.getImage2DViewOf3DFeaturesEXT();
737 	auto opacityMicromapFeatures					= m_context.getOpacityMicromapFeaturesEXT();
738 	auto displacementMicromapFeatures				= m_context.getDisplacementMicromapFeatures();
739 	auto clusterCullingShaderFeatures				= m_context.getClusterCullingShaderFeaturesHUAWEI();
740 	auto borderColorSwizzleFeatures					= m_context.getBorderColorSwizzleFeaturesEXT();
741 	auto pageableDeviceLocalMemoryFeatures			= m_context.getPageableDeviceLocalMemoryFeaturesEXT();
742 	auto maintenance4Features						= m_context.getMaintenance4Features();
743 	auto imageSlicedViewOf3DFeatures				= m_context.getImageSlicedViewOf3DFeaturesEXT();
744 	auto descriptorSetHostMappingFeatures			= m_context.getDescriptorSetHostMappingFeaturesVALVE();
745 	auto depthClampZeroOneFeatures					= m_context.getDepthClampZeroOneFeaturesEXT();
746 	auto nonSeamlessCubeMapFeatures					= m_context.getNonSeamlessCubeMapFeaturesEXT();
747 	auto fragmentDensityMapOffsetFeatures			= m_context.getFragmentDensityMapOffsetFeaturesQCOM();
748 	auto copyMemoryIndirectFeatures					= m_context.getCopyMemoryIndirectFeatures();
749 	auto memoryDecompressionFeatures				= m_context.getMemoryDecompressionFeatures();
750 	auto linearColorAttachmentFeatures				= m_context.getLinearColorAttachmentFeatures();
751 	auto imageCompressionControlFeatures			= m_context.getImageCompressionControlFeaturesEXT();
752 	auto imageCompressionControLSwapchainFeatures	= m_context.getImageCompressionControlSwapchainFeaturesEXT();
753 	auto imageProcessingFeatures					= m_context.getImageProcessingFeaturesQCOM();
754 	auto extendedDynamicState3Features				= m_context.getExtendedDynamicState3FeaturesEXT();
755 	auto subpassMergeFeedbackFeatures				= m_context.getSubpassMergeFeedbackFeaturesEXT();
756 	auto shaderModuleIdentifierFeatures				= m_context.getShaderModuleIdentifierFeaturesEXT();
757 	auto opticalFlowFeatures						= m_context.getOpticalFlowFeatures();
758 	auto legacyDitheringFeatures					= m_context.getLegacyDitheringFeaturesEXT();
759 	auto pipelineProtectedAccessFeatures			= m_context.getPipelineProtectedAccessFeaturesEXT();
760 	auto tilePropertiesFeatures						= m_context.getTilePropertiesFeaturesQCOM();
761 	auto multivewPerViewViewportsFeatures			= m_context.getMultiviewPerViewViewportsFeaturesQCOM();
762 	auto rayTracingInvocationReorderFeatures		= m_context.getRayTracingInvocationReorderFeatures();
763 	auto shaderCoreBuiltinsFeatures					= m_context.getShaderCoreBuiltinsFeaturesARM();
764 	auto pipelineLibraryGroupHandlesFeatures		= m_context.getPipelineLibraryGroupHandlesFeaturesEXT();
765 	auto multivewPerViewRenderAreasFeatures			= m_context.getMultiviewPerViewRenderAreasFeaturesQCOM();
766 
767 	// These features depend on other features being enabled
768 	meshShaderFeatures.multiviewMeshShader = VK_FALSE;
769 	meshShaderFeatures.primitiveFragmentShadingRateMeshShader = VK_FALSE;
770 
771 	std::vector<void*> pNextFeatures = {
772 		&vulkan11features,
773 		&vulkan12features,
774 		&vulkan13features,
775 		&transformFeedbackFeatures,
776 		&dynamicRenderingFeatures,
777 		&cornerSampledImageFeatures,
778 		&multiviewFeatures,
779 		&shaderDrawParametersFeatures,
780 		&textureCompressionAstrHdrFeatures,
781 		&pipelineRobustnessFeatures,
782 		&conditionalRenderingFeatures,
783 		&shaderFloat16Int8Features,
784 		&f16BitStorageFeatures,
785 		&depthCilpEnableFeatures,
786 		&imagelessFramebufferFeatures,
787 		&performanceQueryFeatures,
788 		&variablePointersFeatures,
789 		&inlineUniformBlockFeatures,
790 		&protectedMemoryFeatures,
791 		&blendOperationAdvancedFeatures,
792 		&accelerationStructureFeatures,
793 		&smBuiltinFeatures,
794 		&samplerYcbcrConversionFeatures,
795 		&descriptorIndexingFeatures,
796 		&portabilitySubsetFeatures,
797 		&shadingRateImageFeatures,
798 		&representativeFragmentTestFeatures,
799 		&shaderSubgroupExtnededTypesFeatures,
800 		&f8BitStorageFeatures,
801 		&shaderAtomicInt64Features,
802 		&shaderClockFeatures,
803 		&vertexAttributeDivisorFeatures,
804 		&computeShaderDerivativesFeatures,
805 		&meshShaderFeatures,
806 		&fragmentShaderBarycentricFeatures,
807 		&shaderImageFootprintFeatures,
808 		&exclusiveScissorFeatures,
809 		&timelineSemaphoreFeatures,
810 		&shaderIntegerFunctions2Features,
811 		&vulkanMemoryModelFeatures,
812 		&shaderTerminateInvocationFeatures,
813 		&fragmentDensityMapFeatures,
814 		&scalarBlockLayoutFeatures,
815 		&subgroupSizeControlFeatures,
816 		&coherentMemoryFeatures,
817 		&shaderImageAtomicInt64Features,
818 		&memoryPriorityFeatures,
819 		&dedicatedAllocationImageAliasingFeatures,
820 		&separateDepthStencilLayoutFeatures,
821 		&bufferDeviceAddressFeatures,
822 		&presentWaitFeatures,
823 		&cooperativeMatrixFeatures,
824 		&coverageReductionModeFeatures,
825 		&fragmentShaderInterlockFeatures,
826 		&ycbcrImageArraysFeatures,
827 		&uniformBufferStandardLayoutFeatures,
828 		&provokingVertexFeatures,
829 		&lineRasterizationFeatures,
830 		&shaderAtomicFloatFeatures,
831 		&hostQueryResetFeatures,
832 		&indexTypeUint8Features,
833 		&extendedDynamicStateFeatures,
834 		&pipelineExecutablePropertiesFeatures,
835 		&shaderAtomicFloat2Features,
836 		&swapchainMaitenance1Features,
837 		&shaderDemoteToHelperInvocationFeatures,
838 		&deviceGeneratedCommandsFeatures,
839 		&inheritedViewportScissorFeatures,
840 		&shaderIntegerDotProductFeatures,
841 		&texelBufferAlignmentFeatures,
842 		&deviceMemoryReportFeatures,
843 		&robustness2Features,
844 		&customBorderColorFeatures,
845 		&presentBarrierFeatures,
846 		&presentIdFeatures,
847 		&privateDataFeatures,
848 		&pipelineCreationCacheControlFeatures,
849 		&diagnosticConfigFeatures,
850 		&synchronization2Features,
851 		&descriptorBufferFeatures,
852 		&graphicsPipelineLibraryFeatures,
853 		&shaderEarlyAndLateFragmentTestsFeatures,
854 		&shaderSubgroupUniformControlFlowFeatures,
855 		&zeroInitializeWorkgroupMemoryFeatures,
856 		&fragmentShadingRateEnumsFeatures,
857 		&rayTracingMotionBlurFeatures,
858 		&ycbcr2Plane444FormatsFeatures,
859 		&fragmentDensityMap2Features,
860 		&imageRobustnessFeatures,
861 		&workgroupMemoryExplicitLayoutFeatures,
862 		&ImageCompressionControlFeatures,
863 		&attachmentFeedbackLoopFeatures,
864 		&f4444FormatsFeatures,
865 		&faultFeatures,
866 		&rasterizationOrderAttachmentAccessFeatures,
867 		&rgba10x6FormatsFeatures,
868 		&rayTracingPipelineFeatures,
869 		&rayQueryFeatures,
870 		&mutableDescriptorTypeFeatures,
871 		&vertexInputDynamicStateFeatures,
872 		&addressBindingReportFeatures,
873 		&depthClipControlFeatures,
874 		&primitiveTopologyListRestartFeatures,
875 		&subpassShadingFeatures,
876 		&invocationMaskFeatures,
877 		&externalMemoryRDMAFeatures,
878 		&pipelinePropertiesFeatures,
879 		&multisampledRenderToSingleSampledFeatures,
880 		&extendedDynamicState2Features,
881 		&colorWriteEnableFeatures,
882 		&primitivesGeneratedQueryFeatures,
883 		&rayTracingMaintenance1Features,
884 		&globalPriorityQueryFeatures,
885 		&imageViewMinLodFeatures,
886 		&multiDrawFeatures,
887 		&image2DViewOf3DFeatures,
888 		&opacityMicromapFeatures,
889 		&displacementMicromapFeatures,
890 		&clusterCullingShaderFeatures,
891 		&borderColorSwizzleFeatures,
892 		&pageableDeviceLocalMemoryFeatures,
893 		&maintenance4Features,
894 		&imageSlicedViewOf3DFeatures,
895 		&descriptorSetHostMappingFeatures,
896 		&depthClampZeroOneFeatures,
897 		&nonSeamlessCubeMapFeatures,
898 		&fragmentDensityMapOffsetFeatures,
899 		&copyMemoryIndirectFeatures,
900 		&memoryDecompressionFeatures,
901 		&linearColorAttachmentFeatures,
902 		&imageCompressionControlFeatures,
903 		&imageCompressionControLSwapchainFeatures,
904 		&imageProcessingFeatures,
905 		&extendedDynamicState3Features,
906 		&subpassMergeFeedbackFeatures,
907 		&shaderModuleIdentifierFeatures,
908 		&opticalFlowFeatures,
909 		&legacyDitheringFeatures,
910 		&pipelineProtectedAccessFeatures,
911 		&tilePropertiesFeatures,
912 		&multivewPerViewViewportsFeatures,
913 		&rayTracingInvocationReorderFeatures,
914 		&shaderCoreBuiltinsFeatures,
915 		&pipelineLibraryGroupHandlesFeatures,
916 		&multivewPerViewRenderAreasFeatures,
917 	};
918 
919 	const float							queuePriority			= 1.0f;
920 
921 	const vk::VkDeviceQueueCreateInfo	deviceQueueCI =
922 	{
923 		vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// sType
924 		DE_NULL,															// pNext
925 		(vk::VkDeviceQueueCreateFlags)0u,									// flags
926 		queueFamilyIndex,													// queueFamilyIndex;
927 		1,																	// queueCount;
928 		&queuePriority,														// pQueuePriorities;
929 	};
930 
931 	const vk::VkDeviceCreateInfo		deviceCreateInfo =
932 	{
933 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,				// sType;
934 		&testFeatures,											// pNext;
935 		0u,														// flags
936 		1u,														// queueCreateInfoCount;
937 		&deviceQueueCI,											// pQueueCreateInfos;
938 		0u,														// layerCount;
939 		DE_NULL,												// ppEnabledLayerNames;
940 		(deUint32)extensions.size(),							// deUint32							enabledExtensionCount;
941 		extensions.data(),										// const char* const*				ppEnabledExtensionNames;
942 		DE_NULL,												// pEnabledFeatures;
943 	};
944 
945 	const deUint32 coreFeaturesCount	= 50u;
946 	const deUint32 pNextFeaturesCount	= (deUint32)pNextFeatures.size();
947 
948 	// There are too many features to test every combination, so we group them by step = 10
949 	const deUint32 step1 = 10u;
950 	const deUint32 step2 = 30u;
951 	const deUint32 count2 = deUint32(std::pow(2u, pNextFeaturesCount / step2));
952 	vk::VkBool32* coreFeaturesPtr = &testFeatures.features.robustBufferAccess;
953 
954 	for (deUint32 i = 0; i < count2; ++i)
955 	{
956 		// Reset features
957 		testFeatures.features = features2.features;
958 		void* pNext = DE_NULL;
959 		for (deUint32 j = 0; j < coreFeaturesCount; ++j)
960 		{
961 			if (((m_index >> (j / step1)) & 1) == 0)
962 				coreFeaturesPtr[j] = VK_FALSE;
963 		}
964 		for (deUint32 j = 0; j < pNextFeaturesCount; ++j)
965 		{
966 			if (((i >> (j / step2)) & 1) == 1)
967 			{
968 				if (findPNext(features2.pNext, ((vk::VkBaseOutStructure*)pNextFeatures[j])->sType))
969 				{
970 					((vk::VkBaseOutStructure*)pNextFeatures[j])->pNext = (vk::VkBaseOutStructure*)pNext;
971 					pNext = pNextFeatures[j];
972 				}
973 			}
974 		}
975 
976 		shaderObjectFeatures.pNext = pNext;
977 		testFeatures.pNext = &shaderObjectFeatures;
978 		// Geometry and tessellation features must not be modified
979 		testFeatures.features.tessellationShader = features.tessellationShader;
980 		testFeatures.features.geometryShader = features.geometryShader;
981 
982 		vk::Move<vk::VkDevice>		otherDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, instanceDriver, physicalDevice, &deviceCreateInfo);
983 
984 		vk::Move<vk::VkShaderEXT>	otherShader = createShader(vk, binaries, *otherDevice, features, layout, m_linked, m_stage);
985 		vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, DE_NULL);
986 		otherData.resize(otherDataSize);
987 		vk.getShaderBinaryDataEXT(*otherDevice, *otherShader, &otherDataSize, otherData.data());
988 
989 		if (dataSize != otherDataSize)
990 			return tcu::TestStatus::fail("Size not matching");
991 
992 		for (deUint32 j = 0; j < dataSize; ++j)
993 			if (data[j] != otherData[j])
994 				return tcu::TestStatus::fail("Data not matching");
995 	}
996 
997 	return tcu::TestStatus::pass("Pass");
998 }
999 
1000 class ShaderObjectDeviceFeaturesBinaryCase : public vkt::TestCase
1001 {
1002 public:
ShaderObjectDeviceFeaturesBinaryCase(tcu::TestContext & testCtx,const std::string & name,const bool linked,const vk::VkShaderStageFlagBits stage,const deUint32 index)1003 					ShaderObjectDeviceFeaturesBinaryCase	(tcu::TestContext& testCtx, const std::string& name, const bool linked, const vk::VkShaderStageFlagBits stage, const deUint32 index)
1004 															: vkt::TestCase		(testCtx, name)
1005 															, m_linked			(linked)
1006 															, m_stage			(stage)
1007 															, m_index			(index)
1008 															{}
~ShaderObjectDeviceFeaturesBinaryCase(void)1009 	virtual			~ShaderObjectDeviceFeaturesBinaryCase	(void) {}
1010 
1011 	void			checkSupport							(vkt::Context& context) const override;
1012 	virtual void	initPrograms							(vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const1013 	TestInstance*	createInstance							(Context& context) const override { return new ShaderObjectDeviceFeaturesBinaryInstance(context, m_linked, m_stage, m_index); }
1014 
1015 private:
1016 	const bool						m_linked;
1017 	const vk::VkShaderStageFlagBits	m_stage;
1018 	const deUint32					m_index;
1019 };
1020 
checkSupport(Context & context) const1021 void ShaderObjectDeviceFeaturesBinaryCase::checkSupport (Context& context) const
1022 {
1023 	context.requireDeviceFunctionality("VK_EXT_shader_object");
1024 
1025 	if (m_stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1026 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1027 	if (m_stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
1028 		context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1029 }
1030 
initPrograms(vk::SourceCollections & programCollection) const1031 void ShaderObjectDeviceFeaturesBinaryCase::initPrograms (vk::SourceCollections& programCollection) const
1032 {
1033 	vk::addBasicShaderObjectShaders(programCollection);
1034 }
1035 
getName(QueryType queryType)1036 std::string getName (QueryType queryType)
1037 {
1038 	switch (queryType) {
1039 	case SAME_SHADER:
1040 		return "same_shader";
1041 		break;
1042 	case NEW_SHADER:
1043 		return "new_shader";
1044 		break;
1045 	case SHADER_FROM_BINARY:
1046 		return "shader_from_binary";
1047 		break;
1048 	case NEW_DEVICE:
1049 		return "new_device";
1050 	case DEVICE_NO_EXTS_FEATURES:
1051 		return "device_no_exts_features";
1052 	default:
1053 		DE_ASSERT(0);
1054 		break;
1055 	}
1056 	return {};
1057 }
1058 
1059 }
1060 
createShaderObjectBinaryTests(tcu::TestContext & testCtx)1061 tcu::TestCaseGroup* createShaderObjectBinaryTests (tcu::TestContext& testCtx)
1062 {
1063 	de::MovePtr<tcu::TestCaseGroup> binaryGroup(new tcu::TestCaseGroup(testCtx, "binary"));
1064 
1065 	const struct
1066 	{
1067 		vk::VkShaderStageFlagBits	stage;
1068 		const char* name;
1069 	} stageTests[] =
1070 	{
1071 		{ vk::VK_SHADER_STAGE_VERTEX_BIT,					"vert"		},
1072 		{ vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc"		},
1073 		{ vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese"		},
1074 		{ vk::VK_SHADER_STAGE_GEOMETRY_BIT,					"geom"		},
1075 		{ vk::VK_SHADER_STAGE_FRAGMENT_BIT,					"frag"		},
1076 		{ vk::VK_SHADER_STAGE_COMPUTE_BIT,					"comp"		},
1077 	};
1078 
1079 	const bool linkedTests[] =
1080 	{
1081 		false,
1082 		true,
1083 	};
1084 
1085 	const QueryType queryTypeTests[] =
1086 	{
1087 		SAME_SHADER,
1088 		NEW_SHADER,
1089 		SHADER_FROM_BINARY,
1090 		NEW_DEVICE,
1091 		DEVICE_NO_EXTS_FEATURES,
1092 	};
1093 
1094 	de::MovePtr<tcu::TestCaseGroup> queryGroup(new tcu::TestCaseGroup(testCtx, "query"));
1095 	for (const auto& stage : stageTests)
1096 	{
1097 		de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stage.name));
1098 		for (const auto& linked : linkedTests)
1099 		{
1100 			if (linked && stage.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT)
1101 				continue;
1102 
1103 			std::string linkedName = linked ? "linked" : "unlinked";
1104 			de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedName.c_str()));
1105 			for (const auto& queryType : queryTypeTests)
1106 			{
1107 				TestParams params =
1108 				{
1109 					stage.stage,
1110 					linked,
1111 					queryType,
1112 				};
1113 				linkedGroup->addChild(new ShaderObjectBinaryQueryCase(testCtx, getName(queryType), params));
1114 			}
1115 			stageGroup->addChild(linkedGroup.release());
1116 		}
1117 		queryGroup->addChild(stageGroup.release());
1118 	}
1119 
1120 	const struct
1121 	{
1122 		IncompleteBinaryTestType	type;
1123 		const char* name;
1124 	} incompatibleTests[] =
1125 	{
1126 		{ HALF_DATA_SIZE,					"half_size",					},
1127 		{ GARBAGE_DATA,						"garbage_data",					},
1128 		{ GARBAGE_SECOND_HALF,				"garbage_second_half",			},
1129 		{ CREATE_FROM_HALF_SIZE,			"create_from_half_size"			},
1130 		{ CREATE_FROM_HALF_SIZE_GARBAGE,	"create_from_half_size_garbage"	},
1131 	};
1132 
1133 	de::MovePtr<tcu::TestCaseGroup> incompatibleGroup(new tcu::TestCaseGroup(testCtx, "incompatible"));
1134 	for (const auto& stage : stageTests)
1135 	{
1136 		de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stage.name));
1137 		for (const auto& testType : incompatibleTests)
1138 		{
1139 			stageGroup->addChild(new ShaderObjectIncompatibleBinaryCase(testCtx, testType.name, stage.stage, testType.type));
1140 		}
1141 		incompatibleGroup->addChild(stageGroup.release());
1142 	}
1143 
1144 	de::MovePtr<tcu::TestCaseGroup> deviceFeaturesGroup(new tcu::TestCaseGroup(testCtx, "device_features"));
1145 	for (const auto& stage : stageTests)
1146 	{
1147 		de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, stage.name));
1148 		for (const auto& linked : linkedTests)
1149 		{
1150 			if (linked && stage.stage == vk::VK_SHADER_STAGE_COMPUTE_BIT)
1151 				continue;
1152 
1153 			std::string linkedName = linked ? "linked" : "unlinked";
1154 			de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedName.c_str()));
1155 			for (deUint32 i = 0; i < 32; ++i)
1156 			{
1157 				linkedGroup->addChild(new ShaderObjectDeviceFeaturesBinaryCase(testCtx, std::to_string(i), linked, stage.stage, i));
1158 			}
1159 			stageGroup->addChild(linkedGroup.release());
1160 		}
1161 		deviceFeaturesGroup->addChild(stageGroup.release());
1162 	}
1163 
1164 	binaryGroup->addChild(queryGroup.release());
1165 	binaryGroup->addChild(incompatibleGroup.release());
1166 	binaryGroup->addChild(deviceFeaturesGroup.release());
1167 
1168 	return binaryGroup.release();
1169 }
1170 
1171 } // ShaderObject
1172 } // vkt
1173