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