1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 Google Inc.
6 * Copyright (c) 2023 LunarG, Inc.
7 * Copyright (c) 2023 Nintendo
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Vulkan test case base classes
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktTestCase.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkDeviceUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkDebugReportUtil.hpp"
36 #include "vkDeviceFeatures.hpp"
37 #include "vkDeviceProperties.hpp"
38 #ifdef CTS_USES_VULKANSC
39 #include "vkSafetyCriticalUtil.hpp"
40 #include "vkAppParamsUtil.hpp"
41 #endif // CTS_USES_VULKANSC
42
43 #include "tcuCommandLine.hpp"
44 #include "tcuTestLog.hpp"
45
46 #include "deSTLUtil.hpp"
47 #include "deMemory.h"
48
49 #include <set>
50 #include <cstring>
51 #include <iterator>
52 #include <algorithm>
53
54 namespace vkt
55 {
56
57 // Default device utilities
58
59 using std::vector;
60 using std::string;
61 using std::set;
62 using namespace vk;
63
64 namespace
65 {
66
filterExtensions(const vector<VkExtensionProperties> & extensions)67 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
68 {
69 vector<string> enabledExtensions;
70 bool khrBufferDeviceAddress = false;
71 bool excludeExtension = false;
72
73 const char* extensionGroups[] =
74 {
75 "VK_KHR_",
76 "VK_EXT_",
77 "VK_KHX_",
78 "VK_OHOS_",
79 "VK_NV_cooperative_matrix",
80 "VK_NV_ray_tracing",
81 "VK_NV_inherited_viewport_scissor",
82 "VK_NV_mesh_shader",
83 "VK_AMD_mixed_attachment_samples",
84 "VK_AMD_buffer_marker",
85 "VK_AMD_shader_explicit_vertex_parameter",
86 "VK_AMD_shader_image_load_store_lod",
87 "VK_AMD_shader_trinary_minmax",
88 "VK_AMD_texture_gather_bias_lod",
89 "VK_AMD_shader_early_and_late_fragment_tests",
90 "VK_ANDROID_external_memory_android_hardware_buffer",
91 "VK_VALVE_mutable_descriptor_type",
92 "VK_NV_shader_subgroup_partitioned",
93 "VK_NV_clip_space_w_scaling",
94 "VK_NV_scissor_exclusive",
95 "VK_NV_shading_rate_image",
96 "VK_ARM_rasterization_order_attachment_access",
97 "VK_GOOGLE_surfaceless_query",
98 "VK_FUCHSIA_",
99 "VK_NV_fragment_coverage_to_color",
100 "VK_NV_framebuffer_mixed_samples",
101 "VK_NV_coverage_reduction_mode",
102 "VK_NV_viewport_swizzle",
103 "VK_NV_representative_fragment_test",
104 };
105
106 const char* exclusions[] =
107 {
108 "VK_EXT_device_address_binding_report",
109 "VK_EXT_device_memory_report"
110 };
111
112 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
113 {
114 if (deStringEqual(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address"))
115 {
116 khrBufferDeviceAddress = true;
117 break;
118 }
119 }
120
121 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
122 {
123 const auto& extName = extensions[extNdx].extensionName;
124
125 excludeExtension = false;
126
127 // VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
128 if (khrBufferDeviceAddress && deStringEqual(extName, "VK_EXT_buffer_device_address"))
129 continue;
130
131 for (int exclusionsNdx = 0; exclusionsNdx < DE_LENGTH_OF_ARRAY(exclusions); exclusionsNdx++)
132 {
133 if (deStringEqual(extName, exclusions[exclusionsNdx]))
134 {
135 excludeExtension = true;
136 break;
137 }
138 }
139
140 if (excludeExtension)
141 continue;
142
143 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
144 {
145 if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
146 enabledExtensions.push_back(extName);
147 }
148 }
149
150 return enabledExtensions;
151 }
152
addExtensions(const vector<string> & a,const vector<const char * > & b)153 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
154 {
155 vector<string> res (a);
156
157 for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
158 {
159 if (!de::contains(res.begin(), res.end(), string(*bIter)))
160 res.push_back(string(*bIter));
161 }
162
163 return res;
164 }
165
addCoreInstanceExtensions(const vector<string> & extensions,deUint32 instanceVersion)166 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
167 {
168 vector<const char*> coreExtensions;
169 getCoreInstanceExtensions(instanceVersion, coreExtensions);
170 return addExtensions(extensions, coreExtensions);
171 }
172
addCoreDeviceExtensions(const vector<string> & extensions,deUint32 instanceVersion)173 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
174 {
175 vector<const char*> coreExtensions;
176 getCoreDeviceExtensions(instanceVersion, coreExtensions);
177 return addExtensions(extensions, coreExtensions);
178 }
179
getTargetInstanceVersion(const PlatformInterface & vkp)180 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
181 {
182 deUint32 version = pack(ApiVersion(0, 1, 0, 0));
183
184 if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
185 TCU_THROW(InternalError, "Enumerate instance version error");
186 #ifdef CTS_USES_VULKANSC
187 // Temporary workaround for Vulkan loader problem - currently Vulkan loader always returs API variant == 0
188 version = pack(ApiVersion(1, 1, 0, 0));
189 #endif
190 return version;
191 }
192
determineDeviceVersions(const PlatformInterface & vkp,deUint32 apiVersion,const tcu::CommandLine & cmdLine)193 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
194 {
195 Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion, cmdLine);
196 InstanceDriver preinterface (vkp, preinstance.get());
197
198 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get());
199 deUint32 lowestDeviceVersion = 0xFFFFFFFFu;
200 for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
201 {
202 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
203 if (props.apiVersion < lowestDeviceVersion)
204 lowestDeviceVersion = props.apiVersion;
205 }
206
207 const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine);
208 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, choosenDevice);
209 const deUint32 choosenDeviceVersion = props.apiVersion;
210
211 return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
212 }
213
214 // Remove extensions from a which are found in b.
removeExtensions(const vector<string> & a,const vector<const char * > & b)215 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
216 {
217 vector<string> res;
218 set<string> removeExts (b.begin(), b.end());
219
220 for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
221 {
222 if (!de::contains(removeExts, *aIter))
223 res.push_back(*aIter);
224 }
225
226 return res;
227 }
228
229 #ifndef CTS_USES_VULKANSC
createInstance(const PlatformInterface & vkp,deUint32 apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine,DebugReportRecorder * recorder)230 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine, DebugReportRecorder* recorder)
231 #else
232 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
233 #endif // CTS_USES_VULKANSC
234 {
235 #ifndef CTS_USES_VULKANSC
236 const bool isValidationEnabled = (recorder != nullptr);
237 #else
238 const bool isValidationEnabled = false;
239 #endif // CTS_USES_VULKANSC
240 vector<const char*> enabledLayers;
241
242 // \note Extensions in core are not explicitly enabled even though
243 // they are in the extension list advertised to tests.
244 vector<const char*> coreExtensions;
245 getCoreInstanceExtensions(apiVersion, coreExtensions);
246 const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
247
248 if (isValidationEnabled)
249 {
250 if (!isDebugReportSupported(vkp))
251 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
252
253 enabledLayers = vkt::getValidationLayers(vkp);
254 if (enabledLayers.empty())
255 TCU_THROW(NotSupportedError, "No validation layers found");
256 }
257
258 #ifndef CTS_USES_VULKANSC
259 return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, cmdLine, recorder);
260 #else
261 return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions, cmdLine);
262 #endif // CTS_USES_VULKANSC
263 }
264
createDefaultDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 queueIndex,deUint32 sparseQueueIndex,const VkPhysicalDeviceFeatures2 & enabledFeatures,const vector<const char * > & usedExtensions,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)265 Move<VkDevice> createDefaultDevice (const PlatformInterface& vkp,
266 VkInstance instance,
267 const InstanceInterface& vki,
268 VkPhysicalDevice physicalDevice,
269 deUint32 queueIndex,
270 deUint32 sparseQueueIndex,
271 const VkPhysicalDeviceFeatures2& enabledFeatures,
272 const vector<const char*>& usedExtensions,
273 const tcu::CommandLine& cmdLine,
274 de::SharedPtr<vk::ResourceInterface> resourceInterface)
275 {
276 VkDeviceQueueCreateInfo queueInfo[2];
277 VkDeviceCreateInfo deviceInfo;
278 vector<const char*> enabledLayers;
279 const float queuePriority = 1.0f;
280 const deUint32 numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
281
282 deMemset(&queueInfo, 0, sizeof(queueInfo));
283 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
284
285 if (cmdLine.isValidationEnabled())
286 {
287 enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
288 if (enabledLayers.empty())
289 TCU_THROW(NotSupportedError, "No validation layers found");
290 }
291
292 queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
293 queueInfo[0].pNext = DE_NULL;
294 queueInfo[0].flags = (VkDeviceQueueCreateFlags)0u;
295 queueInfo[0].queueFamilyIndex = queueIndex;
296 queueInfo[0].queueCount = 1u;
297 queueInfo[0].pQueuePriorities = &queuePriority;
298
299 if (numQueues > 1)
300 {
301 queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
302 queueInfo[1].pNext = DE_NULL;
303 queueInfo[1].flags = (VkDeviceQueueCreateFlags)0u;
304 queueInfo[1].queueFamilyIndex = sparseQueueIndex;
305 queueInfo[1].queueCount = 1u;
306 queueInfo[1].pQueuePriorities = &queuePriority;
307 }
308
309 // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
310 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
311 deviceInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : nullptr;
312 deviceInfo.queueCreateInfoCount = numQueues;
313 deviceInfo.pQueueCreateInfos = queueInfo;
314 deviceInfo.enabledExtensionCount = de::sizeU32(usedExtensions);
315 deviceInfo.ppEnabledExtensionNames = de::dataOrNull(usedExtensions);
316 deviceInfo.enabledLayerCount = de::sizeU32(enabledLayers);
317 deviceInfo.ppEnabledLayerNames = de::dataOrNull(enabledLayers);
318 deviceInfo.pEnabledFeatures = enabledFeatures.pNext ? nullptr : &enabledFeatures.features;
319
320 #ifdef CTS_USES_VULKANSC
321 // devices created for Vulkan SC must have VkDeviceObjectReservationCreateInfo structure defined in VkDeviceCreateInfo::pNext chain
322 VkDeviceObjectReservationCreateInfo dmrCI = resetDeviceObjectReservationCreateInfo();
323 VkPipelineCacheCreateInfo pcCI =
324 {
325 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
326 DE_NULL, // const void* pNext;
327 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
328 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
329 0U, // deUintptr initialDataSize;
330 DE_NULL // const void* pInitialData;
331 };
332
333 std::vector<VkPipelinePoolSize> poolSizes;
334 if (cmdLine.isSubProcess())
335 {
336 resourceInterface->importPipelineCacheData(vkp, instance, vki, physicalDevice, queueIndex);
337
338 dmrCI = resourceInterface->getStatMax();
339
340 if(resourceInterface->getCacheDataSize() > 0)
341 {
342 pcCI.initialDataSize = resourceInterface->getCacheDataSize();
343 pcCI.pInitialData = resourceInterface->getCacheData();
344 dmrCI.pipelineCacheCreateInfoCount = 1;
345 dmrCI.pPipelineCacheCreateInfos = &pcCI;
346 }
347
348 poolSizes = resourceInterface->getPipelinePoolSizes();
349 if (!poolSizes.empty())
350 {
351 dmrCI.pipelinePoolSizeCount = deUint32(poolSizes.size());
352 dmrCI.pPipelinePoolSizes = poolSizes.data();
353 }
354 }
355
356 dmrCI.pNext = deviceInfo.pNext;
357 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
358 if (findStructureInChain(dmrCI.pNext, getStructureType<VkPhysicalDeviceVulkanSC10Features>()) == nullptr)
359 {
360 sc10Features.pNext = &dmrCI;
361 deviceInfo.pNext = &sc10Features;
362 }
363 else
364 deviceInfo.pNext = &dmrCI;
365
366 vector<VkApplicationParametersEXT> appParams;
367 if (readApplicationParameters(appParams, cmdLine, false))
368 {
369 appParams[appParams.size() - 1].pNext = deviceInfo.pNext;
370 deviceInfo.pNext = &appParams[0];
371 }
372
373 VkFaultCallbackInfo faultCallbackInfo =
374 {
375 VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO, // VkStructureType sType;
376 DE_NULL, // void* pNext;
377 0U, // uint32_t faultCount;
378 nullptr, // VkFaultData* pFaults;
379 Context::faultCallbackFunction // PFN_vkFaultCallbackFunction pfnFaultCallback;
380 };
381
382 if (cmdLine.isSubProcess())
383 {
384 // XXX workaround incorrect constness on faultCallbackInfo.pNext.
385 faultCallbackInfo.pNext = const_cast<void *>(deviceInfo.pNext);
386 deviceInfo.pNext = &faultCallbackInfo;
387 }
388
389 #else
390 DE_UNREF(resourceInterface);
391 #endif // CTS_USES_VULKANSC
392
393 return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
394 }
395
396 } // anonymous
397
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)398 deUint32 findQueueFamilyIndexWithCaps(const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
399 {
400 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
401
402 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
403 {
404 deUint32 queueFlags = queueProps[queueNdx].queueFlags;
405 if ((queueFlags & requiredCaps) == requiredCaps && !(queueFlags & excludedCaps))
406 return (deUint32)queueNdx;
407 }
408
409 TCU_THROW(NotSupportedError, "No matching queue found");
410 }
411
412 class DefaultDevice
413 {
414 public:
415 DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine, de::SharedPtr<vk::ResourceInterface> resourceInterface);
416 ~DefaultDevice (void);
417
getInstance(void) const418 VkInstance getInstance (void) const { return *m_instance; }
getInstanceInterface(void) const419 const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; }
getMaximumFrameworkVulkanVersion(void) const420 deUint32 getMaximumFrameworkVulkanVersion (void) const { return m_maximumFrameworkVulkanVersion; }
getAvailableInstanceVersion(void) const421 deUint32 getAvailableInstanceVersion (void) const { return m_availableInstanceVersion; }
getUsedInstanceVersion(void) const422 deUint32 getUsedInstanceVersion (void) const { return m_usedInstanceVersion; }
getInstanceExtensions(void) const423 const vector<string>& getInstanceExtensions (void) const { return m_instanceExtensions; }
424
getPhysicalDevice(void) const425 VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; }
getDeviceVersion(void) const426 deUint32 getDeviceVersion (void) const { return m_deviceVersion; }
427
isDeviceFeatureInitialized(VkStructureType sType) const428 bool isDeviceFeatureInitialized (VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType); }
getDeviceFeatures(void) const429 const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures.getCoreFeatures2().features; }
getDeviceFeatures2(void) const430 const VkPhysicalDeviceFeatures2& getDeviceFeatures2 (void) const { return m_deviceFeatures.getCoreFeatures2(); }
getVulkan11Features(void) const431 const VkPhysicalDeviceVulkan11Features& getVulkan11Features (void) const { return m_deviceFeatures.getVulkan11Features(); }
getVulkan12Features(void) const432 const VkPhysicalDeviceVulkan12Features& getVulkan12Features (void) const { return m_deviceFeatures.getVulkan12Features(); }
433 #ifndef CTS_USES_VULKANSC
getVulkan13Features(void) const434 const VkPhysicalDeviceVulkan13Features& getVulkan13Features (void) const { return m_deviceFeatures.getVulkan13Features(); }
435 #endif // CTS_USES_VULKANSC
436
437 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
438
isDevicePropertyInitialized(VkStructureType sType) const439 bool isDevicePropertyInitialized (VkStructureType sType) const { return m_deviceProperties.isDevicePropertyInitialized(sType); }
getDeviceProperties(void) const440 const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties.getCoreProperties2().properties; }
getDeviceProperties2(void) const441 const VkPhysicalDeviceProperties2& getDeviceProperties2 (void) const { return m_deviceProperties.getCoreProperties2(); }
getDeviceVulkan11Properties(void) const442 const VkPhysicalDeviceVulkan11Properties& getDeviceVulkan11Properties (void) const { return m_deviceProperties.getVulkan11Properties(); }
getDeviceVulkan12Properties(void) const443 const VkPhysicalDeviceVulkan12Properties& getDeviceVulkan12Properties (void) const { return m_deviceProperties.getVulkan12Properties(); }
444 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const445 const VkPhysicalDeviceVulkan13Properties& getDeviceVulkan13Properties (void) const { return m_deviceProperties.getVulkan13Properties(); }
446 #endif // CTS_USES_VULKANSC
447 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const448 const VkPhysicalDeviceVulkanSC10Properties& getDeviceVulkanSC10Properties (void) const { return m_deviceProperties.getVulkanSC10Properties(); }
449 #endif // CTS_USES_VULKANSC
450
451 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
452
getDevice(void) const453 VkDevice getDevice (void) const { return *m_device; }
getDeviceInterface(void) const454 const DeviceInterface& getDeviceInterface (void) const { return *m_deviceInterface; }
getDeviceExtensions(void) const455 const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; }
getDeviceCreationExtensions(void) const456 const vector<const char*>& getDeviceCreationExtensions (void) const { return m_creationExtensions; }
getUsedApiVersion(void) const457 deUint32 getUsedApiVersion (void) const { return m_usedApiVersion; }
getUniversalQueueFamilyIndex(void) const458 deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; }
459 VkQueue getUniversalQueue (void) const;
getSparseQueueFamilyIndex(void) const460 deUint32 getSparseQueueFamilyIndex (void) const { return m_sparseQueueFamilyIndex; }
461 VkQueue getSparseQueue (void) const;
462
463 #ifndef CTS_USES_VULKANSC
hasDebugReportRecorder(void) const464 bool hasDebugReportRecorder (void) const { return m_debugReportRecorder.get() != nullptr; }
getDebugReportRecorder(void) const465 vk::DebugReportRecorder& getDebugReportRecorder (void) const { return *m_debugReportRecorder.get(); }
466 #endif // CTS_USES_VULKANSC
467
468 private:
469 #ifndef CTS_USES_VULKANSC
470 using DebugReportRecorderPtr = de::UniquePtr<vk::DebugReportRecorder>;
471 using DebugReportCallbackPtr = vk::Move<VkDebugReportCallbackEXT>;
472 #endif // CTS_USES_VULKANSC
473
474 const deUint32 m_maximumFrameworkVulkanVersion;
475 const deUint32 m_availableInstanceVersion;
476 const deUint32 m_usedInstanceVersion;
477
478 const std::pair<deUint32, deUint32> m_deviceVersions;
479 const deUint32 m_usedApiVersion;
480
481 #ifndef CTS_USES_VULKANSC
482 const DebugReportRecorderPtr m_debugReportRecorder;
483 #endif // CTS_USES_VULKANSC
484 const vector<string> m_instanceExtensions;
485 const Unique<VkInstance> m_instance;
486 #ifndef CTS_USES_VULKANSC
487 const InstanceDriver m_instanceInterface;
488 const DebugReportCallbackPtr m_debugReportCallback;
489 #else
490 const InstanceDriverSC m_instanceInterface;
491 #endif // CTS_USES_VULKANSC
492 const VkPhysicalDevice m_physicalDevice;
493 const deUint32 m_deviceVersion;
494
495 const vector<string> m_deviceExtensions;
496 const DeviceFeatures m_deviceFeatures;
497
498 const deUint32 m_universalQueueFamilyIndex;
499 const deUint32 m_sparseQueueFamilyIndex;
500 const DeviceProperties m_deviceProperties;
501 const vector<const char*> m_creationExtensions;
502
503 const Unique<VkDevice> m_device;
504 const de::MovePtr<DeviceDriver> m_deviceInterface;
505 };
506
507 namespace
508 {
509
sanitizeApiVersion(deUint32 v)510 deUint32 sanitizeApiVersion(deUint32 v)
511 {
512 return VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(v), VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0 );
513 }
514
515 #ifndef CTS_USES_VULKANSC
createDebugReportRecorder(const vk::PlatformInterface & vkp,bool printValidationErrors)516 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, bool printValidationErrors)
517 {
518 if (isDebugReportSupported(vkp))
519 return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
520 else
521 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
522 }
523 #endif // CTS_USES_VULKANSC
524
525 // Returns list of non-core extensions. Note the pointers in the result vector come from the extensions vector passed as an argument.
removeCoreExtensions(const deUint32 apiVersion,const vector<string> & extensions)526 vector<const char*> removeCoreExtensions (const deUint32 apiVersion, const vector<string>& extensions)
527 {
528 // Make vector of char ptrs.
529 vector<const char*> extensionPtrs;
530 extensionPtrs.reserve(extensions.size());
531 std::transform(begin(extensions), end(extensions), std::back_inserter(extensionPtrs), [](const string& s) { return s.c_str(); });
532
533 // Obtain the core extension list.
534 vector<const char*> coreExtensions;
535 getCoreDeviceExtensions(apiVersion, coreExtensions);
536
537 // Remove any extension found in the core extension list.
538 const auto isNonCoreExtension = [&coreExtensions](const char* extName) {
539 const auto isSameString = [&extName](const char* otherExtName) { return (std::strcmp(otherExtName, extName) == 0); };
540 return std::find_if(begin(coreExtensions), end(coreExtensions), isSameString) == end(coreExtensions);
541 };
542
543 vector<const char*> filteredExtensions;
544 std::copy_if(begin(extensionPtrs), end(extensionPtrs), std::back_inserter(filteredExtensions), isNonCoreExtension);
545 return filteredExtensions;
546 }
547
548 } // anonymous
549
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)550 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine, de::SharedPtr<vk::ResourceInterface> resourceInterface)
551 #ifndef CTS_USES_VULKANSC
552 : m_maximumFrameworkVulkanVersion (VK_API_MAX_FRAMEWORK_VERSION)
553 #else
554 : m_maximumFrameworkVulkanVersion (VKSC_API_MAX_FRAMEWORK_VERSION)
555 #endif // CTS_USES_VULKANSC
556 , m_availableInstanceVersion (getTargetInstanceVersion(vkPlatform))
557 , m_usedInstanceVersion (sanitizeApiVersion(minVulkanAPIVersion(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
558 , m_deviceVersions (determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
559 , m_usedApiVersion (sanitizeApiVersion(minVulkanAPIVersion(m_usedInstanceVersion, m_deviceVersions.first)))
560
561 #ifndef CTS_USES_VULKANSC
562 , m_debugReportRecorder (cmdLine.isValidationEnabled()
563 ? createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors())
564 : de::MovePtr<vk::DebugReportRecorder>())
565 #endif // CTS_USES_VULKANSC
566 , m_instanceExtensions (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
567 #ifndef CTS_USES_VULKANSC
568 , m_instance (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine, m_debugReportRecorder.get()))
569 #else
570 , m_instance (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
571 #endif // CTS_USES_VULKANSC
572
573 #ifndef CTS_USES_VULKANSC
574 , m_instanceInterface (vkPlatform, *m_instance)
575
576 , m_debugReportCallback (cmdLine.isValidationEnabled()
577 ? m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get())
578 : DebugReportCallbackPtr())
579 #else
580 , m_instanceInterface (vkPlatform, *m_instance, cmdLine, resourceInterface)
581 #endif // CTS_USES_VULKANSC
582 , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
583 , m_deviceVersion (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
584
585 , m_deviceExtensions (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
586 , m_deviceFeatures (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
587 , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
588 #ifndef CTS_USES_VULKANSC
589 , m_sparseQueueFamilyIndex (m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
590 #else
591 , m_sparseQueueFamilyIndex (0)
592 #endif // CTS_USES_VULKANSC
593 , m_deviceProperties (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
594 // When the default device is created, we remove the core extensions from the extension list, but those core extensions are
595 // still reported as part of Context::getDeviceExtensions(). If we need the list of extensions actually used when creating the
596 // default device, we can use Context::getDeviceCreationExtensions().
597 , m_creationExtensions (removeCoreExtensions(m_usedApiVersion, m_deviceExtensions))
598 , m_device (createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_creationExtensions, cmdLine, resourceInterface))
599 #ifndef CTS_USES_VULKANSC
600 , m_deviceInterface (de::MovePtr<DeviceDriver>(new DeviceDriver(vkPlatform, *m_instance, *m_device, m_usedApiVersion)))
601 #else
602 , m_deviceInterface (de::MovePtr<DeviceDriverSC>(new DeviceDriverSC(vkPlatform, *m_instance, *m_device, cmdLine, resourceInterface, getDeviceVulkanSC10Properties(), getDeviceProperties(), m_usedApiVersion)))
603 #endif // CTS_USES_VULKANSC
604 {
605 #ifndef CTS_USES_VULKANSC
606 DE_UNREF(resourceInterface);
607 #endif
608 DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
609 }
610
~DefaultDevice(void)611 DefaultDevice::~DefaultDevice (void)
612 {
613 }
614
getUniversalQueue(void) const615 VkQueue DefaultDevice::getUniversalQueue (void) const
616 {
617 return getDeviceQueue(*m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
618 }
619
getSparseQueue(void) const620 VkQueue DefaultDevice::getSparseQueue (void) const
621 {
622 if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
623 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
624
625 return getDeviceQueue(*m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
626 }
627
628 namespace
629 {
630 // Allocator utilities
631
createAllocator(DefaultDevice * device)632 vk::Allocator* createAllocator (DefaultDevice* device)
633 {
634 const auto& vki = device->getInstanceInterface();
635 const auto physicalDevice = device->getPhysicalDevice();
636 const auto memoryProperties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
637
638 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
639 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
640 }
641
642 } // anonymous
643
644 // Context
645
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection,de::SharedPtr<vk::ResourceInterface> resourceInterface)646 Context::Context (tcu::TestContext& testCtx,
647 const vk::PlatformInterface& platformInterface,
648 vk::BinaryCollection& progCollection,
649 de::SharedPtr<vk::ResourceInterface> resourceInterface )
650 : m_testCtx (testCtx)
651 , m_platformInterface (platformInterface)
652 , m_progCollection (progCollection)
653 , m_resourceInterface (resourceInterface)
654 , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine(), resourceInterface))
655 , m_allocator (createAllocator(m_device.get()))
656 , m_resultSetOnValidation (false)
657 {
658 }
659
~Context(void)660 Context::~Context (void)
661 {
662 }
663
getMaximumFrameworkVulkanVersion(void) const664 deUint32 Context::getMaximumFrameworkVulkanVersion (void) const { return m_device->getMaximumFrameworkVulkanVersion(); }
getAvailableInstanceVersion(void) const665 deUint32 Context::getAvailableInstanceVersion (void) const { return m_device->getAvailableInstanceVersion(); }
getInstanceExtensions(void) const666 const vector<string>& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); }
getInstance(void) const667 vk::VkInstance Context::getInstance (void) const { return m_device->getInstance(); }
getInstanceInterface(void) const668 const vk::InstanceInterface& Context::getInstanceInterface (void) const { return m_device->getInstanceInterface(); }
getPhysicalDevice(void) const669 vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); }
getDeviceVersion(void) const670 deUint32 Context::getDeviceVersion (void) const { return m_device->getDeviceVersion(); }
getDeviceFeatures(void) const671 const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); }
getDeviceFeatures2(void) const672 const vk::VkPhysicalDeviceFeatures2& Context::getDeviceFeatures2 (void) const { return m_device->getDeviceFeatures2(); }
getDeviceVulkan11Features(void) const673 const vk::VkPhysicalDeviceVulkan11Features& Context::getDeviceVulkan11Features (void) const { return m_device->getVulkan11Features(); }
getDeviceVulkan12Features(void) const674 const vk::VkPhysicalDeviceVulkan12Features& Context::getDeviceVulkan12Features (void) const { return m_device->getVulkan12Features(); }
675 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Features(void) const676 const vk::VkPhysicalDeviceVulkan13Features& Context::getDeviceVulkan13Features (void) const { return m_device->getVulkan13Features(); }
677 #endif // CTS_USES_VULKANSC
678 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Features(void) const679 const vk::VkPhysicalDeviceVulkanSC10Features& Context::getDeviceVulkanSC10Features (void) const { return m_device->getVulkanSC10Features(); }
680 #endif // CTS_USES_VULKANSC
681
isDeviceFunctionalitySupported(const std::string & extension) const682 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
683 {
684 // If extension was promoted to core then check using the core mechanism. This is required so that
685 // all core implementations have the functionality tested, even if they don't support the extension.
686 // (It also means that core-optional extensions will not be reported as supported unless the
687 // features are really supported if the CTS code adds all core extensions to the extension list).
688 deUint32 apiVersion = getUsedApiVersion();
689 if (isCoreDeviceExtension(apiVersion, extension))
690 {
691 if (apiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0))
692 {
693 // Check feature bits in extension-specific structures.
694 if (extension == "VK_KHR_multiview")
695 return !!m_device->getMultiviewFeatures().multiview;
696 if (extension == "VK_KHR_variable_pointers")
697 return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
698 if (extension == "VK_KHR_sampler_ycbcr_conversion")
699 return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
700 if (extension == "VK_KHR_shader_draw_parameters")
701 return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
702 }
703 else
704 {
705 // Check feature bits using the new Vulkan 1.2 structures.
706 const auto& vk11Features = m_device->getVulkan11Features();
707 if (extension == "VK_KHR_multiview")
708 return !!vk11Features.multiview;
709 if (extension == "VK_KHR_variable_pointers")
710 return !!vk11Features.variablePointersStorageBuffer;
711 if (extension == "VK_KHR_sampler_ycbcr_conversion")
712 return !!vk11Features.samplerYcbcrConversion;
713 if (extension == "VK_KHR_shader_draw_parameters")
714 return !!vk11Features.shaderDrawParameters;
715
716 const auto& vk12Features = m_device->getVulkan12Features();
717 if (extension == "VK_KHR_timeline_semaphore")
718 return !!vk12Features.timelineSemaphore;
719 if (extension == "VK_KHR_buffer_device_address")
720 return !!vk12Features.bufferDeviceAddress;
721 if (extension == "VK_EXT_descriptor_indexing")
722 return !!vk12Features.descriptorIndexing;
723 if (extension == "VK_KHR_draw_indirect_count")
724 return !!vk12Features.drawIndirectCount;
725 if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
726 return !!vk12Features.samplerMirrorClampToEdge;
727 if (extension == "VK_EXT_sampler_filter_minmax")
728 return !!vk12Features.samplerFilterMinmax;
729 if (extension == "VK_EXT_shader_viewport_index_layer")
730 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
731
732 #ifndef CTS_USES_VULKANSC
733 const auto& vk13Features = m_device->getVulkan13Features();
734 if (extension == "VK_EXT_inline_uniform_block")
735 return !!vk13Features.inlineUniformBlock;
736 if (extension == "VK_EXT_pipeline_creation_cache_control")
737 return !!vk13Features.pipelineCreationCacheControl;
738 if (extension == "VK_EXT_private_data")
739 return !!vk13Features.privateData;
740 if (extension == "VK_EXT_shader_demote_to_helper_invocation")
741 return !!vk13Features.shaderDemoteToHelperInvocation;
742 if (extension == "VK_KHR_shader_terminate_invocation")
743 return !!vk13Features.shaderTerminateInvocation;
744 if (extension == "VK_EXT_subgroup_size_control")
745 return !!vk13Features.subgroupSizeControl;
746 if (extension == "VK_KHR_synchronization2")
747 return !!vk13Features.synchronization2;
748 if (extension == "VK_EXT_texture_compression_astc_hdr")
749 return !!vk13Features.textureCompressionASTC_HDR;
750 if (extension == "VK_KHR_zero_initialize_workgroup_memory")
751 return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
752 if (extension == "VK_KHR_dynamic_rendering")
753 return !!vk13Features.dynamicRendering;
754 if (extension == "VK_KHR_shader_integer_dot_product")
755 return !!vk13Features.shaderIntegerDotProduct;
756 if (extension == "VK_KHR_maintenance4")
757 return !!vk13Features.maintenance4;
758 #endif // CTS_USES_VULKANSC
759
760 #ifdef CTS_USES_VULKANSC
761 const auto& vk12Properties = m_device->getDeviceVulkan12Properties();
762 if (extension == "VK_KHR_depth_stencil_resolve")
763 return (vk12Properties.supportedDepthResolveModes != VK_RESOLVE_MODE_NONE) && (vk12Properties.supportedStencilResolveModes != VK_RESOLVE_MODE_NONE);
764 #endif // CTS_USES_VULKANSC
765 }
766
767 // No feature flags to check.
768 return true;
769 }
770
771 // If this is not a core extension then just return whether the implementation says it's supported.
772 const auto& extensions = getDeviceExtensions();
773 return de::contains(extensions.begin(), extensions.end(), extension);
774 }
775
isInstanceFunctionalitySupported(const std::string & extension) const776 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
777 {
778 // NOTE: current implementation uses isInstanceExtensionSupported but
779 // this will change when some instance extensions will be promoted to the
780 // core; don't use isInstanceExtensionSupported directly, use this method instead
781 return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
782 }
783
784 #include "vkDeviceFeaturesForContextDefs.inl"
785
getDeviceProperties(void) const786 const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); }
getDeviceProperties2(void) const787 const vk::VkPhysicalDeviceProperties2& Context::getDeviceProperties2 (void) const { return m_device->getDeviceProperties2(); }
getDeviceVulkan11Properties(void) const788 const vk::VkPhysicalDeviceVulkan11Properties& Context::getDeviceVulkan11Properties (void) const { return m_device->getDeviceVulkan11Properties(); }
getDeviceVulkan12Properties(void) const789 const vk::VkPhysicalDeviceVulkan12Properties& Context::getDeviceVulkan12Properties (void) const { return m_device->getDeviceVulkan12Properties(); }
790 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const791 const vk::VkPhysicalDeviceVulkan13Properties& Context::getDeviceVulkan13Properties (void) const { return m_device->getDeviceVulkan13Properties(); }
792 #endif // CTS_USES_VULKANSC
793 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const794 const vk::VkPhysicalDeviceVulkanSC10Properties& Context::getDeviceVulkanSC10Properties (void) const { return m_device->getDeviceVulkanSC10Properties(); }
795 #endif // CTS_USES_VULKANSC
796
797 #include "vkDevicePropertiesForContextDefs.inl"
798
getDeviceExtensions(void) const799 const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); }
getDeviceCreationExtensions(void) const800 const vector<const char*>& Context::getDeviceCreationExtensions (void) const { return m_device->getDeviceCreationExtensions(); }
getDevice(void) const801 vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); }
getDeviceInterface(void) const802 const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); }
getUniversalQueueFamilyIndex(void) const803 deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); }
getUniversalQueue(void) const804 vk::VkQueue Context::getUniversalQueue (void) const { return m_device->getUniversalQueue(); }
getSparseQueueFamilyIndex(void) const805 deUint32 Context::getSparseQueueFamilyIndex (void) const { return m_device->getSparseQueueFamilyIndex(); }
getSparseQueue(void) const806 vk::VkQueue Context::getSparseQueue (void) const { return m_device->getSparseQueue(); }
getResourceInterface(void) const807 de::SharedPtr<vk::ResourceInterface> Context::getResourceInterface (void) const { return m_resourceInterface; }
getDefaultAllocator(void) const808 vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; }
getUsedApiVersion(void) const809 deUint32 Context::getUsedApiVersion (void) const { return m_device->getUsedApiVersion(); }
contextSupports(const deUint32 variantNum,const deUint32 majorNum,const deUint32 minorNum,const deUint32 patchNum) const810 bool Context::contextSupports (const deUint32 variantNum, const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
811 { return isApiVersionSupported(m_device->getUsedApiVersion(), VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNum)); }
contextSupports(const ApiVersion version) const812 bool Context::contextSupports (const ApiVersion version) const
813 { return isApiVersionSupported(m_device->getUsedApiVersion(), pack(version)); }
contextSupports(const deUint32 requiredApiVersionBits) const814 bool Context::contextSupports (const deUint32 requiredApiVersionBits) const
815 { return isApiVersionSupported(m_device->getUsedApiVersion(), requiredApiVersionBits); }
isDeviceFeatureInitialized(vk::VkStructureType sType) const816 bool Context::isDeviceFeatureInitialized (vk::VkStructureType sType) const
817 { return m_device->isDeviceFeatureInitialized(sType); }
isDevicePropertyInitialized(vk::VkStructureType sType) const818 bool Context::isDevicePropertyInitialized (vk::VkStructureType sType) const
819 { return m_device->isDevicePropertyInitialized(sType); }
820
requireDeviceFunctionality(const std::string & required) const821 bool Context::requireDeviceFunctionality (const std::string& required) const
822 {
823 if (!isDeviceFunctionalitySupported(required))
824 TCU_THROW(NotSupportedError, required + " is not supported");
825
826 return true;
827 }
828
requireInstanceFunctionality(const std::string & required) const829 bool Context::requireInstanceFunctionality (const std::string& required) const
830 {
831 if (!isInstanceFunctionalitySupported(required))
832 TCU_THROW(NotSupportedError, required + " is not supported");
833
834 return true;
835 }
836
837 struct DeviceCoreFeaturesTable
838 {
839 const char* featureName;
840 const deUint32 featureArrayIndex;
841 const deUint32 featureArrayOffset;
842 };
843
844 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
845 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME) { #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
846
847 const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] =
848 {
849 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS , robustBufferAccess ),
850 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32 , fullDrawIndexUint32 ),
851 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY , imageCubeArray ),
852 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND , independentBlend ),
853 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER , geometryShader ),
854 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER , tessellationShader ),
855 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING , sampleRateShading ),
856 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND , dualSrcBlend ),
857 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP , logicOp ),
858 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT , multiDrawIndirect ),
859 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE , drawIndirectFirstInstance ),
860 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP , depthClamp ),
861 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP , depthBiasClamp ),
862 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID , fillModeNonSolid ),
863 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS , depthBounds ),
864 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES , wideLines ),
865 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS , largePoints ),
866 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE , alphaToOne ),
867 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT , multiViewport ),
868 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY , samplerAnisotropy ),
869 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2 , textureCompressionETC2 ),
870 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR , textureCompressionASTC_LDR ),
871 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC , textureCompressionBC ),
872 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE , occlusionQueryPrecise ),
873 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY , pipelineStatisticsQuery ),
874 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS , vertexPipelineStoresAndAtomics ),
875 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS , fragmentStoresAndAtomics ),
876 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE , shaderTessellationAndGeometryPointSize ),
877 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED , shaderImageGatherExtended ),
878 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS , shaderStorageImageExtendedFormats ),
879 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE , shaderStorageImageMultisample ),
880 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT , shaderStorageImageReadWithoutFormat ),
881 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT , shaderStorageImageWriteWithoutFormat ),
882 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderUniformBufferArrayDynamicIndexing ),
883 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderSampledImageArrayDynamicIndexing ),
884 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderStorageBufferArrayDynamicIndexing ),
885 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderStorageImageArrayDynamicIndexing ),
886 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE , shaderClipDistance ),
887 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE , shaderCullDistance ),
888 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64 , shaderFloat64 ),
889 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64 , shaderInt64 ),
890 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16 , shaderInt16 ),
891 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY , shaderResourceResidency ),
892 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD , shaderResourceMinLod ),
893 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING , sparseBinding ),
894 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER , sparseResidencyBuffer ),
895 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D , sparseResidencyImage2D ),
896 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D , sparseResidencyImage3D ),
897 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES , sparseResidency2Samples ),
898 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES , sparseResidency4Samples ),
899 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES , sparseResidency8Samples ),
900 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES , sparseResidency16Samples ),
901 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED , sparseResidencyAliased ),
902 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE , variableMultisampleRate ),
903 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES , inheritedQueries ),
904 };
905
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)906 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
907 {
908 const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures();
909 const vk::VkBool32* featuresAvailableArray = (vk::VkBool32*)(&featuresAvailable);
910 const deUint32 requiredFeatureIndex = static_cast<deUint32>(requiredFeature);
911
912 DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
913 DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
914
915 if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
916 TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
917
918 return true;
919 }
920
921 #ifndef CTS_USES_VULKANSC
922
isExtendedStorageFormat(VkFormat format)923 static bool isExtendedStorageFormat (VkFormat format)
924 {
925 switch(format)
926 {
927 case VK_FORMAT_R8G8B8A8_UNORM:
928 case VK_FORMAT_R8G8B8A8_SNORM:
929 case VK_FORMAT_R8G8B8A8_UINT:
930 case VK_FORMAT_R8G8B8A8_SINT:
931 case VK_FORMAT_R32_UINT:
932 case VK_FORMAT_R32_SINT:
933 case VK_FORMAT_R32_SFLOAT:
934 case VK_FORMAT_R32G32_UINT:
935 case VK_FORMAT_R32G32_SINT:
936 case VK_FORMAT_R32G32_SFLOAT:
937 case VK_FORMAT_R32G32B32A32_UINT:
938 case VK_FORMAT_R32G32B32A32_SINT:
939 case VK_FORMAT_R32G32B32A32_SFLOAT:
940 case VK_FORMAT_R16G16B16A16_UINT:
941 case VK_FORMAT_R16G16B16A16_SINT:
942 case VK_FORMAT_R16G16B16A16_SFLOAT:
943 case VK_FORMAT_R16G16_SFLOAT:
944 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
945 case VK_FORMAT_R16_SFLOAT:
946 case VK_FORMAT_R16G16B16A16_UNORM:
947 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
948 case VK_FORMAT_R16G16_UNORM:
949 case VK_FORMAT_R8G8_UNORM:
950 case VK_FORMAT_R16_UNORM:
951 case VK_FORMAT_R8_UNORM:
952 case VK_FORMAT_R16G16B16A16_SNORM:
953 case VK_FORMAT_R16G16_SNORM:
954 case VK_FORMAT_R8G8_SNORM:
955 case VK_FORMAT_R16_SNORM:
956 case VK_FORMAT_R8_SNORM:
957 case VK_FORMAT_R16G16_SINT:
958 case VK_FORMAT_R8G8_SINT:
959 case VK_FORMAT_R16_SINT:
960 case VK_FORMAT_R8_SINT:
961 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
962 case VK_FORMAT_R16G16_UINT:
963 case VK_FORMAT_R8G8_UINT:
964 case VK_FORMAT_R16_UINT:
965 case VK_FORMAT_R8_UINT:
966 return true;
967 default:
968 return false;
969 }
970 }
971
isDepthFormat(VkFormat format)972 static bool isDepthFormat (VkFormat format)
973 {
974 switch(format)
975 {
976 case VK_FORMAT_D16_UNORM:
977 case VK_FORMAT_X8_D24_UNORM_PACK32:
978 case VK_FORMAT_D32_SFLOAT:
979 case VK_FORMAT_D16_UNORM_S8_UINT:
980 case VK_FORMAT_D24_UNORM_S8_UINT:
981 case VK_FORMAT_D32_SFLOAT_S8_UINT:
982 return true;
983 default:
984 return false;
985 }
986 }
987
getRequiredFormatProperties(const vk::VkFormat & format) const988 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat& format) const
989 {
990 vk::VkFormatProperties3 p;
991 p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
992 p.pNext = DE_NULL;
993
994 vk::VkFormatProperties properties;
995 getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
996 p.linearTilingFeatures = properties.linearTilingFeatures;
997 p.optimalTilingFeatures = properties.optimalTilingFeatures;
998 p.bufferFeatures = properties.bufferFeatures;
999
1000 const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures();
1001 if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
1002 {
1003 if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1004 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1005 if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1006 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1007 }
1008 if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
1009 {
1010 if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1011 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1012 if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1013 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1014 }
1015 if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1016 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1017 if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1018 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1019
1020 return p;
1021 }
1022
getFormatProperties(const vk::VkFormat & format) const1023 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat& format) const
1024 {
1025 if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
1026 {
1027 vk::VkFormatProperties3 p;
1028 p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1029 p.pNext = DE_NULL;
1030
1031 vk::VkFormatProperties2 properties;
1032 properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1033 properties.pNext = &p;
1034
1035 getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
1036 return p;
1037 }
1038 else
1039 return Context::getRequiredFormatProperties(format);
1040 }
1041
1042 #endif // CTS_USES_VULKANSC
1043
getInstanceProcAddr()1044 void* Context::getInstanceProcAddr ()
1045 {
1046 return (void*)m_platformInterface.getGetInstanceProcAddr();
1047 }
1048
isBufferDeviceAddressSupported(void) const1049 bool Context::isBufferDeviceAddressSupported(void) const
1050 {
1051 return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
1052 isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
1053 }
1054
1055 #ifndef CTS_USES_VULKANSC
1056
hasDebugReportRecorder() const1057 bool Context::hasDebugReportRecorder () const
1058 {
1059 return m_device->hasDebugReportRecorder();
1060 }
1061
getDebugReportRecorder() const1062 vk::DebugReportRecorder& Context::getDebugReportRecorder () const
1063 {
1064 return m_device->getDebugReportRecorder();
1065 }
1066
1067 #endif // CTS_USES_VULKANSC
1068
resetCommandPoolForVKSC(const VkDevice device,const VkCommandPool commandPool)1069 void Context::resetCommandPoolForVKSC (const VkDevice device,
1070 const VkCommandPool commandPool)
1071 {
1072 #ifdef CTS_USES_VULKANSC
1073 if (getDeviceVulkanSC10Properties().commandPoolResetCommandBuffer == VK_FALSE) {
1074 const DeviceInterface &vk = getDeviceInterface();
1075 VK_CHECK(vk.resetCommandPool(device, commandPool, 0u));
1076 }
1077 #else
1078 DE_UNREF(device);
1079 DE_UNREF(commandPool);
1080 #endif
1081 }
1082
getContextCommonData()1083 ContextCommonData Context::getContextCommonData() {
1084 return ContextCommonData {
1085 getInstanceInterface(),
1086 getDevice(),
1087 getDeviceInterface(),
1088 getPhysicalDevice(),
1089 getDefaultAllocator(),
1090 getUniversalQueueFamilyIndex(),
1091 getUniversalQueue()
1092 };
1093 }
1094
1095 #ifdef CTS_USES_VULKANSC
1096 std::vector<VkFaultData> Context::m_faultData;
1097 std::mutex Context::m_faultDataMutex;
1098
faultCallbackFunction(VkBool32 unrecordedFaults,uint32_t faultCount,const VkFaultData * pFaults)1099 void Context::faultCallbackFunction(VkBool32 unrecordedFaults,
1100 uint32_t faultCount,
1101 const VkFaultData* pFaults)
1102 {
1103 DE_UNREF(unrecordedFaults);
1104 std::lock_guard<std::mutex> lock(m_faultDataMutex);
1105
1106 // Append new faults to the vector
1107 for (deUint32 i = 0; i < faultCount; ++i) {
1108 VkFaultData faultData = pFaults[i];
1109 faultData.pNext = DE_NULL;
1110
1111 m_faultData.push_back(faultData);
1112 }
1113 }
1114 #endif // CTS_USES_VULKANSC
1115
1116 // TestCase
1117
initPrograms(SourceCollections &) const1118 void TestCase::initPrograms (SourceCollections&) const
1119 {
1120 }
1121
checkSupport(Context &) const1122 void TestCase::checkSupport (Context&) const
1123 {
1124 }
1125
delayedInit(void)1126 void TestCase::delayedInit (void)
1127 {
1128 }
1129
1130 #ifndef CTS_USES_VULKANSC
1131
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)1132 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
1133 {
1134 using DebugMessages = vk::DebugReportRecorder::MessageList;
1135
1136 const DebugMessages& messages = debugReportRecorder.getMessages();
1137 tcu::TestLog& log = context.getTestContext().getLog();
1138
1139 if (messages.size() > 0)
1140 {
1141 const tcu::ScopedLogSection section (log, "DebugMessages", "Debug Messages");
1142 int numErrors = 0;
1143
1144 for (const auto& msg : messages)
1145 {
1146 if (msg.shouldBeLogged())
1147 log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
1148
1149 if (msg.isError())
1150 numErrors += 1;
1151 }
1152
1153 debugReportRecorder.clearMessages();
1154
1155 if (numErrors > 0)
1156 {
1157 string errorMsg = de::toString(numErrors) + " API usage errors found";
1158 context.resultSetOnValidation(true);
1159 context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
1160 }
1161 }
1162 }
1163
1164 #endif // CTS_USES_VULKANSC
1165
1166 } // vkt
1167