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::set;
60 using std::string;
61 using std::vector;
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 "VK_KHR_",
75 "VK_EXT_",
76 "VK_KHX_",
77 "VK_NV_cooperative_matrix",
78 "VK_NV_ray_tracing",
79 "VK_NV_inherited_viewport_scissor",
80 "VK_NV_mesh_shader",
81 "VK_AMD_mixed_attachment_samples",
82 "VK_AMD_buffer_marker",
83 "VK_AMD_shader_explicit_vertex_parameter",
84 "VK_AMD_shader_image_load_store_lod",
85 "VK_AMD_shader_trinary_minmax",
86 "VK_AMD_texture_gather_bias_lod",
87 "VK_AMD_shader_early_and_late_fragment_tests",
88 "VK_ANDROID_external_memory_android_hardware_buffer",
89 "VK_ANDROID_external_format_resolve",
90 "VK_VALVE_mutable_descriptor_type",
91 "VK_NV_shader_subgroup_partitioned",
92 "VK_NV_clip_space_w_scaling",
93 "VK_NV_scissor_exclusive",
94 "VK_NV_shading_rate_image",
95 "VK_ARM_rasterization_order_attachment_access",
96 "VK_GOOGLE_surfaceless_query",
97 "VK_FUCHSIA_",
98 "VK_NV_fragment_coverage_to_color",
99 "VK_NV_framebuffer_mixed_samples",
100 "VK_NV_coverage_reduction_mode",
101 "VK_NV_viewport_swizzle",
102 "VK_NV_representative_fragment_test",
103 "VK_NV_device_generated_commands", // This filter also applies to _compute.
104 "VK_NV_shader_atomic_float16_vector",
105 "VK_MVK_macos_surface",
106 "VK_NV_raw_access_chains",
107 "VK_NV_linear_color_attachment",
108 "VK_NV_cooperative_matrix2",
109 };
110
111 const char *exclusions[] = {"VK_EXT_device_address_binding_report", "VK_EXT_device_memory_report"};
112
113 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
114 {
115 if (strcmp(extensions[extNdx].extensionName, "VK_KHR_buffer_device_address") == 0)
116 {
117 khrBufferDeviceAddress = true;
118 break;
119 }
120 }
121
122 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
123 {
124 const auto &extName = extensions[extNdx].extensionName;
125
126 excludeExtension = false;
127
128 // VK_EXT_buffer_device_address is deprecated and must not be enabled if VK_KHR_buffer_device_address is enabled
129 if (khrBufferDeviceAddress && strcmp(extName, "VK_EXT_buffer_device_address") == 0)
130 continue;
131
132 for (int exclusionsNdx = 0; exclusionsNdx < DE_LENGTH_OF_ARRAY(exclusions); exclusionsNdx++)
133 {
134 if (strcmp(extName, exclusions[exclusionsNdx]) == 0)
135 {
136 excludeExtension = true;
137 break;
138 }
139 }
140
141 if (excludeExtension)
142 continue;
143
144 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
145 {
146 if (deStringBeginsWith(extName, extensionGroups[extGroupNdx]))
147 enabledExtensions.push_back(extName);
148 }
149 }
150
151 return enabledExtensions;
152 }
153
addExtensions(const vector<string> & a,const vector<const char * > & b)154 vector<string> addExtensions(const vector<string> &a, const vector<const char *> &b)
155 {
156 vector<string> res(a);
157
158 for (vector<const char *>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
159 {
160 if (!de::contains(res.begin(), res.end(), string(*bIter)))
161 res.push_back(string(*bIter));
162 }
163
164 return res;
165 }
166
addCoreInstanceExtensions(const vector<string> & extensions,uint32_t instanceVersion)167 vector<string> addCoreInstanceExtensions(const vector<string> &extensions, uint32_t instanceVersion)
168 {
169 vector<const char *> coreExtensions;
170 getCoreInstanceExtensions(instanceVersion, coreExtensions);
171 return addExtensions(extensions, coreExtensions);
172 }
173
addCoreDeviceExtensions(const vector<string> & extensions,uint32_t instanceVersion)174 vector<string> addCoreDeviceExtensions(const vector<string> &extensions, uint32_t instanceVersion)
175 {
176 vector<const char *> coreExtensions;
177 getCoreDeviceExtensions(instanceVersion, coreExtensions);
178 return addExtensions(extensions, coreExtensions);
179 }
180
getTargetInstanceVersion(const PlatformInterface & vkp)181 uint32_t getTargetInstanceVersion(const PlatformInterface &vkp)
182 {
183 uint32_t version = pack(ApiVersion(0, 1, 0, 0));
184
185 if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
186 TCU_THROW(InternalError, "Enumerate instance version error");
187 #ifdef CTS_USES_VULKANSC
188 // Temporary workaround for Vulkan loader problem - currently Vulkan loader always returs API variant == 0
189 version = pack(ApiVersion(1, 1, 0, 0));
190 #endif
191 return version;
192 }
193
determineDeviceVersions(const PlatformInterface & vkp,uint32_t apiVersion,const tcu::CommandLine & cmdLine)194 std::pair<uint32_t, uint32_t> determineDeviceVersions(const PlatformInterface &vkp, uint32_t apiVersion,
195 const tcu::CommandLine &cmdLine)
196 {
197 Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion, cmdLine);
198 InstanceDriver preinterface(vkp, preinstance.get());
199
200 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get());
201 uint32_t lowestDeviceVersion = 0xFFFFFFFFu;
202 for (uint32_t deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
203 {
204 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
205 if (props.apiVersion < lowestDeviceVersion)
206 lowestDeviceVersion = props.apiVersion;
207 }
208
209 const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine);
210 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, choosenDevice);
211 const uint32_t choosenDeviceVersion = props.apiVersion;
212
213 return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
214 }
215
216 // Remove extensions from a which are found in b.
removeExtensions(const vector<string> & a,const vector<const char * > & b)217 vector<string> removeExtensions(const vector<string> &a, const vector<const char *> &b)
218 {
219 vector<string> res;
220 set<string> removeExts(b.begin(), b.end());
221
222 for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
223 {
224 if (!de::contains(removeExts, *aIter))
225 res.push_back(*aIter);
226 }
227
228 return res;
229 }
230
231 #ifndef CTS_USES_VULKANSC
createInstance(const PlatformInterface & vkp,uint32_t apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine,DebugReportRecorder * recorder)232 Move<VkInstance> createInstance(const PlatformInterface &vkp, uint32_t apiVersion,
233 const vector<string> &enabledExtensions, const tcu::CommandLine &cmdLine,
234 DebugReportRecorder *recorder)
235 #else
236 Move<VkInstance> createInstance(const PlatformInterface &vkp, uint32_t apiVersion,
237 const vector<string> &enabledExtensions, const tcu::CommandLine &cmdLine)
238 #endif // CTS_USES_VULKANSC
239 {
240 #ifndef CTS_USES_VULKANSC
241 const bool isValidationEnabled = (recorder != nullptr);
242 #else
243 const bool isValidationEnabled = false;
244 #endif // CTS_USES_VULKANSC
245 vector<const char *> enabledLayers;
246
247 // \note Extensions in core are not explicitly enabled even though
248 // they are in the extension list advertised to tests.
249 vector<const char *> coreExtensions;
250 getCoreInstanceExtensions(apiVersion, coreExtensions);
251 const auto nonCoreExtensions = removeExtensions(enabledExtensions, coreExtensions);
252
253 if (isValidationEnabled)
254 {
255 if (!isDebugUtilsSupported(vkp))
256 TCU_THROW(NotSupportedError, "VK_EXT_utils_report is not supported");
257
258 enabledLayers = vkt::getValidationLayers(vkp);
259 if (enabledLayers.empty())
260 TCU_THROW(NotSupportedError, "No validation layers found");
261 }
262
263 #ifndef CTS_USES_VULKANSC
264 return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)),
265 nonCoreExtensions, cmdLine, recorder);
266 #else
267 return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)),
268 nonCoreExtensions, cmdLine);
269 #endif // CTS_USES_VULKANSC
270 }
271
createDefaultDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,uint32_t universalQueueIndex,uint32_t sparseQueueIndex,int computeQueueIndex,int transferQueueIndex,const VkPhysicalDeviceFeatures2 & enabledFeatures,const vector<const char * > & usedExtensions,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)272 Move<VkDevice> createDefaultDevice(const PlatformInterface &vkp, VkInstance instance, const InstanceInterface &vki,
273 VkPhysicalDevice physicalDevice, uint32_t universalQueueIndex,
274 uint32_t sparseQueueIndex, int computeQueueIndex, int transferQueueIndex,
275 const VkPhysicalDeviceFeatures2 &enabledFeatures,
276 const vector<const char *> &usedExtensions, const tcu::CommandLine &cmdLine,
277 de::SharedPtr<vk::ResourceInterface> resourceInterface)
278 {
279 VkDeviceQueueCreateInfo queueInfo[4];
280 VkDeviceCreateInfo deviceInfo;
281 vector<const char *> enabledLayers;
282 const float queuePriority = 1.0f;
283 uint32_t numQueues = 1;
284
285 deMemset(&queueInfo, 0, sizeof(queueInfo));
286
287 // Always create the universal queue.
288 queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
289 queueInfo[0].pNext = nullptr;
290 queueInfo[0].flags = (VkDeviceQueueCreateFlags)0u;
291 queueInfo[0].queueFamilyIndex = universalQueueIndex;
292 queueInfo[0].queueCount = 1u;
293 queueInfo[0].pQueuePriorities = &queuePriority;
294
295 // And the optional queues if they differ from the "universal" queue, and are supported.
296 if (enabledFeatures.features.sparseBinding && (universalQueueIndex != sparseQueueIndex))
297 {
298 queueInfo[numQueues].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
299 queueInfo[numQueues].pNext = nullptr;
300 queueInfo[numQueues].flags = (VkDeviceQueueCreateFlags)0u;
301 queueInfo[numQueues].queueFamilyIndex = sparseQueueIndex;
302 queueInfo[numQueues].queueCount = 1u;
303 queueInfo[numQueues].pQueuePriorities = &queuePriority;
304 numQueues++;
305 }
306 if (computeQueueIndex != -1 && (universalQueueIndex != (uint32_t)computeQueueIndex))
307 {
308 queueInfo[numQueues].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
309 queueInfo[numQueues].pNext = nullptr;
310 queueInfo[numQueues].flags = (VkDeviceQueueCreateFlags)0u;
311 queueInfo[numQueues].queueFamilyIndex = computeQueueIndex;
312 queueInfo[numQueues].queueCount = 1u;
313 queueInfo[numQueues].pQueuePriorities = &queuePriority;
314 numQueues++;
315 }
316 if (transferQueueIndex != -1 && (universalQueueIndex != (uint32_t)transferQueueIndex))
317 {
318 queueInfo[numQueues].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
319 queueInfo[numQueues].pNext = nullptr;
320 queueInfo[numQueues].flags = (VkDeviceQueueCreateFlags)0u;
321 queueInfo[numQueues].queueFamilyIndex = transferQueueIndex;
322 queueInfo[numQueues].queueCount = 1u;
323 queueInfo[numQueues].pQueuePriorities = &queuePriority;
324 numQueues++;
325 }
326
327 if (cmdLine.isValidationEnabled())
328 {
329 enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
330 if (enabledLayers.empty())
331 TCU_THROW(NotSupportedError, "No validation layers found");
332 }
333
334 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
335 // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
336 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
337 deviceInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : nullptr;
338 deviceInfo.queueCreateInfoCount = numQueues;
339 deviceInfo.pQueueCreateInfos = queueInfo;
340 deviceInfo.enabledExtensionCount = de::sizeU32(usedExtensions);
341 deviceInfo.ppEnabledExtensionNames = de::dataOrNull(usedExtensions);
342 deviceInfo.enabledLayerCount = de::sizeU32(enabledLayers);
343 deviceInfo.ppEnabledLayerNames = de::dataOrNull(enabledLayers);
344 deviceInfo.pEnabledFeatures = enabledFeatures.pNext ? nullptr : &enabledFeatures.features;
345
346 #ifdef CTS_USES_VULKANSC
347 // devices created for Vulkan SC must have VkDeviceObjectReservationCreateInfo structure defined in VkDeviceCreateInfo::pNext chain
348 VkDeviceObjectReservationCreateInfo dmrCI = resetDeviceObjectReservationCreateInfo();
349 VkPipelineCacheCreateInfo pcCI = {
350 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
351 nullptr, // const void* pNext;
352 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
353 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
354 0U, // uintptr_t initialDataSize;
355 nullptr // const void* pInitialData;
356 };
357
358 std::vector<VkPipelinePoolSize> poolSizes;
359 if (cmdLine.isSubProcess())
360 {
361 resourceInterface->importPipelineCacheData(vkp, instance, vki, physicalDevice, universalQueueIndex);
362
363 dmrCI = resourceInterface->getStatMax();
364
365 if (resourceInterface->getCacheDataSize() > 0)
366 {
367 pcCI.initialDataSize = resourceInterface->getCacheDataSize();
368 pcCI.pInitialData = resourceInterface->getCacheData();
369 dmrCI.pipelineCacheCreateInfoCount = 1;
370 dmrCI.pPipelineCacheCreateInfos = &pcCI;
371 }
372
373 poolSizes = resourceInterface->getPipelinePoolSizes();
374 if (!poolSizes.empty())
375 {
376 dmrCI.pipelinePoolSizeCount = uint32_t(poolSizes.size());
377 dmrCI.pPipelinePoolSizes = poolSizes.data();
378 }
379 }
380
381 dmrCI.pNext = deviceInfo.pNext;
382 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
383 if (findStructureInChain(dmrCI.pNext, getStructureType<VkPhysicalDeviceVulkanSC10Features>()) == nullptr)
384 {
385 sc10Features.pNext = &dmrCI;
386 deviceInfo.pNext = &sc10Features;
387 }
388 else
389 deviceInfo.pNext = &dmrCI;
390
391 vector<VkApplicationParametersEXT> appParams;
392 if (readApplicationParameters(appParams, cmdLine, false))
393 {
394 appParams[appParams.size() - 1].pNext = deviceInfo.pNext;
395 deviceInfo.pNext = &appParams[0];
396 }
397
398 VkFaultCallbackInfo faultCallbackInfo = {
399 VK_STRUCTURE_TYPE_FAULT_CALLBACK_INFO, // VkStructureType sType;
400 nullptr, // void* pNext;
401 0U, // uint32_t faultCount;
402 nullptr, // VkFaultData* pFaults;
403 Context::faultCallbackFunction // PFN_vkFaultCallbackFunction pfnFaultCallback;
404 };
405
406 if (cmdLine.isSubProcess())
407 {
408 // XXX workaround incorrect constness on faultCallbackInfo.pNext.
409 faultCallbackInfo.pNext = const_cast<void *>(deviceInfo.pNext);
410 deviceInfo.pNext = &faultCallbackInfo;
411 }
412
413 #else
414 DE_UNREF(resourceInterface);
415 #endif // CTS_USES_VULKANSC
416
417 return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
418 }
419
420 } // namespace
421
findQueueFamilyIndexWithCapsNoThrow(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)422 int findQueueFamilyIndexWithCapsNoThrow(const InstanceInterface &vkInstance, VkPhysicalDevice physicalDevice,
423 VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
424 {
425 try
426 {
427 return static_cast<int>(findQueueFamilyIndexWithCaps(vkInstance, physicalDevice, requiredCaps, excludedCaps));
428 }
429 catch (const tcu::NotSupportedError &)
430 {
431 return -1;
432 }
433 }
434
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps,VkQueueFlags excludedCaps)435 uint32_t findQueueFamilyIndexWithCaps(const InstanceInterface &vkInstance, VkPhysicalDevice physicalDevice,
436 VkQueueFlags requiredCaps, VkQueueFlags excludedCaps)
437 {
438 const vector<VkQueueFamilyProperties> queueProps =
439 getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
440
441 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
442 {
443 uint32_t queueFlags = queueProps[queueNdx].queueFlags;
444 if ((queueFlags & requiredCaps) == requiredCaps && !(queueFlags & excludedCaps))
445 return (uint32_t)queueNdx;
446 }
447
448 TCU_THROW(NotSupportedError, "No matching queue found");
449 }
450
451 class DefaultDevice
452 {
453 public:
454 DefaultDevice(const PlatformInterface &vkPlatform, const tcu::CommandLine &cmdLine,
455 de::SharedPtr<vk::ResourceInterface> resourceInterface);
456 ~DefaultDevice(void);
457
getInstance(void) const458 VkInstance getInstance(void) const
459 {
460 return *m_instance;
461 }
getInstanceInterface(void) const462 const InstanceInterface &getInstanceInterface(void) const
463 {
464 return m_instanceInterface;
465 }
getMaximumFrameworkVulkanVersion(void) const466 uint32_t getMaximumFrameworkVulkanVersion(void) const
467 {
468 return m_maximumFrameworkVulkanVersion;
469 }
getAvailableInstanceVersion(void) const470 uint32_t getAvailableInstanceVersion(void) const
471 {
472 return m_availableInstanceVersion;
473 }
getUsedInstanceVersion(void) const474 uint32_t getUsedInstanceVersion(void) const
475 {
476 return m_usedInstanceVersion;
477 }
getInstanceExtensions(void) const478 const vector<string> &getInstanceExtensions(void) const
479 {
480 return m_instanceExtensions;
481 }
482
getPhysicalDevice(void) const483 VkPhysicalDevice getPhysicalDevice(void) const
484 {
485 return m_physicalDevice;
486 }
getDeviceVersion(void) const487 uint32_t getDeviceVersion(void) const
488 {
489 return m_deviceVersion;
490 }
491
isDeviceFeatureInitialized(VkStructureType sType) const492 bool isDeviceFeatureInitialized(VkStructureType sType) const
493 {
494 return m_deviceFeatures.isDeviceFeatureInitialized(sType);
495 }
getDeviceFeatures(void) const496 const VkPhysicalDeviceFeatures &getDeviceFeatures(void) const
497 {
498 return m_deviceFeatures.getCoreFeatures2().features;
499 }
getDeviceFeatures2(void) const500 const VkPhysicalDeviceFeatures2 &getDeviceFeatures2(void) const
501 {
502 return m_deviceFeatures.getCoreFeatures2();
503 }
getVulkan11Features(void) const504 const VkPhysicalDeviceVulkan11Features &getVulkan11Features(void) const
505 {
506 return m_deviceFeatures.getVulkan11Features();
507 }
getVulkan12Features(void) const508 const VkPhysicalDeviceVulkan12Features &getVulkan12Features(void) const
509 {
510 return m_deviceFeatures.getVulkan12Features();
511 }
512 #ifndef CTS_USES_VULKANSC
getVulkan13Features(void) const513 const VkPhysicalDeviceVulkan13Features &getVulkan13Features(void) const
514 {
515 return m_deviceFeatures.getVulkan13Features();
516 }
getVulkan14Features(void) const517 const VkPhysicalDeviceVulkan14Features &getVulkan14Features(void) const
518 {
519 return m_deviceFeatures.getVulkan14Features();
520 }
521 #endif // CTS_USES_VULKANSC
522
523 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
524
isDevicePropertyInitialized(VkStructureType sType) const525 bool isDevicePropertyInitialized(VkStructureType sType) const
526 {
527 return m_deviceProperties.isDevicePropertyInitialized(sType);
528 }
getDeviceProperties(void) const529 const VkPhysicalDeviceProperties &getDeviceProperties(void) const
530 {
531 return m_deviceProperties.getCoreProperties2().properties;
532 }
getDeviceProperties2(void) const533 const VkPhysicalDeviceProperties2 &getDeviceProperties2(void) const
534 {
535 return m_deviceProperties.getCoreProperties2();
536 }
getDeviceVulkan11Properties(void) const537 const VkPhysicalDeviceVulkan11Properties &getDeviceVulkan11Properties(void) const
538 {
539 return m_deviceProperties.getVulkan11Properties();
540 }
getDeviceVulkan12Properties(void) const541 const VkPhysicalDeviceVulkan12Properties &getDeviceVulkan12Properties(void) const
542 {
543 return m_deviceProperties.getVulkan12Properties();
544 }
545 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const546 const VkPhysicalDeviceVulkan13Properties &getDeviceVulkan13Properties(void) const
547 {
548 return m_deviceProperties.getVulkan13Properties();
549 }
getDeviceVulkan14Properties(void) const550 const VkPhysicalDeviceVulkan14Properties &getDeviceVulkan14Properties(void) const
551 {
552 return m_deviceProperties.getVulkan14Properties();
553 }
554 #endif // CTS_USES_VULKANSC
555 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const556 const VkPhysicalDeviceVulkanSC10Properties &getDeviceVulkanSC10Properties(void) const
557 {
558 return m_deviceProperties.getVulkanSC10Properties();
559 }
560 #endif // CTS_USES_VULKANSC
561
562 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
563
getDevice(void) const564 VkDevice getDevice(void) const
565 {
566 return *m_device;
567 }
getDeviceInterface(void) const568 const DeviceInterface &getDeviceInterface(void) const
569 {
570 return *m_deviceInterface;
571 }
getDeviceExtensions(void) const572 const vector<string> &getDeviceExtensions(void) const
573 {
574 return m_deviceExtensions;
575 }
getDeviceCreationExtensions(void) const576 const vector<const char *> &getDeviceCreationExtensions(void) const
577 {
578 return m_creationExtensions;
579 }
getUsedApiVersion(void) const580 uint32_t getUsedApiVersion(void) const
581 {
582 return m_usedApiVersion;
583 }
getUniversalQueueFamilyIndex(void) const584 uint32_t getUniversalQueueFamilyIndex(void) const
585 {
586 return m_universalQueueFamilyIndex;
587 }
588 VkQueue getUniversalQueue(void) const;
getSparseQueueFamilyIndex(void) const589 uint32_t getSparseQueueFamilyIndex(void) const
590 {
591 return m_sparseQueueFamilyIndex;
592 }
593 VkQueue getSparseQueue(void) const;
getTransferQueueFamilyIndex(void) const594 int getTransferQueueFamilyIndex(void) const
595 {
596 return m_transferQueueFamilyIndex;
597 }
598 VkQueue getTransferQueue(void) const;
getComputeQueueFamilyIndex(void) const599 int getComputeQueueFamilyIndex(void) const
600 {
601 return m_computeQueueFamilyIndex;
602 }
603 VkQueue getComputeQueue(void) const;
604 #ifndef CTS_USES_VULKANSC
hasDebugReportRecorder(void) const605 bool hasDebugReportRecorder(void) const
606 {
607 return m_debugReportRecorder.get() != nullptr;
608 }
getDebugReportRecorder(void) const609 vk::DebugReportRecorder &getDebugReportRecorder(void) const
610 {
611 return *m_debugReportRecorder.get();
612 }
613 #endif // CTS_USES_VULKANSC
614
615 private:
616 #ifndef CTS_USES_VULKANSC
617 using DebugReportRecorderPtr = de::UniquePtr<vk::DebugReportRecorder>;
618 using DebugReportCallbackPtr = vk::Move<VkDebugUtilsMessengerEXT>;
619 #endif // CTS_USES_VULKANSC
620
621 const uint32_t m_maximumFrameworkVulkanVersion;
622 const uint32_t m_availableInstanceVersion;
623 const uint32_t m_usedInstanceVersion;
624
625 const std::pair<uint32_t, uint32_t> m_deviceVersions;
626 const uint32_t m_usedApiVersion;
627
628 #ifndef CTS_USES_VULKANSC
629 const DebugReportRecorderPtr m_debugReportRecorder;
630 #endif // CTS_USES_VULKANSC
631 const vector<string> m_instanceExtensions;
632 const Unique<VkInstance> m_instance;
633 #ifndef CTS_USES_VULKANSC
634 const InstanceDriver m_instanceInterface;
635 const DebugReportCallbackPtr m_debugReportCallback;
636 #else
637 const InstanceDriverSC m_instanceInterface;
638 #endif // CTS_USES_VULKANSC
639 const VkPhysicalDevice m_physicalDevice;
640 const uint32_t m_deviceVersion;
641
642 const vector<string> m_deviceExtensions;
643 const DeviceFeatures m_deviceFeatures;
644
645 const uint32_t m_universalQueueFamilyIndex;
646 const uint32_t m_sparseQueueFamilyIndex;
647
648 // Optional exclusive queues
649 const int m_computeQueueFamilyIndex;
650 const int m_transferQueueFamilyIndex;
651
652 const DeviceProperties m_deviceProperties;
653 const vector<const char *> m_creationExtensions;
654
655 const Unique<VkDevice> m_device;
656 const de::MovePtr<DeviceDriver> m_deviceInterface;
657 };
658
659 namespace
660 {
661
sanitizeApiVersion(uint32_t v)662 uint32_t sanitizeApiVersion(uint32_t v)
663 {
664 return VK_MAKE_API_VERSION(VK_API_VERSION_VARIANT(v), VK_API_VERSION_MAJOR(v), VK_API_VERSION_MINOR(v), 0);
665 }
666
667 #ifndef CTS_USES_VULKANSC
createDebugReportRecorder(const vk::PlatformInterface & vkp,bool printValidationErrors)668 de::MovePtr<vk::DebugReportRecorder> createDebugReportRecorder(const vk::PlatformInterface &vkp,
669 bool printValidationErrors)
670 {
671 if (isDebugUtilsSupported(vkp))
672 return de::MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(printValidationErrors));
673 else
674 TCU_THROW(NotSupportedError, "VK_EXT_debug_utils is not supported");
675 }
676 #endif // CTS_USES_VULKANSC
677
678 // Returns list of non-core extensions. Note the pointers in the result vector come from the extensions vector passed as an argument.
removeCoreExtensions(const uint32_t apiVersion,const vector<string> & extensions)679 vector<const char *> removeCoreExtensions(const uint32_t apiVersion, const vector<string> &extensions)
680 {
681 // Make vector of char ptrs.
682 vector<const char *> extensionPtrs;
683 extensionPtrs.reserve(extensions.size());
684 std::transform(begin(extensions), end(extensions), std::back_inserter(extensionPtrs),
685 [](const string &s) { return s.c_str(); });
686
687 // Obtain the core extension list.
688 vector<const char *> coreExtensions;
689 getCoreDeviceExtensions(apiVersion, coreExtensions);
690
691 // Remove any extension found in the core extension list.
692 const auto isNonCoreExtension = [&coreExtensions](const char *extName)
693 {
694 const auto isSameString = [&extName](const char *otherExtName)
695 { return (std::strcmp(otherExtName, extName) == 0); };
696 return std::find_if(begin(coreExtensions), end(coreExtensions), isSameString) == end(coreExtensions);
697 };
698
699 vector<const char *> filteredExtensions;
700 std::copy_if(begin(extensionPtrs), end(extensionPtrs), std::back_inserter(filteredExtensions), isNonCoreExtension);
701 return filteredExtensions;
702 }
703
704 } // namespace
705
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine,de::SharedPtr<vk::ResourceInterface> resourceInterface)706 DefaultDevice::DefaultDevice(const PlatformInterface &vkPlatform, const tcu::CommandLine &cmdLine,
707 de::SharedPtr<vk::ResourceInterface> resourceInterface)
708 #ifndef CTS_USES_VULKANSC
709 : m_maximumFrameworkVulkanVersion(VK_API_MAX_FRAMEWORK_VERSION)
710 #else
711 : m_maximumFrameworkVulkanVersion(VKSC_API_MAX_FRAMEWORK_VERSION)
712 #endif // CTS_USES_VULKANSC
713 , m_availableInstanceVersion(getTargetInstanceVersion(vkPlatform))
714 , m_usedInstanceVersion(
715 sanitizeApiVersion(minVulkanAPIVersion(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
716 , m_deviceVersions(determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
717 , m_usedApiVersion(sanitizeApiVersion(minVulkanAPIVersion(m_usedInstanceVersion, m_deviceVersions.first)))
718
719 #ifndef CTS_USES_VULKANSC
720 , m_debugReportRecorder(cmdLine.isValidationEnabled() ?
721 createDebugReportRecorder(vkPlatform, cmdLine.printValidationErrors()) :
722 de::MovePtr<vk::DebugReportRecorder>())
723 #endif // CTS_USES_VULKANSC
724 , m_instanceExtensions(addCoreInstanceExtensions(
725 filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, nullptr)), m_usedApiVersion))
726 #ifndef CTS_USES_VULKANSC
727 , m_instance(
728 createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine, m_debugReportRecorder.get()))
729 #else
730 , m_instance(createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
731 #endif // CTS_USES_VULKANSC
732
733 #ifndef CTS_USES_VULKANSC
734 , m_instanceInterface(vkPlatform, *m_instance)
735
736 , m_debugReportCallback(cmdLine.isValidationEnabled() ?
737 m_debugReportRecorder->createCallback(m_instanceInterface, m_instance.get()) :
738 DebugReportCallbackPtr())
739 #else
740 , m_instanceInterface(vkPlatform, *m_instance, cmdLine, resourceInterface)
741 #endif // CTS_USES_VULKANSC
742 , m_physicalDevice(chooseDevice(m_instanceInterface, *m_instance, cmdLine))
743 , m_deviceVersion(getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
744
745 , m_deviceExtensions(addCoreDeviceExtensions(
746 filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, nullptr)),
747 m_usedApiVersion))
748 , m_deviceFeatures(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions,
749 m_deviceExtensions)
750 , m_universalQueueFamilyIndex(findQueueFamilyIndexWithCaps(
751 m_instanceInterface, m_physicalDevice,
752 cmdLine.isComputeOnly() ? VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
753 #ifndef CTS_USES_VULKANSC
754 , m_sparseQueueFamilyIndex(
755 m_deviceFeatures.getCoreFeatures2().features.sparseBinding ?
756 findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) :
757 0)
758 #else
759 , m_sparseQueueFamilyIndex(0)
760 #endif // CTS_USES_VULKANSC
761 , m_computeQueueFamilyIndex(findQueueFamilyIndexWithCapsNoThrow(m_instanceInterface, m_physicalDevice,
762 VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT))
763 , m_transferQueueFamilyIndex(findQueueFamilyIndexWithCapsNoThrow(
764 m_instanceInterface, m_physicalDevice, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
765 , m_deviceProperties(m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions,
766 m_deviceExtensions)
767 // When the default device is created, we remove the core extensions from the extension list, but those core extensions are
768 // still reported as part of Context::getDeviceExtensions(). If we need the list of extensions actually used when creating the
769 // default device, we can use Context::getDeviceCreationExtensions().
770 , m_creationExtensions(removeCoreExtensions(m_usedApiVersion, m_deviceExtensions))
771 , m_device(createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice,
772 m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_computeQueueFamilyIndex,
773 m_transferQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(),
774 m_creationExtensions, cmdLine, resourceInterface))
775 #ifndef CTS_USES_VULKANSC
776 , m_deviceInterface(
777 de::MovePtr<DeviceDriver>(new DeviceDriver(vkPlatform, *m_instance, *m_device, m_usedApiVersion, cmdLine)))
778 #else
779 , m_deviceInterface(de::MovePtr<DeviceDriverSC>(
780 new DeviceDriverSC(vkPlatform, *m_instance, *m_device, cmdLine, resourceInterface,
781 getDeviceVulkanSC10Properties(), getDeviceProperties(), m_usedApiVersion)))
782 #endif // CTS_USES_VULKANSC
783 {
784 #ifndef CTS_USES_VULKANSC
785 DE_UNREF(resourceInterface);
786 #endif
787 DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
788 }
789
~DefaultDevice(void)790 DefaultDevice::~DefaultDevice(void)
791 {
792 }
793
getUniversalQueue(void) const794 VkQueue DefaultDevice::getUniversalQueue(void) const
795 {
796 return getDeviceQueue(*m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
797 }
798
getSparseQueue(void) const799 VkQueue DefaultDevice::getSparseQueue(void) const
800 {
801 if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
802 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
803
804 return getDeviceQueue(*m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
805 }
806
getComputeQueue(void) const807 VkQueue DefaultDevice::getComputeQueue(void) const
808 {
809 if (m_computeQueueFamilyIndex == -1)
810 TCU_THROW(NotSupportedError, "Exclusive compute queue not supported.");
811
812 return getDeviceQueue(*m_deviceInterface, *m_device, m_computeQueueFamilyIndex, 0);
813 }
814
getTransferQueue(void) const815 VkQueue DefaultDevice::getTransferQueue(void) const
816 {
817 if (m_transferQueueFamilyIndex == -1)
818 TCU_THROW(NotSupportedError, "Exclusive transfer queue not supported.");
819
820 return getDeviceQueue(*m_deviceInterface, *m_device, m_transferQueueFamilyIndex, 0);
821 }
822
823 namespace
824 {
825 // Allocator utilities
826
createAllocator(DefaultDevice * device)827 vk::Allocator *createAllocator(DefaultDevice *device)
828 {
829 const auto &vki = device->getInstanceInterface();
830 const auto physicalDevice = device->getPhysicalDevice();
831 const auto memoryProperties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
832
833 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
834 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
835 }
836
837 } // namespace
838
839 // Context
840
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection,de::SharedPtr<vk::ResourceInterface> resourceInterface)841 Context::Context(tcu::TestContext &testCtx, const vk::PlatformInterface &platformInterface,
842 vk::BinaryCollection &progCollection, de::SharedPtr<vk::ResourceInterface> resourceInterface)
843 : m_testCtx(testCtx)
844 , m_platformInterface(platformInterface)
845 , m_progCollection(progCollection)
846 , m_resourceInterface(resourceInterface)
847 , m_device(new DefaultDevice(m_platformInterface, testCtx.getCommandLine(), resourceInterface))
848 , m_allocator(createAllocator(m_device.get()))
849 , m_resultSetOnValidation(false)
850 {
851 }
852
~Context(void)853 Context::~Context(void)
854 {
855 }
856
getMaximumFrameworkVulkanVersion(void) const857 uint32_t Context::getMaximumFrameworkVulkanVersion(void) const
858 {
859 return m_device->getMaximumFrameworkVulkanVersion();
860 }
getAvailableInstanceVersion(void) const861 uint32_t Context::getAvailableInstanceVersion(void) const
862 {
863 return m_device->getAvailableInstanceVersion();
864 }
getInstanceExtensions(void) const865 const vector<string> &Context::getInstanceExtensions(void) const
866 {
867 return m_device->getInstanceExtensions();
868 }
getInstance(void) const869 vk::VkInstance Context::getInstance(void) const
870 {
871 return m_device->getInstance();
872 }
getInstanceInterface(void) const873 const vk::InstanceInterface &Context::getInstanceInterface(void) const
874 {
875 return m_device->getInstanceInterface();
876 }
getPhysicalDevice(void) const877 vk::VkPhysicalDevice Context::getPhysicalDevice(void) const
878 {
879 return m_device->getPhysicalDevice();
880 }
getDeviceVersion(void) const881 uint32_t Context::getDeviceVersion(void) const
882 {
883 return m_device->getDeviceVersion();
884 }
getDeviceFeatures(void) const885 const vk::VkPhysicalDeviceFeatures &Context::getDeviceFeatures(void) const
886 {
887 return m_device->getDeviceFeatures();
888 }
getDeviceFeatures2(void) const889 const vk::VkPhysicalDeviceFeatures2 &Context::getDeviceFeatures2(void) const
890 {
891 return m_device->getDeviceFeatures2();
892 }
getDeviceVulkan11Features(void) const893 const vk::VkPhysicalDeviceVulkan11Features &Context::getDeviceVulkan11Features(void) const
894 {
895 return m_device->getVulkan11Features();
896 }
getDeviceVulkan12Features(void) const897 const vk::VkPhysicalDeviceVulkan12Features &Context::getDeviceVulkan12Features(void) const
898 {
899 return m_device->getVulkan12Features();
900 }
901 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Features(void) const902 const vk::VkPhysicalDeviceVulkan13Features &Context::getDeviceVulkan13Features(void) const
903 {
904 return m_device->getVulkan13Features();
905 }
getDeviceVulkan14Features(void) const906 const vk::VkPhysicalDeviceVulkan14Features &Context::getDeviceVulkan14Features(void) const
907 {
908 return m_device->getVulkan14Features();
909 }
910 #endif // CTS_USES_VULKANSC
911 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Features(void) const912 const vk::VkPhysicalDeviceVulkanSC10Features &Context::getDeviceVulkanSC10Features(void) const
913 {
914 return m_device->getVulkanSC10Features();
915 }
916 #endif // CTS_USES_VULKANSC
917
isDeviceFunctionalitySupported(const std::string & extension) const918 bool Context::isDeviceFunctionalitySupported(const std::string &extension) const
919 {
920 // If extension was promoted to core then check using the core mechanism. This is required so that
921 // all core implementations have the functionality tested, even if they don't support the extension.
922 // (It also means that core-optional extensions will not be reported as supported unless the
923 // features are really supported if the CTS code adds all core extensions to the extension list).
924 uint32_t apiVersion = getUsedApiVersion();
925 if (isCoreDeviceExtension(apiVersion, extension))
926 {
927 if (apiVersion < VK_MAKE_API_VERSION(0, 1, 2, 0))
928 {
929 // Check feature bits in extension-specific structures.
930 if (extension == "VK_KHR_multiview")
931 return !!m_device->getMultiviewFeatures().multiview;
932 if (extension == "VK_KHR_variable_pointers")
933 return !!m_device->getVariablePointersFeatures().variablePointersStorageBuffer;
934 if (extension == "VK_KHR_sampler_ycbcr_conversion")
935 return !!m_device->getSamplerYcbcrConversionFeatures().samplerYcbcrConversion;
936 if (extension == "VK_KHR_shader_draw_parameters")
937 return !!m_device->getShaderDrawParametersFeatures().shaderDrawParameters;
938 }
939 else
940 {
941 // Check feature bits using the new Vulkan 1.2 structures.
942 const auto &vk11Features = m_device->getVulkan11Features();
943 if (extension == "VK_KHR_multiview")
944 return !!vk11Features.multiview;
945 if (extension == "VK_KHR_variable_pointers")
946 return !!vk11Features.variablePointersStorageBuffer;
947 if (extension == "VK_KHR_sampler_ycbcr_conversion")
948 return !!vk11Features.samplerYcbcrConversion;
949 if (extension == "VK_KHR_shader_draw_parameters")
950 return !!vk11Features.shaderDrawParameters;
951
952 const auto &vk12Features = m_device->getVulkan12Features();
953 if (extension == "VK_KHR_timeline_semaphore")
954 return !!vk12Features.timelineSemaphore;
955 if (extension == "VK_KHR_buffer_device_address")
956 return !!vk12Features.bufferDeviceAddress;
957 if (extension == "VK_EXT_descriptor_indexing")
958 return !!vk12Features.descriptorIndexing;
959 if (extension == "VK_KHR_draw_indirect_count")
960 return !!vk12Features.drawIndirectCount;
961 if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
962 return !!vk12Features.samplerMirrorClampToEdge;
963 if (extension == "VK_EXT_sampler_filter_minmax")
964 return !!vk12Features.samplerFilterMinmax;
965 if (extension == "VK_EXT_shader_viewport_index_layer")
966 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
967
968 #ifndef CTS_USES_VULKANSC
969 const auto &vk13Features = m_device->getVulkan13Features();
970 if (extension == "VK_EXT_inline_uniform_block")
971 return !!vk13Features.inlineUniformBlock;
972 if (extension == "VK_EXT_pipeline_creation_cache_control")
973 return !!vk13Features.pipelineCreationCacheControl;
974 if (extension == "VK_EXT_private_data")
975 return !!vk13Features.privateData;
976 if (extension == "VK_EXT_shader_demote_to_helper_invocation")
977 return !!vk13Features.shaderDemoteToHelperInvocation;
978 if (extension == "VK_KHR_shader_terminate_invocation")
979 return !!vk13Features.shaderTerminateInvocation;
980 if (extension == "VK_EXT_subgroup_size_control")
981 return !!vk13Features.subgroupSizeControl;
982 if (extension == "VK_KHR_synchronization2")
983 return !!vk13Features.synchronization2;
984 if (extension == "VK_EXT_texture_compression_astc_hdr")
985 return !!vk13Features.textureCompressionASTC_HDR;
986 if (extension == "VK_KHR_zero_initialize_workgroup_memory")
987 return !!vk13Features.shaderZeroInitializeWorkgroupMemory;
988 if (extension == "VK_KHR_dynamic_rendering")
989 return !!vk13Features.dynamicRendering;
990 if (extension == "VK_KHR_shader_integer_dot_product")
991 return !!vk13Features.shaderIntegerDotProduct;
992 if (extension == "VK_KHR_maintenance4")
993 return !!vk13Features.maintenance4;
994
995 const auto &vk14Features = m_device->getVulkan14Features();
996 if (extension == "VK_KHR_dynamic_rendering_local_read")
997 return !!vk14Features.dynamicRenderingLocalRead;
998 if (extension == "VK_KHR_global_priority")
999 return !!vk14Features.globalPriorityQuery;
1000 if (extension == "VK_KHR_index_type_uint8")
1001 return !!vk14Features.indexTypeUint8;
1002 if (extension == "VK_KHR_maintenance5")
1003 return !!vk14Features.maintenance5;
1004 if (extension == "VK_KHR_maintenance6")
1005 return !!vk14Features.maintenance6;
1006 if (extension == "VK_KHR_shader_expect_assume")
1007 return !!vk14Features.shaderExpectAssume;
1008 if (extension == "VK_KHR_shader_float_controls2")
1009 return !!vk14Features.shaderFloatControls2;
1010 if (extension == "VK_EXT_host_image_copy")
1011 return !!vk14Features.hostImageCopy;
1012 if (extension == "VK_EXT_pipeline_protected_access")
1013 return !!vk14Features.pipelineProtectedAccess;
1014 if (extension == "VK_EXT_pipeline_robustness")
1015 return !!vk14Features.pipelineRobustness;
1016 if (extension == "VK_KHR_push_descriptor")
1017 return !!vk14Features.pushDescriptor;
1018 #endif // CTS_USES_VULKANSC
1019
1020 #ifdef CTS_USES_VULKANSC
1021 const auto &vk12Properties = m_device->getDeviceVulkan12Properties();
1022 if (extension == "VK_KHR_depth_stencil_resolve")
1023 return (vk12Properties.supportedDepthResolveModes != VK_RESOLVE_MODE_NONE) &&
1024 (vk12Properties.supportedStencilResolveModes != VK_RESOLVE_MODE_NONE);
1025 #endif // CTS_USES_VULKANSC
1026 }
1027
1028 // No feature flags to check.
1029 return true;
1030 }
1031
1032 // If this is not a core extension then just return whether the implementation says it's supported.
1033 const auto &extensions = getDeviceExtensions();
1034 return de::contains(extensions.begin(), extensions.end(), extension);
1035 }
1036
isInstanceFunctionalitySupported(const std::string & extension) const1037 bool Context::isInstanceFunctionalitySupported(const std::string &extension) const
1038 {
1039 // NOTE: current implementation uses isInstanceExtensionSupported but
1040 // this will change when some instance extensions will be promoted to the
1041 // core; don't use isInstanceExtensionSupported directly, use this method instead
1042 return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
1043 }
1044
1045 #include "vkDeviceFeaturesForContextDefs.inl"
1046
getDeviceProperties(void) const1047 const vk::VkPhysicalDeviceProperties &Context::getDeviceProperties(void) const
1048 {
1049 return m_device->getDeviceProperties();
1050 }
getDeviceProperties2(void) const1051 const vk::VkPhysicalDeviceProperties2 &Context::getDeviceProperties2(void) const
1052 {
1053 return m_device->getDeviceProperties2();
1054 }
getDeviceVulkan11Properties(void) const1055 const vk::VkPhysicalDeviceVulkan11Properties &Context::getDeviceVulkan11Properties(void) const
1056 {
1057 return m_device->getDeviceVulkan11Properties();
1058 }
getDeviceVulkan12Properties(void) const1059 const vk::VkPhysicalDeviceVulkan12Properties &Context::getDeviceVulkan12Properties(void) const
1060 {
1061 return m_device->getDeviceVulkan12Properties();
1062 }
1063 #ifndef CTS_USES_VULKANSC
getDeviceVulkan13Properties(void) const1064 const vk::VkPhysicalDeviceVulkan13Properties &Context::getDeviceVulkan13Properties(void) const
1065 {
1066 return m_device->getDeviceVulkan13Properties();
1067 }
getDeviceVulkan14Properties(void) const1068 const vk::VkPhysicalDeviceVulkan14Properties &Context::getDeviceVulkan14Properties(void) const
1069 {
1070 return m_device->getDeviceVulkan14Properties();
1071 }
1072 #endif // CTS_USES_VULKANSC
1073 #ifdef CTS_USES_VULKANSC
getDeviceVulkanSC10Properties(void) const1074 const vk::VkPhysicalDeviceVulkanSC10Properties &Context::getDeviceVulkanSC10Properties(void) const
1075 {
1076 return m_device->getDeviceVulkanSC10Properties();
1077 }
1078 #endif // CTS_USES_VULKANSC
1079
1080 #include "vkDevicePropertiesForContextDefs.inl"
1081
getDeviceExtensions(void) const1082 const vector<string> &Context::getDeviceExtensions(void) const
1083 {
1084 return m_device->getDeviceExtensions();
1085 }
getDeviceCreationExtensions(void) const1086 const vector<const char *> &Context::getDeviceCreationExtensions(void) const
1087 {
1088 return m_device->getDeviceCreationExtensions();
1089 }
getDevice(void) const1090 vk::VkDevice Context::getDevice(void) const
1091 {
1092 return m_device->getDevice();
1093 }
getDeviceInterface(void) const1094 const vk::DeviceInterface &Context::getDeviceInterface(void) const
1095 {
1096 return m_device->getDeviceInterface();
1097 }
getUniversalQueueFamilyIndex(void) const1098 uint32_t Context::getUniversalQueueFamilyIndex(void) const
1099 {
1100 return m_device->getUniversalQueueFamilyIndex();
1101 }
getUniversalQueue(void) const1102 vk::VkQueue Context::getUniversalQueue(void) const
1103 {
1104 return m_device->getUniversalQueue();
1105 }
getComputeQueueFamilyIndex(void) const1106 int Context::getComputeQueueFamilyIndex(void) const
1107 {
1108 return m_device->getComputeQueueFamilyIndex();
1109 }
getComputeQueue(void) const1110 vk::VkQueue Context::getComputeQueue(void) const
1111 {
1112 return m_device->getComputeQueue();
1113 }
getTransferQueueFamilyIndex(void) const1114 int Context::getTransferQueueFamilyIndex(void) const
1115 {
1116 return m_device->getTransferQueueFamilyIndex();
1117 }
getTransferQueue(void) const1118 vk::VkQueue Context::getTransferQueue(void) const
1119 {
1120 return m_device->getTransferQueue();
1121 }
getSparseQueueFamilyIndex(void) const1122 uint32_t Context::getSparseQueueFamilyIndex(void) const
1123 {
1124 return m_device->getSparseQueueFamilyIndex();
1125 }
getSparseQueue(void) const1126 vk::VkQueue Context::getSparseQueue(void) const
1127 {
1128 return m_device->getSparseQueue();
1129 }
getResourceInterface(void) const1130 de::SharedPtr<vk::ResourceInterface> Context::getResourceInterface(void) const
1131 {
1132 return m_resourceInterface;
1133 }
getDefaultAllocator(void) const1134 vk::Allocator &Context::getDefaultAllocator(void) const
1135 {
1136 return *m_allocator;
1137 }
getUsedApiVersion(void) const1138 uint32_t Context::getUsedApiVersion(void) const
1139 {
1140 return m_device->getUsedApiVersion();
1141 }
contextSupports(const uint32_t variantNum,const uint32_t majorNum,const uint32_t minorNum,const uint32_t patchNum) const1142 bool Context::contextSupports(const uint32_t variantNum, const uint32_t majorNum, const uint32_t minorNum,
1143 const uint32_t patchNum) const
1144 {
1145 return isApiVersionSupported(m_device->getUsedApiVersion(),
1146 VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNum));
1147 }
contextSupports(const ApiVersion version) const1148 bool Context::contextSupports(const ApiVersion version) const
1149 {
1150 return isApiVersionSupported(m_device->getUsedApiVersion(), pack(version));
1151 }
contextSupports(const uint32_t requiredApiVersionBits) const1152 bool Context::contextSupports(const uint32_t requiredApiVersionBits) const
1153 {
1154 return isApiVersionSupported(m_device->getUsedApiVersion(), requiredApiVersionBits);
1155 }
isDeviceFeatureInitialized(vk::VkStructureType sType) const1156 bool Context::isDeviceFeatureInitialized(vk::VkStructureType sType) const
1157 {
1158 return m_device->isDeviceFeatureInitialized(sType);
1159 }
isDevicePropertyInitialized(vk::VkStructureType sType) const1160 bool Context::isDevicePropertyInitialized(vk::VkStructureType sType) const
1161 {
1162 return m_device->isDevicePropertyInitialized(sType);
1163 }
1164
requireDeviceFunctionality(const std::string & required) const1165 bool Context::requireDeviceFunctionality(const std::string &required) const
1166 {
1167 if (!isDeviceFunctionalitySupported(required))
1168 TCU_THROW(NotSupportedError, required + " is not supported");
1169
1170 return true;
1171 }
1172
requireInstanceFunctionality(const std::string & required) const1173 bool Context::requireInstanceFunctionality(const std::string &required) const
1174 {
1175 if (!isInstanceFunctionalitySupported(required))
1176 TCU_THROW(NotSupportedError, required + " is not supported");
1177
1178 return true;
1179 }
1180
1181 struct DeviceCoreFeaturesTable
1182 {
1183 const char *featureName;
1184 const uint32_t featureArrayIndex;
1185 const uint32_t featureArrayOffset;
1186 };
1187
1188 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) offsetof(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
1189 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME) \
1190 { \
1191 #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) \
1192 }
1193
1194 const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] = {
1195 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS, robustBufferAccess),
1196 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32, fullDrawIndexUint32),
1197 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY, imageCubeArray),
1198 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND, independentBlend),
1199 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER, geometryShader),
1200 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER, tessellationShader),
1201 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING, sampleRateShading),
1202 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND, dualSrcBlend),
1203 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP, logicOp),
1204 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT, multiDrawIndirect),
1205 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE, drawIndirectFirstInstance),
1206 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP, depthClamp),
1207 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP, depthBiasClamp),
1208 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID, fillModeNonSolid),
1209 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS, depthBounds),
1210 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES, wideLines),
1211 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS, largePoints),
1212 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE, alphaToOne),
1213 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT, multiViewport),
1214 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY, samplerAnisotropy),
1215 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2, textureCompressionETC2),
1216 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR, textureCompressionASTC_LDR),
1217 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC, textureCompressionBC),
1218 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE, occlusionQueryPrecise),
1219 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY, pipelineStatisticsQuery),
1220 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS, vertexPipelineStoresAndAtomics),
1221 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS, fragmentStoresAndAtomics),
1222 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE,
1223 shaderTessellationAndGeometryPointSize),
1224 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED, shaderImageGatherExtended),
1225 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS,
1226 shaderStorageImageExtendedFormats),
1227 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE, shaderStorageImageMultisample),
1228 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT,
1229 shaderStorageImageReadWithoutFormat),
1230 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT,
1231 shaderStorageImageWriteWithoutFormat),
1232 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
1233 shaderUniformBufferArrayDynamicIndexing),
1234 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING,
1235 shaderSampledImageArrayDynamicIndexing),
1236 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
1237 shaderStorageBufferArrayDynamicIndexing),
1238 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING,
1239 shaderStorageImageArrayDynamicIndexing),
1240 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE, shaderClipDistance),
1241 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE, shaderCullDistance),
1242 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64, shaderFloat64),
1243 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64, shaderInt64),
1244 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16, shaderInt16),
1245 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY, shaderResourceResidency),
1246 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD, shaderResourceMinLod),
1247 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING, sparseBinding),
1248 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER, sparseResidencyBuffer),
1249 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D, sparseResidencyImage2D),
1250 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D, sparseResidencyImage3D),
1251 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES, sparseResidency2Samples),
1252 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES, sparseResidency4Samples),
1253 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES, sparseResidency8Samples),
1254 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES, sparseResidency16Samples),
1255 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED, sparseResidencyAliased),
1256 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE, variableMultisampleRate),
1257 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES, inheritedQueries),
1258 };
1259
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)1260 bool Context::requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)
1261 {
1262 const vk::VkPhysicalDeviceFeatures &featuresAvailable = getDeviceFeatures();
1263 const vk::VkBool32 *featuresAvailableArray = (vk::VkBool32 *)(&featuresAvailable);
1264 const uint32_t requiredFeatureIndex = static_cast<uint32_t>(requiredFeature);
1265
1266 DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
1267 DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) ==
1268 deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
1269
1270 if (featuresAvailableArray[requiredFeatureIndex] == false)
1271 TCU_THROW(NotSupportedError, "Requested core feature is not supported: " +
1272 std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
1273
1274 return true;
1275 }
1276
1277 #ifndef CTS_USES_VULKANSC
1278
isSpirvCompatibleFormat(VkFormat format)1279 static bool isSpirvCompatibleFormat(VkFormat format)
1280 {
1281 switch (format)
1282 {
1283 case VK_FORMAT_R32G32B32A32_SFLOAT:
1284 case VK_FORMAT_R32G32_SFLOAT:
1285 case VK_FORMAT_R32_SFLOAT:
1286 case VK_FORMAT_R16G16B16A16_SFLOAT:
1287 case VK_FORMAT_R16G16_SFLOAT:
1288 case VK_FORMAT_R16_SFLOAT:
1289 case VK_FORMAT_R16G16B16A16_UNORM:
1290 case VK_FORMAT_R16G16_UNORM:
1291 case VK_FORMAT_R16_UNORM:
1292 case VK_FORMAT_R16G16B16A16_SNORM:
1293 case VK_FORMAT_R16G16_SNORM:
1294 case VK_FORMAT_R16_SNORM:
1295 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1296 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1297 case VK_FORMAT_R8G8B8A8_UNORM:
1298 case VK_FORMAT_R8G8_UNORM:
1299 case VK_FORMAT_R8_UNORM:
1300 case VK_FORMAT_R8G8B8A8_SNORM:
1301 case VK_FORMAT_R8G8_SNORM:
1302 case VK_FORMAT_R8_SNORM:
1303 case VK_FORMAT_R32G32B32A32_SINT:
1304 case VK_FORMAT_R32G32_SINT:
1305 case VK_FORMAT_R32_SINT:
1306 case VK_FORMAT_R16G16B16A16_SINT:
1307 case VK_FORMAT_R16G16_SINT:
1308 case VK_FORMAT_R16_SINT:
1309 case VK_FORMAT_R8G8B8A8_SINT:
1310 case VK_FORMAT_R8G8_SINT:
1311 case VK_FORMAT_R8_SINT:
1312 case VK_FORMAT_R32G32B32A32_UINT:
1313 case VK_FORMAT_R32G32_UINT:
1314 case VK_FORMAT_R32_UINT:
1315 case VK_FORMAT_R16G16B16A16_UINT:
1316 case VK_FORMAT_R16G16_UINT:
1317 case VK_FORMAT_R16_UINT:
1318 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1319 case VK_FORMAT_R8G8B8A8_UINT:
1320 case VK_FORMAT_R8G8_UINT:
1321 case VK_FORMAT_R8_UINT:
1322 case VK_FORMAT_R64_SINT:
1323 case VK_FORMAT_R64_UINT:
1324 // These formats can be explicitly expressed in SPIR-V.
1325 return true;
1326 default:
1327 return false;
1328 }
1329 }
1330
isExtendedStorageFormat(VkFormat format)1331 static bool isExtendedStorageFormat(VkFormat format)
1332 {
1333 switch (format)
1334 {
1335 case VK_FORMAT_R8G8B8A8_UNORM:
1336 case VK_FORMAT_R8G8B8A8_SNORM:
1337 case VK_FORMAT_R8G8B8A8_UINT:
1338 case VK_FORMAT_R8G8B8A8_SINT:
1339 case VK_FORMAT_R32_UINT:
1340 case VK_FORMAT_R32_SINT:
1341 case VK_FORMAT_R32_SFLOAT:
1342 case VK_FORMAT_R32G32_UINT:
1343 case VK_FORMAT_R32G32_SINT:
1344 case VK_FORMAT_R32G32_SFLOAT:
1345 case VK_FORMAT_R32G32B32A32_UINT:
1346 case VK_FORMAT_R32G32B32A32_SINT:
1347 case VK_FORMAT_R32G32B32A32_SFLOAT:
1348 case VK_FORMAT_R16G16B16A16_UINT:
1349 case VK_FORMAT_R16G16B16A16_SINT:
1350 case VK_FORMAT_R16G16B16A16_SFLOAT:
1351 case VK_FORMAT_R16G16_SFLOAT:
1352 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1353 case VK_FORMAT_R16_SFLOAT:
1354 case VK_FORMAT_R16G16B16A16_UNORM:
1355 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1356 case VK_FORMAT_R16G16_UNORM:
1357 case VK_FORMAT_R8G8_UNORM:
1358 case VK_FORMAT_R16_UNORM:
1359 case VK_FORMAT_R8_UNORM:
1360 case VK_FORMAT_R16G16B16A16_SNORM:
1361 case VK_FORMAT_R16G16_SNORM:
1362 case VK_FORMAT_R8G8_SNORM:
1363 case VK_FORMAT_R16_SNORM:
1364 case VK_FORMAT_R8_SNORM:
1365 case VK_FORMAT_R16G16_SINT:
1366 case VK_FORMAT_R8G8_SINT:
1367 case VK_FORMAT_R16_SINT:
1368 case VK_FORMAT_R8_SINT:
1369 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1370 case VK_FORMAT_R16G16_UINT:
1371 case VK_FORMAT_R8G8_UINT:
1372 case VK_FORMAT_R16_UINT:
1373 case VK_FORMAT_R8_UINT:
1374 return true;
1375 default:
1376 return false;
1377 }
1378 }
1379
isDepthFormat(VkFormat format)1380 static bool isDepthFormat(VkFormat format)
1381 {
1382 switch (format)
1383 {
1384 case VK_FORMAT_D16_UNORM:
1385 case VK_FORMAT_X8_D24_UNORM_PACK32:
1386 case VK_FORMAT_D32_SFLOAT:
1387 case VK_FORMAT_D16_UNORM_S8_UINT:
1388 case VK_FORMAT_D24_UNORM_S8_UINT:
1389 case VK_FORMAT_D32_SFLOAT_S8_UINT:
1390 return true;
1391 default:
1392 return false;
1393 }
1394 }
1395
getRequiredFormatProperties(const vk::VkFormat & format) const1396 vk::VkFormatProperties3 Context::getRequiredFormatProperties(const vk::VkFormat &format) const
1397 {
1398 vk::VkFormatProperties3 p;
1399 p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1400 p.pNext = nullptr;
1401
1402 vk::VkFormatProperties properties;
1403 getInstanceInterface().getPhysicalDeviceFormatProperties(getPhysicalDevice(), format, &properties);
1404 p.linearTilingFeatures = properties.linearTilingFeatures;
1405 p.optimalTilingFeatures = properties.optimalTilingFeatures;
1406 p.bufferFeatures = properties.bufferFeatures;
1407
1408 const vk::VkPhysicalDeviceFeatures &featuresAvailable = getDeviceFeatures();
1409 if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageReadWithoutFormat)
1410 {
1411 if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1412 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1413 if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1414 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR;
1415 }
1416 if (isExtendedStorageFormat(format) && featuresAvailable.shaderStorageImageWriteWithoutFormat)
1417 {
1418 if (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1419 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1420 if (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)
1421 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
1422 }
1423 // If an implementation exposes storage image/buffer feature on formats not in the SPIR-V compatibility table,
1424 // the implementation must at least expose one of the WITHOUT_FORMAT (either READ or WRITE) storage features.
1425 if (!isSpirvCompatibleFormat(format))
1426 {
1427 if ((p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1428 (p.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1429 {
1430 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1431 }
1432 if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1433 (p.optimalTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1434 {
1435 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1436 }
1437 if ((p.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR) ||
1438 (p.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR))
1439 {
1440 p.bufferFeatures |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR;
1441 }
1442 }
1443 if (isDepthFormat(format) && (p.linearTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1444 p.linearTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1445 if (isDepthFormat(format) && (p.optimalTilingFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)))
1446 p.optimalTilingFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
1447
1448 return p;
1449 }
1450
getFormatProperties(const vk::VkFormat & format) const1451 vk::VkFormatProperties3 Context::getFormatProperties(const vk::VkFormat &format) const
1452 {
1453 if (isDeviceFunctionalitySupported("VK_KHR_format_feature_flags2"))
1454 {
1455 vk::VkFormatProperties3 p;
1456 p.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3;
1457 p.pNext = nullptr;
1458
1459 vk::VkFormatProperties2 properties;
1460 properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
1461 properties.pNext = &p;
1462
1463 getInstanceInterface().getPhysicalDeviceFormatProperties2(getPhysicalDevice(), format, &properties);
1464 return p;
1465 }
1466 else
1467 return Context::getRequiredFormatProperties(format);
1468 }
1469
1470 #endif // CTS_USES_VULKANSC
1471
getInstanceProcAddr()1472 void *Context::getInstanceProcAddr()
1473 {
1474 return (void *)m_platformInterface.getGetInstanceProcAddr();
1475 }
1476
isBufferDeviceAddressSupported(void) const1477 bool Context::isBufferDeviceAddressSupported(void) const
1478 {
1479 return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
1480 isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
1481 }
1482
1483 #ifndef CTS_USES_VULKANSC
1484
hasDebugReportRecorder() const1485 bool Context::hasDebugReportRecorder() const
1486 {
1487 return m_device->hasDebugReportRecorder();
1488 }
1489
getDebugReportRecorder() const1490 vk::DebugReportRecorder &Context::getDebugReportRecorder() const
1491 {
1492 return m_device->getDebugReportRecorder();
1493 }
1494
1495 #endif // CTS_USES_VULKANSC
1496
resetCommandPoolForVKSC(const VkDevice device,const VkCommandPool commandPool)1497 void Context::resetCommandPoolForVKSC(const VkDevice device, const VkCommandPool commandPool)
1498 {
1499 #ifdef CTS_USES_VULKANSC
1500 if (getDeviceVulkanSC10Properties().commandPoolResetCommandBuffer == VK_FALSE)
1501 {
1502 const DeviceInterface &vk = getDeviceInterface();
1503 VK_CHECK(vk.resetCommandPool(device, commandPool, 0u));
1504 }
1505 #else
1506 DE_UNREF(device);
1507 DE_UNREF(commandPool);
1508 #endif
1509 }
1510
getContextCommonData() const1511 ContextCommonData Context::getContextCommonData() const
1512 {
1513 return ContextCommonData{
1514 getPlatformInterface(), getInstanceInterface(),
1515 getDeviceInterface(), getInstance(),
1516 getPhysicalDevice(), getDevice(),
1517 getDefaultAllocator(), getUniversalQueueFamilyIndex(),
1518 getUniversalQueue(),
1519 };
1520 }
1521
1522 #ifdef CTS_USES_VULKANSC
1523 std::vector<VkFaultData> Context::m_faultData;
1524 std::mutex Context::m_faultDataMutex;
1525
faultCallbackFunction(VkBool32 unrecordedFaults,uint32_t faultCount,const VkFaultData * pFaults)1526 void Context::faultCallbackFunction(VkBool32 unrecordedFaults, uint32_t faultCount, const VkFaultData *pFaults)
1527 {
1528 DE_UNREF(unrecordedFaults);
1529 std::lock_guard<std::mutex> lock(m_faultDataMutex);
1530
1531 // Append new faults to the vector
1532 for (uint32_t i = 0; i < faultCount; ++i)
1533 {
1534 VkFaultData faultData = pFaults[i];
1535 faultData.pNext = nullptr;
1536
1537 m_faultData.push_back(faultData);
1538 }
1539 }
1540 #endif // CTS_USES_VULKANSC
1541
1542 // TestCase
1543
initPrograms(SourceCollections &) const1544 void TestCase::initPrograms(SourceCollections &) const
1545 {
1546 }
1547
checkSupport(Context &) const1548 void TestCase::checkSupport(Context &) const
1549 {
1550 }
1551
delayedInit(void)1552 void TestCase::delayedInit(void)
1553 {
1554 }
1555
1556 #ifndef CTS_USES_VULKANSC
1557
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)1558 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context &context)
1559 {
1560 using DebugMessages = vk::DebugReportRecorder::MessageList;
1561
1562 const DebugMessages &messages = debugReportRecorder.getMessages();
1563 tcu::TestLog &log = context.getTestContext().getLog();
1564
1565 if (messages.size() > 0)
1566 {
1567 const tcu::ScopedLogSection section(log, "DebugMessages", "Debug Messages");
1568 int numErrors = 0;
1569
1570 for (const auto &msg : messages)
1571 {
1572 if (msg.shouldBeLogged())
1573 log << tcu::TestLog::Message << msg << tcu::TestLog::EndMessage;
1574
1575 if (msg.isError())
1576 numErrors += 1;
1577 }
1578
1579 debugReportRecorder.clearMessages();
1580
1581 if (numErrors > 0)
1582 {
1583 string errorMsg = de::toString(numErrors) + " API usage errors found";
1584 context.resultSetOnValidation(true);
1585 context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
1586 }
1587 }
1588 }
1589
1590 #endif // CTS_USES_VULKANSC
1591
1592 } // namespace vkt
1593