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