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
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestLog.hpp"
39
40 #include "deSTLUtil.hpp"
41 #include "deMemory.h"
42
43 #include <set>
44
45 struct vk_executor;
46
47 namespace vkt
48 {
49
50 // Default device utilities
51
52 using std::vector;
53 using std::string;
54 using std::set;
55 using namespace vk;
56
57 namespace
58 {
59
filterExtensions(const vector<VkExtensionProperties> & extensions)60 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions)
61 {
62 vector<string> enabledExtensions;
63 const char* extensionGroups[] =
64 {
65 "VK_KHR_",
66 "VK_EXT_",
67 "VK_KHX_",
68 "VK_NV_cooperative_matrix",
69 "VK_NV_shading_rate_image",
70 "VK_NV_ray_tracing",
71 "VK_AMD_mixed_attachment_samples",
72 "VK_AMD_shader_fragment_mask",
73 "VK_AMD_buffer_marker",
74 };
75
76 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
77 {
78 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++)
79 {
80 if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx]))
81 enabledExtensions.push_back(extensions[extNdx].extensionName);
82 }
83 }
84
85 return enabledExtensions;
86 }
87
addExtensions(const vector<string> & a,const vector<const char * > & b)88 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b)
89 {
90 vector<string> res (a);
91
92 for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter)
93 {
94 if (!de::contains(res.begin(), res.end(), string(*bIter)))
95 res.push_back(string(*bIter));
96 }
97
98 return res;
99 }
100
removeExtensions(const vector<string> & a,const vector<const char * > & b)101 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
102 {
103 vector<string> res;
104 set<string> removeExts (b.begin(), b.end());
105
106 for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
107 {
108 if (!de::contains(removeExts, *aIter))
109 res.push_back(*aIter);
110 }
111
112 return res;
113 }
114
addCoreInstanceExtensions(const vector<string> & extensions,deUint32 instanceVersion)115 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion)
116 {
117 vector<const char*> coreExtensions;
118 getCoreInstanceExtensions(instanceVersion, coreExtensions);
119 return addExtensions(extensions, coreExtensions);
120 }
121
addCoreDeviceExtensions(const vector<string> & extensions,deUint32 instanceVersion)122 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion)
123 {
124 vector<const char*> coreExtensions;
125 getCoreDeviceExtensions(instanceVersion, coreExtensions);
126 return addExtensions(extensions, coreExtensions);
127 }
128
getTargetInstanceVersion(const PlatformInterface & vkp)129 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp)
130 {
131 deUint32 version = pack(ApiVersion(1, 0, 0));
132
133 if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS)
134 TCU_THROW(InternalError, "Enumerate instance version error");
135 return version;
136 }
137
determineDeviceVersions(const PlatformInterface & vkp,deUint32 apiVersion,const tcu::CommandLine & cmdLine)138 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine)
139 {
140 Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion);
141 InstanceDriver preinterface (vkp, preinstance.get());
142
143 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get());
144 deUint32 lowestDeviceVersion = 0xFFFFFFFFu;
145 for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx)
146 {
147 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]);
148 if (props.apiVersion < lowestDeviceVersion)
149 lowestDeviceVersion = props.apiVersion;
150 }
151
152 const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine);
153 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, choosenDevice);
154 const deUint32 choosenDeviceVersion = props.apiVersion;
155
156 return std::make_pair(choosenDeviceVersion, lowestDeviceVersion);
157 }
158
159
createInstance(const PlatformInterface & vkp,deUint32 apiVersion,const vector<string> & enabledExtensions,const tcu::CommandLine & cmdLine)160 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine)
161 {
162 const bool isValidationEnabled = cmdLine.isValidationEnabled();
163 vector<const char*> enabledLayers;
164
165 // \note Extensions in core are not explicitly enabled even though
166 // they are in the extension list advertised to tests.
167 vector<const char*> coreExtensions;
168 getCoreInstanceExtensions(apiVersion, coreExtensions);
169 vector<string> nonCoreExtensions (removeExtensions(enabledExtensions, coreExtensions));
170
171 if (isValidationEnabled)
172 {
173 if (!isDebugReportSupported(vkp))
174 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
175
176 enabledLayers = vkt::getValidationLayers(vkp);
177 if (enabledLayers.empty())
178 TCU_THROW(NotSupportedError, "No validation layers found");
179 }
180
181 return createDefaultInstance(vkp, apiVersion, vector<string>(begin(enabledLayers), end(enabledLayers)), nonCoreExtensions);
182 }
183
findQueueFamilyIndexWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)184 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
185 {
186 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
187
188 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
189 {
190 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
191 return (deUint32)queueNdx;
192 }
193
194 TCU_THROW(NotSupportedError, "No matching queue found");
195 }
196
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)197 Move<VkDevice> createDefaultDevice (const PlatformInterface& vkp,
198 VkInstance instance,
199 const InstanceInterface& vki,
200 VkPhysicalDevice physicalDevice,
201 const deUint32 apiVersion,
202 deUint32 queueIndex,
203 deUint32 sparseQueueIndex,
204 const VkPhysicalDeviceFeatures2& enabledFeatures,
205 const vector<string>& enabledExtensions,
206 const tcu::CommandLine& cmdLine)
207 {
208 VkDeviceQueueCreateInfo queueInfo[2];
209 VkDeviceCreateInfo deviceInfo;
210 vector<const char*> enabledLayers;
211 vector<const char*> extensionPtrs;
212 const float queuePriority = 1.0f;
213 const deUint32 numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1;
214
215 deMemset(&queueInfo, 0, sizeof(queueInfo));
216 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
217
218 if (cmdLine.isValidationEnabled())
219 {
220 enabledLayers = vkt::getValidationLayers(vki, physicalDevice);
221 if (enabledLayers.empty())
222 TCU_THROW(NotSupportedError, "No validation layers found");
223 }
224
225 // \note Extensions in core are not explicitly enabled even though
226 // they are in the extension list advertised to tests.
227 vector<const char*> coreExtensions;
228 getCoreDeviceExtensions(apiVersion, coreExtensions);
229 vector<string> nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions));
230
231 extensionPtrs.resize(nonCoreExtensions.size());
232
233 for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
234 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
235
236 queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
237 queueInfo[0].pNext = DE_NULL;
238 queueInfo[0].flags = (VkDeviceQueueCreateFlags)0u;
239 queueInfo[0].queueFamilyIndex = queueIndex;
240 queueInfo[0].queueCount = 1u;
241 queueInfo[0].pQueuePriorities = &queuePriority;
242
243 if (numQueues > 1)
244 {
245 queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
246 queueInfo[1].pNext = DE_NULL;
247 queueInfo[1].flags = (VkDeviceQueueCreateFlags)0u;
248 queueInfo[1].queueFamilyIndex = sparseQueueIndex;
249 queueInfo[1].queueCount = 1u;
250 queueInfo[1].pQueuePriorities = &queuePriority;
251 }
252
253 // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0
254 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
255 deviceInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : DE_NULL;
256 deviceInfo.queueCreateInfoCount = numQueues;
257 deviceInfo.pQueueCreateInfos = queueInfo;
258 deviceInfo.enabledExtensionCount = (deUint32)extensionPtrs.size();
259 deviceInfo.ppEnabledExtensionNames = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
260 deviceInfo.enabledLayerCount = (deUint32)enabledLayers.size();
261 deviceInfo.ppEnabledLayerNames = (enabledLayers.empty() ? DE_NULL : enabledLayers.data());
262 deviceInfo.pEnabledFeatures = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features;
263
264 return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo);
265 };
266
267 } // anonymous
268
269 class DefaultDevice
270 {
271 public:
272 DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine);
273 ~DefaultDevice (void);
274
getInstance(void) const275 VkInstance getInstance (void) const { return *m_instance; }
getInstanceInterface(void) const276 const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; }
getMaximumFrameworkVulkanVersion(void) const277 deUint32 getMaximumFrameworkVulkanVersion (void) const { return m_maximumFrameworkVulkanVersion; }
getAvailableInstanceVersion(void) const278 deUint32 getAvailableInstanceVersion (void) const { return m_availableInstanceVersion; }
getUsedInstanceVersion(void) const279 deUint32 getUsedInstanceVersion (void) const { return m_usedInstanceVersion; }
getInstanceExtensions(void) const280 const vector<string>& getInstanceExtensions (void) const { return m_instanceExtensions; }
281
getPhysicalDevice(void) const282 VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; }
getDeviceVersion(void) const283 deUint32 getDeviceVersion (void) const { return m_deviceVersion; }
284
isDeviceFeatureInitialized(VkStructureType sType) const285 bool isDeviceFeatureInitialized (VkStructureType sType) const { return m_deviceFeatures.isDeviceFeatureInitialized(sType); }
getDeviceFeatures(void) const286 const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures.getCoreFeatures2().features; }
getDeviceFeatures2(void) const287 const VkPhysicalDeviceFeatures2& getDeviceFeatures2 (void) const { return m_deviceFeatures.getCoreFeatures2(); }
getVulkan11Features(void) const288 const VkPhysicalDeviceVulkan11Features& getVulkan11Features (void) const { return m_deviceFeatures.getVulkan11Features(); }
getVulkan12Features(void) const289 const VkPhysicalDeviceVulkan12Features& getVulkan12Features (void) const { return m_deviceFeatures.getVulkan12Features(); }
290
291 #include "vkDeviceFeaturesForDefaultDeviceDefs.inl"
292
isDevicePropertyInitialized(VkStructureType sType) const293 bool isDevicePropertyInitialized (VkStructureType sType) const { return m_devicePropertiesFull.isDevicePropertyInitialized(sType); }
getDeviceProperties(void) const294 const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties; }
getDeviceProperties2(void) const295 const VkPhysicalDeviceProperties2& getDeviceProperties2 (void) const { return m_devicePropertiesFull.getCoreProperties2(); }
296
297 #include "vkDevicePropertiesForDefaultDeviceDefs.inl"
298
getDevice(void) const299 VkDevice getDevice (void) const { return *m_device; }
getDeviceInterface(void) const300 const DeviceInterface& getDeviceInterface (void) const { return m_deviceInterface; }
getDeviceExtensions(void) const301 const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; }
getUsedApiVersion(void) const302 deUint32 getUsedApiVersion (void) const { return m_usedApiVersion; }
getUniversalQueueFamilyIndex(void) const303 deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; }
304 VkQueue getUniversalQueue (void) const;
getSparseQueueFamilyIndex(void) const305 deUint32 getSparseQueueFamilyIndex (void) const { return m_sparseQueueFamilyIndex; }
306 VkQueue getSparseQueue (void) const;
307
308 private:
309
310 const deUint32 m_maximumFrameworkVulkanVersion;
311 const deUint32 m_availableInstanceVersion;
312 const deUint32 m_usedInstanceVersion;
313
314 const std::pair<deUint32, deUint32> m_deviceVersions;
315 const deUint32 m_usedApiVersion;
316
317 const vector<string> m_instanceExtensions;
318 const Unique<VkInstance> m_instance;
319 const InstanceDriver m_instanceInterface;
320
321 const VkPhysicalDevice m_physicalDevice;
322 const deUint32 m_deviceVersion;
323
324 const vector<string> m_deviceExtensions;
325 const DeviceFeatures m_deviceFeatures;
326
327 const deUint32 m_universalQueueFamilyIndex;
328 const deUint32 m_sparseQueueFamilyIndex;
329 const VkPhysicalDeviceProperties m_deviceProperties;
330 const DeviceProperties m_devicePropertiesFull;
331
332 const Unique<VkDevice> m_device;
333 const DeviceDriver m_deviceInterface;
334 };
335
sanitizeApiVersion(deUint32 v)336 static deUint32 sanitizeApiVersion(deUint32 v)
337 {
338 return VK_MAKE_VERSION( VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), 0 );
339 }
340
DefaultDevice(const PlatformInterface & vkPlatform,const tcu::CommandLine & cmdLine)341 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine)
342 : m_maximumFrameworkVulkanVersion (VK_API_MAX_FRAMEWORK_VERSION)
343 , m_availableInstanceVersion (getTargetInstanceVersion(vkPlatform))
344 , m_usedInstanceVersion (sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_maximumFrameworkVulkanVersion)))
345 , m_deviceVersions (determineDeviceVersions(vkPlatform, m_usedInstanceVersion, cmdLine))
346 , m_usedApiVersion (sanitizeApiVersion(deMinu32(m_usedInstanceVersion, m_deviceVersions.first)))
347
348 , m_instanceExtensions (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion))
349 , m_instance (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine))
350
351 , m_instanceInterface (vkPlatform, *m_instance)
352 , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine))
353 , m_deviceVersion (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion)
354
355 , m_deviceExtensions (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion))
356 , m_deviceFeatures (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
357 , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
358 , m_sparseQueueFamilyIndex (m_deviceFeatures.getCoreFeatures2().features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0)
359 , m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
360 , m_devicePropertiesFull (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions)
361 , m_device (createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.getCoreFeatures2(), m_deviceExtensions, cmdLine))
362 , m_deviceInterface (vkPlatform, *m_instance, *m_device)
363 {
364 DE_ASSERT(m_deviceVersions.first == m_deviceVersion);
365 }
366
~DefaultDevice(void)367 DefaultDevice::~DefaultDevice (void)
368 {
369 }
370
getUniversalQueue(void) const371 VkQueue DefaultDevice::getUniversalQueue (void) const
372 {
373 return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0);
374 }
375
getSparseQueue(void) const376 VkQueue DefaultDevice::getSparseQueue (void) const
377 {
378 if (!m_deviceFeatures.getCoreFeatures2().features.sparseBinding)
379 TCU_THROW(NotSupportedError, "Sparse binding not supported.");
380
381 return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0);
382 }
383
384 namespace
385 {
386 // Allocator utilities
387
createAllocator(DefaultDevice * device)388 vk::Allocator* createAllocator (DefaultDevice* device)
389 {
390 const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice());
391
392 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
393 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties);
394 }
395
396 } // anonymous
397
398 // Context
399
Context(tcu::TestContext & testCtx,const vk::PlatformInterface & platformInterface,vk::BinaryCollection & progCollection)400 Context::Context (tcu::TestContext& testCtx,
401 const vk::PlatformInterface& platformInterface,
402 vk::BinaryCollection& progCollection)
403 : m_testCtx (testCtx)
404 , m_platformInterface (platformInterface)
405 , m_progCollection (progCollection)
406 , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine()))
407 , m_allocator (createAllocator(m_device.get()))
408 , m_resultSetOnValidation (false)
409 {
410 }
411
~Context(void)412 Context::~Context (void)
413 {
414 }
415
getMaximumFrameworkVulkanVersion(void) const416 deUint32 Context::getMaximumFrameworkVulkanVersion (void) const { return m_device->getMaximumFrameworkVulkanVersion(); }
getAvailableInstanceVersion(void) const417 deUint32 Context::getAvailableInstanceVersion (void) const { return m_device->getAvailableInstanceVersion(); }
getInstanceExtensions(void) const418 const vector<string>& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); }
getInstance(void) const419 vk::VkInstance Context::getInstance (void) const { return m_device->getInstance(); }
getInstanceInterface(void) const420 const vk::InstanceInterface& Context::getInstanceInterface (void) const { return m_device->getInstanceInterface(); }
getPhysicalDevice(void) const421 vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); }
getDeviceVersion(void) const422 deUint32 Context::getDeviceVersion (void) const { return m_device->getDeviceVersion(); }
getDeviceFeatures(void) const423 const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); }
getDeviceFeatures2(void) const424 const vk::VkPhysicalDeviceFeatures2& Context::getDeviceFeatures2 (void) const { return m_device->getDeviceFeatures2(); }
425
isDeviceFunctionalitySupported(const std::string & extension) const426 bool Context::isDeviceFunctionalitySupported (const std::string& extension) const
427 {
428 // check if extension was promoted to core
429 deUint32 apiVersion = getUsedApiVersion();
430 if (isCoreDeviceExtension(getUsedApiVersion(), extension))
431 {
432 // all folowing checks are for vk12 and can be skipped for previous versions
433 if (apiVersion < VK_MAKE_VERSION(1, 2, 0))
434 return true;
435
436 // handle promoted functionality that was provided under feature bit
437 const auto& vk11Features = m_device->getVulkan11Features();
438 if (extension == "VK_KHR_multiview")
439 return !!vk11Features.multiview;
440 if (extension == "VK_KHR_variable_pointers")
441 return !!vk11Features.variablePointersStorageBuffer;
442 if (extension == "VK_KHR_sampler_ycbcr_conversion")
443 return !!vk11Features.samplerYcbcrConversion;
444 if (extension == "VK_KHR_shader_draw_parameters")
445 return !!vk11Features.shaderDrawParameters;
446
447 const auto& vk12Features = m_device->getVulkan12Features();
448 if (extension == "VK_KHR_timeline_semaphore")
449 return !!vk12Features.timelineSemaphore;
450 if (extension == "VK_KHR_buffer_device_address")
451 return !!vk12Features.bufferDeviceAddress;
452 if (extension == "VK_EXT_descriptor_indexing")
453 return !!vk12Features.descriptorIndexing;
454 if (extension == "VK_KHR_draw_indirect_count")
455 return !!vk12Features.drawIndirectCount;
456 if (extension == "VK_KHR_sampler_mirror_clamp_to_edge")
457 return !!vk12Features.samplerMirrorClampToEdge;
458 if (extension == "VK_EXT_sampler_filter_minmax")
459 return !!vk12Features.samplerFilterMinmax;
460 if (extension == "VK_EXT_shader_viewport_index_layer")
461 return !!vk12Features.shaderOutputViewportIndex && !!vk12Features.shaderOutputLayer;
462
463 // no feature flags to check
464 return true;
465 }
466
467 // check if extension is on the lits of extensions for current device
468 const auto& extensions = getDeviceExtensions();
469 if (de::contains(extensions.begin(), extensions.end(), extension))
470 {
471 if (extension == "VK_KHR_timeline_semaphore")
472 return !!getTimelineSemaphoreFeatures().timelineSemaphore;
473
474 return true;
475 }
476
477 return false;
478 }
479
isInstanceFunctionalitySupported(const std::string & extension) const480 bool Context::isInstanceFunctionalitySupported(const std::string& extension) const
481 {
482 // NOTE: current implementation uses isInstanceExtensionSupported but
483 // this will change when some instance extensions will be promoted to the
484 // core; don't use isInstanceExtensionSupported directly, use this method instead
485 return isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), extension);
486 }
487
488 #include "vkDeviceFeaturesForContextDefs.inl"
489
getDeviceProperties(void) const490 const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); }
getDeviceProperties2(void) const491 const vk::VkPhysicalDeviceProperties2& Context::getDeviceProperties2 (void) const { return m_device->getDeviceProperties2(); }
492
493 #include "vkDevicePropertiesForContextDefs.inl"
494
getDeviceExtensions(void) const495 const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); }
getDevice(void) const496 vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); }
getDeviceInterface(void) const497 const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); }
getUniversalQueueFamilyIndex(void) const498 deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); }
getUniversalQueue(void) const499 vk::VkQueue Context::getUniversalQueue (void) const { return m_device->getUniversalQueue(); }
getSparseQueueFamilyIndex(void) const500 deUint32 Context::getSparseQueueFamilyIndex (void) const { return m_device->getSparseQueueFamilyIndex(); }
getSparseQueue(void) const501 vk::VkQueue Context::getSparseQueue (void) const { return m_device->getSparseQueue(); }
getDefaultAllocator(void) const502 vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; }
getUsedApiVersion(void) const503 deUint32 Context::getUsedApiVersion (void) const { return m_device->getUsedApiVersion(); }
contextSupports(const deUint32 majorNum,const deUint32 minorNum,const deUint32 patchNum) const504 bool Context::contextSupports (const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const
505 { return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); }
contextSupports(const ApiVersion version) const506 bool Context::contextSupports (const ApiVersion version) const
507 { return m_device->getUsedApiVersion() >= pack(version); }
contextSupports(const deUint32 requiredApiVersionBits) const508 bool Context::contextSupports (const deUint32 requiredApiVersionBits) const
509 { return m_device->getUsedApiVersion() >= requiredApiVersionBits; }
isDeviceFeatureInitialized(vk::VkStructureType sType) const510 bool Context::isDeviceFeatureInitialized (vk::VkStructureType sType) const
511 { return m_device->isDeviceFeatureInitialized(sType); }
isDevicePropertyInitialized(vk::VkStructureType sType) const512 bool Context::isDevicePropertyInitialized (vk::VkStructureType sType) const
513 { return m_device->isDevicePropertyInitialized(sType); }
514
requireDeviceFunctionality(const std::string & required) const515 bool Context::requireDeviceFunctionality (const std::string& required) const
516 {
517 if (!isDeviceFunctionalitySupported(required))
518 TCU_THROW(NotSupportedError, required + " is not supported");
519
520 return true;
521 }
522
requireInstanceFunctionality(const std::string & required) const523 bool Context::requireInstanceFunctionality (const std::string& required) const
524 {
525 if (!isInstanceFunctionalitySupported(required))
526 TCU_THROW(NotSupportedError, required + " is not supported");
527
528 return true;
529 }
530
531 struct DeviceCoreFeaturesTable
532 {
533 const char* featureName;
534 const deUint32 featureArrayIndex;
535 const deUint32 featureArrayOffset;
536 };
537
538 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME)
539 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME) { #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) }
540
541 const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] =
542 {
543 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS , robustBufferAccess ),
544 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32 , fullDrawIndexUint32 ),
545 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY , imageCubeArray ),
546 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND , independentBlend ),
547 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER , geometryShader ),
548 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER , tessellationShader ),
549 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING , sampleRateShading ),
550 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND , dualSrcBlend ),
551 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP , logicOp ),
552 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT , multiDrawIndirect ),
553 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE , drawIndirectFirstInstance ),
554 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP , depthClamp ),
555 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP , depthBiasClamp ),
556 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID , fillModeNonSolid ),
557 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS , depthBounds ),
558 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES , wideLines ),
559 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS , largePoints ),
560 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE , alphaToOne ),
561 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT , multiViewport ),
562 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY , samplerAnisotropy ),
563 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2 , textureCompressionETC2 ),
564 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR , textureCompressionASTC_LDR ),
565 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC , textureCompressionBC ),
566 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE , occlusionQueryPrecise ),
567 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY , pipelineStatisticsQuery ),
568 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS , vertexPipelineStoresAndAtomics ),
569 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS , fragmentStoresAndAtomics ),
570 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE , shaderTessellationAndGeometryPointSize ),
571 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED , shaderImageGatherExtended ),
572 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS , shaderStorageImageExtendedFormats ),
573 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE , shaderStorageImageMultisample ),
574 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT , shaderStorageImageReadWithoutFormat ),
575 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT , shaderStorageImageWriteWithoutFormat ),
576 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderUniformBufferArrayDynamicIndexing ),
577 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderSampledImageArrayDynamicIndexing ),
578 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderStorageBufferArrayDynamicIndexing ),
579 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderStorageImageArrayDynamicIndexing ),
580 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE , shaderClipDistance ),
581 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE , shaderCullDistance ),
582 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64 , shaderFloat64 ),
583 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64 , shaderInt64 ),
584 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16 , shaderInt16 ),
585 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY , shaderResourceResidency ),
586 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD , shaderResourceMinLod ),
587 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING , sparseBinding ),
588 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER , sparseResidencyBuffer ),
589 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D , sparseResidencyImage2D ),
590 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D , sparseResidencyImage3D ),
591 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES , sparseResidency2Samples ),
592 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES , sparseResidency4Samples ),
593 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES , sparseResidency8Samples ),
594 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES , sparseResidency16Samples ),
595 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED , sparseResidencyAliased ),
596 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE , variableMultisampleRate ),
597 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES , inheritedQueries ),
598 };
599
requireDeviceCoreFeature(const DeviceCoreFeature requiredFeature)600 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature)
601 {
602 const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures();
603 const vk::VkBool32* featuresAvailableArray = (vk::VkBool32*)(&featuresAvailable);
604 const deUint32 requiredFeatureIndex = static_cast<deUint32>(requiredFeature);
605
606 DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable));
607 DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset);
608
609 if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE)
610 TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName));
611
612 return true;
613 }
614
getInstanceProcAddr()615 void* Context::getInstanceProcAddr ()
616 {
617 return (void*)m_platformInterface.getGetInstanceProcAddr();
618 }
619
isBufferDeviceAddressSupported(void) const620 bool Context::isBufferDeviceAddressSupported(void) const
621 {
622 return isDeviceFunctionalitySupported("VK_KHR_buffer_device_address") ||
623 isDeviceFunctionalitySupported("VK_EXT_buffer_device_address");
624 }
625
626 // TestCase
627
initPrograms(SourceCollections &) const628 void TestCase::initPrograms (SourceCollections&) const
629 {
630 }
631
checkSupport(Context &) const632 void TestCase::checkSupport (Context&) const
633 {
634 }
635
delayedInit(void)636 void TestCase::delayedInit (void)
637 {
638 }
639
collectAndReportDebugMessages(vk::DebugReportRecorder & debugReportRecorder,Context & context)640 void collectAndReportDebugMessages(vk::DebugReportRecorder &debugReportRecorder, Context& context)
641 {
642 // \note We are not logging INFORMATION and DEBUG messages
643 static const vk::VkDebugReportFlagsEXT errorFlags = vk::VK_DEBUG_REPORT_ERROR_BIT_EXT;
644 static const vk::VkDebugReportFlagsEXT logFlags = errorFlags
645 | vk::VK_DEBUG_REPORT_WARNING_BIT_EXT
646 | vk::VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
647
648 typedef vk::DebugReportRecorder::MessageList DebugMessages;
649
650 const DebugMessages& messages = debugReportRecorder.getMessages();
651 tcu::TestLog& log = context.getTestContext().getLog();
652
653 if (messages.begin() != messages.end())
654 {
655 const tcu::ScopedLogSection section (log, "DebugMessages", "Debug Messages");
656 int numErrors = 0;
657
658 for (DebugMessages::const_iterator curMsg = messages.begin(); curMsg != messages.end(); ++curMsg)
659 {
660 if ((curMsg->flags & logFlags) != 0)
661 log << tcu::TestLog::Message << *curMsg << tcu::TestLog::EndMessage;
662
663 if ((curMsg->flags & errorFlags) != 0)
664 numErrors += 1;
665 }
666
667 debugReportRecorder.clearMessages();
668
669 if (numErrors > 0)
670 {
671 string errorMsg = de::toString(numErrors) + " API usage errors found";
672 context.resultSetOnValidation(true);
673 context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, errorMsg.c_str());
674 }
675 }
676 }
677
678 } // vkt
679