• 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 API Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "tcuDefs.hpp"
26 #include "tcuTestCase.hpp"
27 #include "deUniquePtr.hpp"
28 #include "tcuTestCase.hpp"
29 #include "vktTestCase.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vktCustomInstancesDevices.hpp"
32 #include "tcuCommandLine.hpp"
33 
34 namespace vkt
35 {
36 namespace ShaderObject
37 {
38 
39 namespace
40 {
41 
42 enum ShaderObjectApiTest {
43 	EXT_DISCARD_RECTANGLES = 0,
44 	NV_SCISSOR_EXCLUSIVE,
45 	KHR_DYNAMIC_RENDERING,
46 	SHADER_BINARY_UUID,
47 };
48 
49 class ShaderObjectApiInstance : public vkt::TestInstance
50 {
51 public:
ShaderObjectApiInstance(Context & context)52 						ShaderObjectApiInstance		(Context& context)
53 							: vkt::TestInstance (context)
54 							{}
~ShaderObjectApiInstance(void)55 	virtual				~ShaderObjectApiInstance	(void) {}
56 
57 	tcu::TestStatus		iterate						(void) override;
58 };
59 
iterate(void)60 tcu::TestStatus ShaderObjectApiInstance::iterate (void)
61 {
62 	const vk::InstanceInterface&			vki				= m_context.getInstanceInterface();
63 	const vk::PlatformInterface&			vkp				= m_context.getPlatformInterface();
64 	const auto								instance		= m_context.getInstance();
65 	const auto								physicalDevice	= m_context.getPhysicalDevice();
66 	vk::VkPhysicalDeviceFeatures2			deviceFeatures	= vk::initVulkanStructure();
67 
68 	vki.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);
69 
70 	const auto								queuePriority	= 1.0f;
71 	const vk::VkDeviceQueueCreateInfo		queueInfo
72 	{
73 		vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		//	VkStructureType					sType;
74 		nullptr,											//	const void*						pNext;
75 		0u,													//	VkDeviceQueueCreateFlags		flags;
76 		m_context.getUniversalQueueFamilyIndex(),			//	deUint32						queueFamilyIndex;
77 		1u,													//	deUint32						queueCount;
78 		&queuePriority,										//	const float*					pQueuePriorities;
79 	};
80 
81 	std::vector<const char*>				extensions		= { "VK_EXT_shader_object" };
82 
83 	vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeaturesEXT	= vk::initVulkanStructure();
84 	vk::VkPhysicalDeviceFeatures2				features2				= vk::initVulkanStructure(&shaderObjectFeaturesEXT);
85 	vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
86 
87 	const vk::VkDeviceCreateInfo			deviceInfo
88 	{
89 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			//	VkStructureType					sType;
90 		&features2,											//	const void*						pNext;
91 		0u,													//	VkDeviceCreateFlags				flags;
92 		1u,													//	deUint32						queueCreateInfoCount;
93 		&queueInfo,											//	const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
94 		0u,													//	deUint32						enabledLayerCount;
95 		nullptr,											//	const char* const*				ppEnabledLayerNames;
96 		(deUint32)extensions.size(),						//	deUint32						enabledExtensionCount;
97 		extensions.data(),									//	const char* const*				ppEnabledExtensionNames;
98 		DE_NULL,											//	const VkPhysicalDeviceFeatures*	pEnabledFeatures;
99 	};
100 
101 	const auto								device			= createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceInfo);
102 
103 	de::MovePtr<vk::DeviceDriver>			vkd				(new vk::DeviceDriver(vkp, instance, device.get(), m_context.getUsedApiVersion()));
104 	const auto&								vk				= *vkd.get();
105 
106 	const std::vector<std::string> functions = {
107 		// VK_EXT_extended_dynamic_state
108 		"vkCmdBindVertexBuffers2EXT",
109 		"vkCmdSetCullModeEXT",
110 		"vkCmdSetDepthBoundsTestEnableEXT",
111 		"vkCmdSetDepthCompareOpEXT",
112 		"vkCmdSetDepthTestEnableEXT",
113 		"vkCmdSetDepthWriteEnableEXT",
114 		"vkCmdSetFrontFaceEXT",
115 		"vkCmdSetPrimitiveTopologyEXT",
116 		"vkCmdSetScissorWithCountEXT",
117 		"vkCmdSetStencilOpEXT",
118 		"vkCmdSetStencilTestEnableEXT",
119 		"vkCmdSetViewportWithCountEXT",
120 		// VK_EXT_extended_dynamic_state2
121 		"vkCmdSetDepthBiasEnableEXT",
122 		"vkCmdSetLogicOpEXT",
123 		"vkCmdSetPatchControlPointsEXT",
124 		"vkCmdSetPrimitiveRestartEnableEXT",
125 		"vkCmdSetRasterizerDiscardEnableEXT",
126 		// VK_EXT_extended_dynamic_state3
127 		"vkCmdSetAlphaToCoverageEnableEXT",
128 		"vkCmdSetAlphaToOneEnableEXT",
129 		"vkCmdSetColorBlendAdvancedEXT",
130 		"vkCmdSetColorBlendEnableEXT",
131 		"vkCmdSetColorBlendEquationEXT",
132 		"vkCmdSetColorWriteMaskEXT",
133 		"vkCmdSetConservativeRasterizationModeEXT",
134 		"vkCmdSetCoverageModulationModeNV",
135 		"vkCmdSetCoverageModulationTableEnableNV",
136 		"vkCmdSetCoverageModulationTableNV",
137 		"vkCmdSetCoverageReductionModeNV",
138 		"vkCmdSetCoverageToColorEnableNV",
139 		"vkCmdSetCoverageToColorLocationNV",
140 		"vkCmdSetDepthClampEnableEXT",
141 		"vkCmdSetDepthClipEnableEXT",
142 		"vkCmdSetDepthClipNegativeOneToOneEXT",
143 		"vkCmdSetExtraPrimitiveOverestimationSizeEXT",
144 		"vkCmdSetLineRasterizationModeEXT",
145 		"vkCmdSetLineStippleEnableEXT",
146 		"vkCmdSetLogicOpEnableEXT",
147 		"vkCmdSetPolygonModeEXT",
148 		"vkCmdSetProvokingVertexModeEXT",
149 		"vkCmdSetRasterizationSamplesEXT",
150 		"vkCmdSetRasterizationStreamEXT",
151 		"vkCmdSetRepresentativeFragmentTestEnableNV",
152 		"vkCmdSetSampleLocationsEnableEXT",
153 		"vkCmdSetSampleMaskEXT",
154 		"vkCmdSetShadingRateImageEnableNV",
155 		"vkCmdSetTessellationDomainOriginEXT",
156 		"vkCmdSetViewportSwizzleNV",
157 		"vkCmdSetViewportWScalingEnableNV",
158 		// VK_EXT_vertex_input_dynamic_state
159 		"vkCmdSetVertexInputEXT",
160 	};
161 
162 	for (const auto& func : functions)
163 	{
164 		const auto& f = vk.getDeviceProcAddr(*device, func.c_str());
165 		if (f == DE_NULL)
166 			return tcu::TestStatus::fail("Failed: " + func);
167 	}
168 
169 	return tcu::TestStatus::pass("Pass");
170 }
171 
172 class ShaderObjectApiCase : public vkt::TestCase
173 {
174 public:
ShaderObjectApiCase(tcu::TestContext & testCtx,const std::string & name)175 					ShaderObjectApiCase		(tcu::TestContext& testCtx, const std::string& name)
176 						: vkt::TestCase		(testCtx, name)
177 						{}
~ShaderObjectApiCase(void)178 	virtual			~ShaderObjectApiCase	(void) {}
179 
180 	void			checkSupport			(vkt::Context& context) const override;
createInstance(Context & context) const181 	TestInstance*	createInstance			(Context& context) const override { return new ShaderObjectApiInstance(context); }
182 };
183 
checkSupport(Context & context) const184 void ShaderObjectApiCase::checkSupport (Context& context) const
185 {
186 	context.requireDeviceFunctionality("VK_EXT_shader_object");
187 }
188 
189 class ShaderObjectExtensionVersionInstance : public vkt::TestInstance
190 {
191 public:
ShaderObjectExtensionVersionInstance(Context & context,const ShaderObjectApiTest test)192 						ShaderObjectExtensionVersionInstance	(Context& context, const ShaderObjectApiTest test)
193 							: vkt::TestInstance	(context)
194 							, m_test			(test)
195 							{}
~ShaderObjectExtensionVersionInstance(void)196 	virtual				~ShaderObjectExtensionVersionInstance	(void) {}
197 
198 	tcu::TestStatus		iterate									(void) override;
199 private:
200 	ShaderObjectApiTest m_test;
201 };
202 
iterate(void)203 tcu::TestStatus ShaderObjectExtensionVersionInstance::iterate (void)
204 {
205 	vk::VkInstance									instance		= m_context.getInstance();
206 	vk::InstanceDriver								instanceDriver	(m_context.getPlatformInterface(), instance);
207 	vk::VkPhysicalDevice							physicalDevice  = m_context.getPhysicalDevice();
208 	const vk::InstanceInterface&					vki				= m_context.getInstanceInterface();
209 	const vk::ApiVersion							deviceVersion	= vk::unpackVersion(m_context.getDeviceVersion());
210 	tcu::TestLog&									log				= m_context.getTestContext().getLog();
211 
212 	vk::VkPhysicalDeviceShaderObjectPropertiesEXT	shaderObjectProperties = vk::initVulkanStructure();
213 
214 	vk::VkPhysicalDeviceProperties					properties;
215 	deMemset(&properties, 0, sizeof(vk::VkPhysicalDeviceProperties));
216 	vk::VkPhysicalDeviceProperties2					properties2 =
217 	{
218 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,			// VkStructureType					sType
219 		&shaderObjectProperties,									// const void*						pNext
220 		properties													// VkPhysicalDeviceProperties		properties
221 	};
222 
223 	instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &properties2);
224 
225 	const std::vector<vk::VkExtensionProperties>&				deviceExtensionProperties = enumerateCachedDeviceExtensionProperties(vki, physicalDevice);
226 
227 	if (m_test == SHADER_BINARY_UUID)
228 	{
229 		bool nonZero = false;
230 		for (deUint32 i = 0; i < VK_UUID_SIZE; ++i)
231 		{
232 			if (shaderObjectProperties.shaderBinaryUUID[i] != 0)
233 			{
234 				nonZero = true;
235 				break;
236 			}
237 		}
238 		if (!nonZero)
239 		{
240 			log << tcu::TestLog::Message << "All shaderBinaryUUID bytes are 0" << tcu::TestLog::EndMessage;
241 			return tcu::TestStatus::fail("Fail");
242 		}
243 	}
244 	else if (m_test == KHR_DYNAMIC_RENDERING)
245 	{
246 		if (deviceVersion.majorNum == 1 && deviceVersion.minorNum < 3)
247 		{
248 			bool found = false;
249 			for (const auto& ext : deviceExtensionProperties)
250 			{
251 				if (strcmp(ext.extensionName, "VK_KHR_dynamic_rendering") == 0)
252 				{
253 					found = true;
254 					break;
255 				}
256 			}
257 			if (!found)
258 			{
259 				log << tcu::TestLog::Message << "VK_EXT_shader_object is supported, but vulkan version is < 1.3 and VK_KHR_dynamic_rendering is not supported" << tcu::TestLog::EndMessage;
260 				return tcu::TestStatus::fail("Fail");
261 			}
262 		}
263 	}
264 	else
265 	{
266 		for (const auto& ext : deviceExtensionProperties)
267 		{
268 			if (m_test == EXT_DISCARD_RECTANGLES)
269 			{
270 				if (strcmp(ext.extensionName, "VK_EXT_discard_rectangles") == 0)
271 				{
272 					if (ext.specVersion < 2)
273 					{
274 						log << tcu::TestLog::Message << "VK_EXT_shader_object and VK_EXT_discard_rectangles are supported, but VK_EXT_discard_rectangles reports version " << ext.specVersion << tcu::TestLog::EndMessage;
275 						return tcu::TestStatus::fail("Fail");
276 					}
277 					break;
278 				}
279 			}
280 			else if (m_test == NV_SCISSOR_EXCLUSIVE)
281 			{
282 				if (strcmp(ext.extensionName, "VK_NV_scissor_exclusive") == 0)
283 				{
284 					if (ext.specVersion < 2)
285 					{
286 						log << tcu::TestLog::Message << "VK_EXT_shader_object and VK_NV_scissor_exclusive are supported, but VK_NV_scissor_exclusive reports version " << ext.specVersion << tcu::TestLog::EndMessage;
287 						return tcu::TestStatus::fail("Fail");
288 					}
289 					break;
290 				}
291 			}
292 		}
293 	}
294 	return tcu::TestStatus::pass("Pass");
295 }
296 
297 class ShaderObjectExtensionVersionCase : public vkt::TestCase
298 {
299 public:
ShaderObjectExtensionVersionCase(tcu::TestContext & testCtx,const std::string & name,const ShaderObjectApiTest test)300 					ShaderObjectExtensionVersionCase	(tcu::TestContext& testCtx, const std::string& name, const ShaderObjectApiTest test)
301 						: vkt::TestCase					(testCtx, name)
302 						, m_test						(test)
303 						{}
~ShaderObjectExtensionVersionCase(void)304 	virtual			~ShaderObjectExtensionVersionCase	(void) {}
305 
306 	void			checkSupport						(vkt::Context& context) const override;
createInstance(Context & context) const307 	TestInstance*	createInstance						(Context& context) const override { return new ShaderObjectExtensionVersionInstance(context, m_test); }
308 private:
309 	ShaderObjectApiTest m_test;
310 };
311 
checkSupport(Context & context) const312 void ShaderObjectExtensionVersionCase::checkSupport(Context& context) const
313 {
314 	context.requireDeviceFunctionality("VK_EXT_shader_object");
315 	if (m_test == EXT_DISCARD_RECTANGLES)
316 	{
317 		context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
318 	}
319 	else if (m_test == NV_SCISSOR_EXCLUSIVE)
320 	{
321 		context.requireDeviceFunctionality("VK_NV_scissor_exclusive");
322 	}
323 }
324 }
325 
createShaderObjectApiTests(tcu::TestContext & testCtx)326 tcu::TestCaseGroup* createShaderObjectApiTests (tcu::TestContext& testCtx)
327 {
328 	de::MovePtr<tcu::TestCaseGroup> apiGroup(new tcu::TestCaseGroup(testCtx, "api"));
329 	apiGroup->addChild(new ShaderObjectApiCase(testCtx, "get_device_proc_addr"));
330 
331 	const struct
332 	{
333 		ShaderObjectApiTest		test;
334 		const char*				name;
335 	} apiTests[] =
336 	{
337 		{ EXT_DISCARD_RECTANGLES,	"discard_rectangles"	},
338 		{ NV_SCISSOR_EXCLUSIVE,		"scissor_exclusive"		},
339 		{ KHR_DYNAMIC_RENDERING,	"dynamic_rendering"		},
340 		{ SHADER_BINARY_UUID,		"shader_binary_uuid"	},
341 	};
342 
343 	for (const auto& test : apiTests)
344 	{
345 		apiGroup->addChild(new ShaderObjectExtensionVersionCase(testCtx, test.name, test.test));
346 	}
347 	return apiGroup.release();
348 }
349 
350 } // ShaderObject
351 } // vkt
352