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