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 26 #include "vkRef.hpp" 27 #include "vkRefUtil.hpp" 28 #include "vkQueryUtil.hpp" 29 #include "vkDeviceUtil.hpp" 30 #include "vkMemUtil.hpp" 31 #include "vkPlatform.hpp" 32 #include "vkDebugReportUtil.hpp" 33 34 #include "tcuCommandLine.hpp" 35 #include "tcuTestLog.hpp" 36 37 #include "deSTLUtil.hpp" 38 #include "deMemory.h" 39 40 #if defined(DEQP_HAVE_VKRUNNER) 41 #include <vkrunner/vkrunner.h> 42 #endif 43 44 #include <set> 45 46 struct vk_executor; 47 48 namespace vkt 49 { 50 51 // Default device utilities 52 53 using std::vector; 54 using std::string; 55 using std::set; 56 using namespace vk; 57 58 namespace 59 { 60 61 vector<string> getValidationLayers (const vector<VkLayerProperties>& supportedLayers) 62 { 63 static const char* s_magicLayer = "VK_LAYER_LUNARG_standard_validation"; 64 static const char* s_defaultLayers[] = 65 { 66 "VK_LAYER_GOOGLE_threading", 67 "VK_LAYER_LUNARG_parameter_validation", 68 "VK_LAYER_LUNARG_device_limits", 69 "VK_LAYER_LUNARG_object_tracker", 70 "VK_LAYER_LUNARG_image", 71 "VK_LAYER_LUNARG_core_validation", 72 "VK_LAYER_LUNARG_swapchain", 73 "VK_LAYER_GOOGLE_unique_objects" 74 }; 75 76 vector<string> enabledLayers; 77 78 if (isLayerSupported(supportedLayers, RequiredLayer(s_magicLayer))) 79 enabledLayers.push_back(s_magicLayer); 80 else 81 { 82 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_defaultLayers); ++ndx) 83 { 84 if (isLayerSupported(supportedLayers, RequiredLayer(s_defaultLayers[ndx]))) 85 enabledLayers.push_back(s_defaultLayers[ndx]); 86 } 87 } 88 89 return enabledLayers; 90 } 91 92 vector<string> getValidationLayers (const PlatformInterface& vkp) 93 { 94 return getValidationLayers(enumerateInstanceLayerProperties(vkp)); 95 } 96 97 vector<string> getValidationLayers (const InstanceInterface& vki, VkPhysicalDevice physicalDevice) 98 { 99 return getValidationLayers(enumerateDeviceLayerProperties(vki, physicalDevice)); 100 } 101 102 vector<string> filterExtensions (const vector<VkExtensionProperties>& extensions) 103 { 104 vector<string> enabledExtensions; 105 const char* extensionGroups[] = 106 { 107 "VK_KHR_", 108 "VK_EXT_", 109 "VK_KHX_" 110 }; 111 112 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++) 113 { 114 for (int extGroupNdx = 0; extGroupNdx < DE_LENGTH_OF_ARRAY(extensionGroups); extGroupNdx++) 115 { 116 if (deStringBeginsWith(extensions[extNdx].extensionName, extensionGroups[extGroupNdx])) 117 enabledExtensions.push_back(extensions[extNdx].extensionName); 118 } 119 } 120 121 return enabledExtensions; 122 } 123 124 vector<string> addExtensions (const vector<string>& a, const vector<const char*>& b) 125 { 126 vector<string> res (a); 127 128 for (vector<const char*>::const_iterator bIter = b.begin(); bIter != b.end(); ++bIter) 129 { 130 if (!de::contains(res.begin(), res.end(), string(*bIter))) 131 res.push_back(string(*bIter)); 132 } 133 134 return res; 135 } 136 137 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b) 138 { 139 vector<string> res; 140 set<string> removeExts (b.begin(), b.end()); 141 142 for (vector<string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter) 143 { 144 if (!de::contains(removeExts, *aIter)) 145 res.push_back(*aIter); 146 } 147 148 return res; 149 } 150 151 vector<string> addCoreInstanceExtensions (const vector<string>& extensions, deUint32 instanceVersion) 152 { 153 vector<const char*> coreExtensions; 154 getCoreInstanceExtensions(instanceVersion, coreExtensions); 155 return addExtensions(extensions, coreExtensions); 156 } 157 158 vector<string> addCoreDeviceExtensions(const vector<string>& extensions, deUint32 instanceVersion) 159 { 160 vector<const char*> coreExtensions; 161 getCoreDeviceExtensions(instanceVersion, coreExtensions); 162 return addExtensions(extensions, coreExtensions); 163 } 164 165 deUint32 getTargetInstanceVersion (const PlatformInterface& vkp) 166 { 167 deUint32 version = pack(ApiVersion(1, 0, 0)); 168 169 if (vkp.enumerateInstanceVersion(&version) != VK_SUCCESS) 170 TCU_THROW(InternalError, "Enumerate instance version error"); 171 return version; 172 } 173 174 std::pair<deUint32, deUint32> determineDeviceVersions(const PlatformInterface& vkp, deUint32 apiVersion, const tcu::CommandLine& cmdLine) 175 { 176 Move<VkInstance> preinstance = createDefaultInstance(vkp, apiVersion); 177 InstanceDriver preinterface (vkp, preinstance.get()); 178 179 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(preinterface, preinstance.get()); 180 deUint32 lowestDeviceVersion = 0xFFFFFFFFu; 181 for (deUint32 deviceNdx = 0u; deviceNdx < devices.size(); ++deviceNdx) 182 { 183 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, devices[deviceNdx]); 184 if (props.apiVersion < lowestDeviceVersion) 185 lowestDeviceVersion = props.apiVersion; 186 } 187 188 const vk::VkPhysicalDevice choosenDevice = chooseDevice(preinterface, *preinstance, cmdLine); 189 const VkPhysicalDeviceProperties props = getPhysicalDeviceProperties(preinterface, choosenDevice); 190 const deUint32 choosenDeviceVersion = props.apiVersion; 191 192 return std::make_pair(choosenDeviceVersion, lowestDeviceVersion); 193 } 194 195 196 Move<VkInstance> createInstance (const PlatformInterface& vkp, deUint32 apiVersion, const vector<string>& enabledExtensions, const tcu::CommandLine& cmdLine) 197 { 198 const bool isValidationEnabled = cmdLine.isValidationEnabled(); 199 vector<string> enabledLayers; 200 201 // \note Extensions in core are not explicitly enabled even though 202 // they are in the extension list advertised to tests. 203 vector<const char*> coreExtensions; 204 getCoreInstanceExtensions(apiVersion, coreExtensions); 205 vector<string> nonCoreExtensions (removeExtensions(enabledExtensions, coreExtensions)); 206 207 if (isValidationEnabled) 208 { 209 if (!isDebugReportSupported(vkp)) 210 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported"); 211 212 enabledLayers = getValidationLayers(vkp); 213 if (enabledLayers.empty()) 214 TCU_THROW(NotSupportedError, "No validation layers found"); 215 } 216 217 return createDefaultInstance(vkp, apiVersion, enabledLayers, nonCoreExtensions); 218 } 219 220 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps) 221 { 222 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice); 223 224 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++) 225 { 226 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps) 227 return (deUint32)queueNdx; 228 } 229 230 TCU_THROW(NotSupportedError, "No matching queue found"); 231 } 232 233 Move<VkDevice> createDefaultDevice (const PlatformInterface& vkp, 234 VkInstance instance, 235 const InstanceInterface& vki, 236 VkPhysicalDevice physicalDevice, 237 const deUint32 apiVersion, 238 deUint32 queueIndex, 239 deUint32 sparseQueueIndex, 240 const VkPhysicalDeviceFeatures2& enabledFeatures, 241 const vector<string>& enabledExtensions, 242 const tcu::CommandLine& cmdLine) 243 { 244 VkDeviceQueueCreateInfo queueInfo[2]; 245 VkDeviceCreateInfo deviceInfo; 246 vector<string> enabledLayers; 247 vector<const char*> layerPtrs; 248 vector<const char*> extensionPtrs; 249 const float queuePriority = 1.0f; 250 const deUint32 numQueues = (enabledFeatures.features.sparseBinding && (queueIndex != sparseQueueIndex)) ? 2 : 1; 251 252 deMemset(&queueInfo, 0, sizeof(queueInfo)); 253 deMemset(&deviceInfo, 0, sizeof(deviceInfo)); 254 255 if (cmdLine.isValidationEnabled()) 256 { 257 enabledLayers = getValidationLayers(vki, physicalDevice); 258 if (enabledLayers.empty()) 259 TCU_THROW(NotSupportedError, "No validation layers found"); 260 } 261 262 layerPtrs.resize(enabledLayers.size()); 263 264 for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx) 265 layerPtrs[ndx] = enabledLayers[ndx].c_str(); 266 267 // \note Extensions in core are not explicitly enabled even though 268 // they are in the extension list advertised to tests. 269 vector<const char*> coreExtensions; 270 getCoreDeviceExtensions(apiVersion, coreExtensions); 271 vector<string> nonCoreExtensions(removeExtensions(enabledExtensions, coreExtensions)); 272 273 extensionPtrs.resize(nonCoreExtensions.size()); 274 275 for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx) 276 extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str(); 277 278 queueInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 279 queueInfo[0].pNext = DE_NULL; 280 queueInfo[0].flags = (VkDeviceQueueCreateFlags)0u; 281 queueInfo[0].queueFamilyIndex = queueIndex; 282 queueInfo[0].queueCount = 1u; 283 queueInfo[0].pQueuePriorities = &queuePriority; 284 285 if (numQueues > 1) 286 { 287 queueInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 288 queueInfo[1].pNext = DE_NULL; 289 queueInfo[1].flags = (VkDeviceQueueCreateFlags)0u; 290 queueInfo[1].queueFamilyIndex = sparseQueueIndex; 291 queueInfo[1].queueCount = 1u; 292 queueInfo[1].pQueuePriorities = &queuePriority; 293 } 294 295 // VK_KHR_get_physical_device_properties2 is used if enabledFeatures.pNext != 0 296 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 297 deviceInfo.pNext = enabledFeatures.pNext ? &enabledFeatures : DE_NULL; 298 deviceInfo.queueCreateInfoCount = numQueues; 299 deviceInfo.pQueueCreateInfos = queueInfo; 300 deviceInfo.enabledExtensionCount = (deUint32)extensionPtrs.size(); 301 deviceInfo.ppEnabledExtensionNames = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]); 302 deviceInfo.enabledLayerCount = (deUint32)layerPtrs.size(); 303 deviceInfo.ppEnabledLayerNames = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]); 304 deviceInfo.pEnabledFeatures = enabledFeatures.pNext ? DE_NULL : &enabledFeatures.features; 305 306 return createDevice(vkp, instance, vki, physicalDevice, &deviceInfo); 307 }; 308 309 bool isPhysicalDeviceFeatures2Supported (const deUint32 version, const vector<string>& instanceExtensions) 310 { 311 return isInstanceExtensionSupported(version, instanceExtensions, "VK_KHR_get_physical_device_properties2"); 312 } 313 314 class DeviceFeatures 315 { 316 public: 317 VkPhysicalDeviceFeatures2 coreFeatures; 318 VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYCbCrConversionFeatures; 319 VkPhysicalDevice8BitStorageFeaturesKHR eightBitStorageFeatures; 320 VkPhysicalDevice16BitStorageFeatures sixteenBitStorageFeatures; 321 VkPhysicalDeviceVariablePointerFeatures variablePointerFeatures; 322 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertexAttributeDivisorFeatures; 323 VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptorIndexingFeatures; 324 VkPhysicalDeviceInlineUniformBlockFeaturesEXT inlineUniformBlockFeatures; 325 VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkanMemoryModelFeatures; 326 VkPhysicalDeviceShaderAtomicInt64FeaturesKHR shaderAtomicInt64Features; 327 VkPhysicalDeviceConditionalRenderingFeaturesEXT conditionalRenderingFeatures; 328 VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalarBlockLayoutFeatures; 329 VkPhysicalDeviceFloat16Int8FeaturesKHR float16Int8Features; 330 331 DeviceFeatures (const InstanceInterface& vki, 332 const deUint32 apiVersion, 333 const VkPhysicalDevice& physicalDevice, 334 const vector<string>& instanceExtensions, 335 const vector<string>& deviceExtensions) 336 { 337 deMemset(&coreFeatures, 0, sizeof(coreFeatures)); 338 deMemset(&samplerYCbCrConversionFeatures, 0, sizeof(samplerYCbCrConversionFeatures)); 339 deMemset(&eightBitStorageFeatures, 0, sizeof(eightBitStorageFeatures)); 340 deMemset(&sixteenBitStorageFeatures, 0, sizeof(sixteenBitStorageFeatures)); 341 deMemset(&variablePointerFeatures, 0, sizeof(variablePointerFeatures)); 342 deMemset(&descriptorIndexingFeatures, 0, sizeof(descriptorIndexingFeatures)); 343 deMemset(&inlineUniformBlockFeatures, 0, sizeof(inlineUniformBlockFeatures)); 344 deMemset(&float16Int8Features, 0, sizeof(float16Int8Features)); 345 deMemset(&vertexAttributeDivisorFeatures, 0, sizeof(vertexAttributeDivisorFeatures)); 346 deMemset(&descriptorIndexingFeatures, 0, sizeof(descriptorIndexingFeatures)); 347 deMemset(&inlineUniformBlockFeatures, 0, sizeof(inlineUniformBlockFeatures)); 348 deMemset(&vulkanMemoryModelFeatures, 0, sizeof(vulkanMemoryModelFeatures)); 349 deMemset(&shaderAtomicInt64Features, 0, sizeof(shaderAtomicInt64Features)); 350 deMemset(&conditionalRenderingFeatures, 0, sizeof(conditionalRenderingFeatures)); 351 deMemset(&scalarBlockLayoutFeatures, 0, sizeof(scalarBlockLayoutFeatures)); 352 353 coreFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 354 samplerYCbCrConversionFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; 355 eightBitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR; 356 sixteenBitStorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR; 357 variablePointerFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR; 358 descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; 359 inlineUniformBlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; 360 float16Int8Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; 361 vertexAttributeDivisorFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; 362 descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; 363 inlineUniformBlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT; 364 vulkanMemoryModelFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR; 365 shaderAtomicInt64Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR; 366 conditionalRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT; 367 scalarBlockLayoutFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT; 368 369 vector<VkExtensionProperties> deviceExtensionProperties = 370 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); 371 372 if (isPhysicalDeviceFeatures2Supported(apiVersion, instanceExtensions)) 373 { 374 void** nextPtr = &coreFeatures.pNext; 375 376 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion")) 377 { 378 *nextPtr = &samplerYCbCrConversionFeatures; 379 nextPtr = &samplerYCbCrConversionFeatures.pNext; 380 } 381 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_8bit_storage")) 382 { 383 *nextPtr = &eightBitStorageFeatures; 384 nextPtr = &eightBitStorageFeatures.pNext; 385 } 386 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_16bit_storage")) 387 { 388 *nextPtr = &sixteenBitStorageFeatures; 389 nextPtr = &sixteenBitStorageFeatures.pNext; 390 } 391 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_variable_pointers")) 392 { 393 *nextPtr = &variablePointerFeatures; 394 nextPtr = &variablePointerFeatures.pNext; 395 } 396 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_descriptor_indexing")) 397 { 398 *nextPtr = &descriptorIndexingFeatures; 399 nextPtr = &descriptorIndexingFeatures.pNext; 400 } 401 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_inline_uniform_block")) 402 { 403 *nextPtr = &inlineUniformBlockFeatures; 404 nextPtr = &inlineUniformBlockFeatures.pNext; 405 } 406 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_shader_float16_int8")) 407 { 408 *nextPtr = &float16Int8Features; 409 nextPtr = &float16Int8Features.pNext; 410 } 411 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_vertex_attribute_divisor")) 412 { 413 *nextPtr = &vertexAttributeDivisorFeatures; 414 nextPtr = &vertexAttributeDivisorFeatures.pNext; 415 } 416 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_vulkan_memory_model")) 417 { 418 for (size_t i = 0; i < deviceExtensionProperties.size(); ++i) 419 { 420 if (deStringEqual(deviceExtensionProperties[i].extensionName, "VK_KHR_vulkan_memory_model")) 421 { 422 if (deviceExtensionProperties[i].specVersion == VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION) 423 { 424 *nextPtr = &vulkanMemoryModelFeatures; 425 nextPtr = &vulkanMemoryModelFeatures.pNext; 426 } 427 break; 428 } 429 } 430 } 431 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_shader_atomic_int64")) 432 { 433 *nextPtr = &shaderAtomicInt64Features; 434 nextPtr = &shaderAtomicInt64Features.pNext; 435 } 436 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_conditional_rendering")) 437 { 438 *nextPtr = &conditionalRenderingFeatures; 439 nextPtr = &conditionalRenderingFeatures.pNext; 440 } 441 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_EXT_scalar_block_layout")) 442 { 443 *nextPtr = &scalarBlockLayoutFeatures; 444 nextPtr = &scalarBlockLayoutFeatures.pNext; 445 } 446 447 vki.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures); 448 } 449 else 450 coreFeatures.features = getPhysicalDeviceFeatures(vki, physicalDevice); 451 452 // Disable robustness by default, as it has an impact on performance on some HW. 453 coreFeatures.features.robustBufferAccess = false; 454 } 455 }; 456 457 } // anonymous 458 459 class DefaultDevice 460 { 461 public: 462 DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine); 463 ~DefaultDevice (void); 464 465 VkInstance getInstance (void) const { return *m_instance; } 466 const InstanceInterface& getInstanceInterface (void) const { return m_instanceInterface; } 467 deUint32 getAvailableInstanceVersion (void) const { return m_availableInstanceVersion; } 468 const vector<string>& getInstanceExtensions (void) const { return m_instanceExtensions; } 469 470 VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; } 471 deUint32 getDeviceVersion (void) const { return m_deviceVersion; } 472 const VkPhysicalDeviceFeatures& getDeviceFeatures (void) const { return m_deviceFeatures.coreFeatures.features; } 473 const VkPhysicalDeviceFeatures2& getDeviceFeatures2 (void) const { return m_deviceFeatures.coreFeatures; } 474 const VkPhysicalDeviceSamplerYcbcrConversionFeatures& getSamplerYCbCrConversionFeatures (void) const { return m_deviceFeatures.samplerYCbCrConversionFeatures; } 475 const VkPhysicalDevice8BitStorageFeaturesKHR& get8BitStorageFeatures (void) const { return m_deviceFeatures.eightBitStorageFeatures; } 476 const VkPhysicalDevice16BitStorageFeatures& get16BitStorageFeatures (void) const { return m_deviceFeatures.sixteenBitStorageFeatures; } 477 const VkPhysicalDeviceVariablePointerFeatures& getVariablePointerFeatures (void) const { return m_deviceFeatures.variablePointerFeatures; } 478 const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT&getVertexAttributeDivisorFeatures (void) const { return m_deviceFeatures.vertexAttributeDivisorFeatures; } 479 const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& getVulkanMemoryModelFeatures (void) const { return m_deviceFeatures.vulkanMemoryModelFeatures; } 480 const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR& getShaderAtomicInt64Features (void) const { return m_deviceFeatures.shaderAtomicInt64Features; } 481 const VkPhysicalDeviceConditionalRenderingFeaturesEXT& getConditionalRenderingFeatures (void) const { return m_deviceFeatures.conditionalRenderingFeatures; } 482 const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& getScalarBlockLayoutFeatures (void) const { return m_deviceFeatures.scalarBlockLayoutFeatures; } 483 const VkPhysicalDeviceFloat16Int8FeaturesKHR& getFloat16Int8Features (void) const { return m_deviceFeatures.float16Int8Features; } 484 VkDevice getDevice (void) const { return *m_device; } 485 const DeviceInterface& getDeviceInterface (void) const { return m_deviceInterface; } 486 const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties; } 487 const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; } 488 489 deUint32 getUsedApiVersion (void) const { return m_usedApiVersion; } 490 491 deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; } 492 VkQueue getUniversalQueue (void) const; 493 deUint32 getSparseQueueFamilyIndex (void) const { return m_sparseQueueFamilyIndex; } 494 VkQueue getSparseQueue (void) const; 495 496 private: 497 498 const deUint32 m_availableInstanceVersion; 499 500 const std::pair<deUint32, deUint32> m_deviceVersions; 501 const deUint32 m_usedApiVersion; 502 503 const vector<string> m_instanceExtensions; 504 const Unique<VkInstance> m_instance; 505 const InstanceDriver m_instanceInterface; 506 507 const VkPhysicalDevice m_physicalDevice; 508 const deUint32 m_deviceVersion; 509 510 const vector<string> m_deviceExtensions; 511 const DeviceFeatures m_deviceFeatures; 512 513 const deUint32 m_universalQueueFamilyIndex; 514 const deUint32 m_sparseQueueFamilyIndex; 515 const VkPhysicalDeviceProperties m_deviceProperties; 516 517 const Unique<VkDevice> m_device; 518 const DeviceDriver m_deviceInterface; 519 520 }; 521 522 static deUint32 sanitizeApiVersion(deUint32 v) 523 { 524 return VK_MAKE_VERSION( VK_VERSION_MAJOR(v), VK_VERSION_MINOR(v), 0 ); 525 } 526 527 DefaultDevice::DefaultDevice (const PlatformInterface& vkPlatform, const tcu::CommandLine& cmdLine) 528 : m_availableInstanceVersion (getTargetInstanceVersion(vkPlatform)) 529 , m_deviceVersions (determineDeviceVersions(vkPlatform, m_availableInstanceVersion, cmdLine)) 530 , m_usedApiVersion (sanitizeApiVersion(deMinu32(m_availableInstanceVersion, m_deviceVersions.first))) 531 532 , m_instanceExtensions (addCoreInstanceExtensions(filterExtensions(enumerateInstanceExtensionProperties(vkPlatform, DE_NULL)), m_usedApiVersion)) 533 , m_instance (createInstance(vkPlatform, m_usedApiVersion, m_instanceExtensions, cmdLine)) 534 535 , m_instanceInterface (vkPlatform, *m_instance) 536 , m_physicalDevice (chooseDevice(m_instanceInterface, *m_instance, cmdLine)) 537 , m_deviceVersion (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice).apiVersion) 538 539 , m_deviceExtensions (addCoreDeviceExtensions(filterExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)), m_usedApiVersion)) 540 , m_deviceFeatures (m_instanceInterface, m_usedApiVersion, m_physicalDevice, m_instanceExtensions, m_deviceExtensions) 541 , m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT)) 542 , m_sparseQueueFamilyIndex (m_deviceFeatures.coreFeatures.features.sparseBinding ? findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_SPARSE_BINDING_BIT) : 0) 543 , m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice)) 544 , m_device (createDefaultDevice(vkPlatform, *m_instance, m_instanceInterface, m_physicalDevice, m_usedApiVersion, m_universalQueueFamilyIndex, m_sparseQueueFamilyIndex, m_deviceFeatures.coreFeatures, m_deviceExtensions, cmdLine)) 545 , m_deviceInterface (vkPlatform, *m_instance, *m_device) 546 { 547 DE_ASSERT(m_deviceVersions.first == m_deviceVersion); 548 } 549 550 DefaultDevice::~DefaultDevice (void) 551 { 552 } 553 554 VkQueue DefaultDevice::getUniversalQueue (void) const 555 { 556 return getDeviceQueue(m_deviceInterface, *m_device, m_universalQueueFamilyIndex, 0); 557 } 558 559 VkQueue DefaultDevice::getSparseQueue (void) const 560 { 561 if (!m_deviceFeatures.coreFeatures.features.sparseBinding) 562 TCU_THROW(NotSupportedError, "Sparse binding not supported."); 563 564 return getDeviceQueue(m_deviceInterface, *m_device, m_sparseQueueFamilyIndex, 0); 565 } 566 567 namespace 568 { 569 // Allocator utilities 570 571 vk::Allocator* createAllocator (DefaultDevice* device) 572 { 573 const VkPhysicalDeviceMemoryProperties memoryProperties = vk::getPhysicalDeviceMemoryProperties(device->getInstanceInterface(), device->getPhysicalDevice()); 574 575 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time) 576 return new SimpleAllocator(device->getDeviceInterface(), device->getDevice(), memoryProperties); 577 } 578 579 } // anonymous 580 581 // Context 582 583 void Context::errorCb(const char* message, 584 void* user_data) 585 { 586 Context* context = (Context*) user_data; 587 588 context->getTestContext().getLog() 589 << tcu::TestLog::Message 590 << message 591 << "\n" 592 << tcu::TestLog::EndMessage; 593 } 594 595 Context::Context (tcu::TestContext& testCtx, 596 const vk::PlatformInterface& platformInterface, 597 vk::BinaryCollection& progCollection) 598 : m_testCtx (testCtx) 599 , m_platformInterface (platformInterface) 600 , m_progCollection (progCollection) 601 , m_device (new DefaultDevice(m_platformInterface, testCtx.getCommandLine())) 602 , m_allocator (createAllocator(m_device.get())) 603 { 604 #if defined(DEQP_HAVE_VKRUNNER) 605 m_config = vr_config_new(); 606 vr_config_set_user_data(m_config, this); 607 vr_config_set_error_cb(m_config, errorCb); 608 m_executor = vr_executor_new(m_config); 609 vr_executor_set_device(m_executor, 610 getInstanceProc, 611 this, 612 getPhysicalDevice(), 613 getUniversalQueueFamilyIndex(), 614 getDevice()); 615 #endif 616 } 617 618 Context::~Context (void) 619 { 620 #if defined(DEQP_HAVE_VKRUNNER) 621 vr_config_free(m_config); 622 vr_executor_free(m_executor); 623 #endif 624 } 625 626 deUint32 Context::getAvailableInstanceVersion (void) const { return m_device->getAvailableInstanceVersion(); } 627 const vector<string>& Context::getInstanceExtensions (void) const { return m_device->getInstanceExtensions(); } 628 vk::VkInstance Context::getInstance (void) const { return m_device->getInstance(); } 629 const vk::InstanceInterface& Context::getInstanceInterface (void) const { return m_device->getInstanceInterface(); } 630 vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); } 631 deUint32 Context::getDeviceVersion (void) const { return m_device->getDeviceVersion(); } 632 const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); } 633 const vk::VkPhysicalDeviceFeatures2& Context::getDeviceFeatures2 (void) const { return m_device->getDeviceFeatures2(); } 634 const vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures& 635 Context::getSamplerYCbCrConversionFeatures 636 (void) const { return m_device->getSamplerYCbCrConversionFeatures(); } 637 const vk::VkPhysicalDevice8BitStorageFeaturesKHR& 638 Context::get8BitStorageFeatures (void) const { return m_device->get8BitStorageFeatures(); } 639 const vk::VkPhysicalDevice16BitStorageFeatures& 640 Context::get16BitStorageFeatures (void) const { return m_device->get16BitStorageFeatures(); } 641 const vk::VkPhysicalDeviceVariablePointerFeatures& 642 Context::getVariablePointerFeatures (void) const { return m_device->getVariablePointerFeatures(); } 643 const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT& 644 Context::getVertexAttributeDivisorFeatures (void) const { return m_device->getVertexAttributeDivisorFeatures(); } 645 const vk::VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& 646 Context::getVulkanMemoryModelFeatures (void) const { return m_device->getVulkanMemoryModelFeatures(); } 647 const vk::VkPhysicalDeviceShaderAtomicInt64FeaturesKHR& 648 Context::getShaderAtomicInt64Features (void) const { return m_device->getShaderAtomicInt64Features(); } 649 const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT& 650 Context::getConditionalRenderingFeatures(void) const { return m_device->getConditionalRenderingFeatures(); } 651 const vk::VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& 652 Context::getScalarBlockLayoutFeatures (void) const { return m_device->getScalarBlockLayoutFeatures(); } 653 const vk::VkPhysicalDeviceFloat16Int8FeaturesKHR& 654 Context::getFloat16Int8Features (void) const { return m_device->getFloat16Int8Features(); } 655 const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); } 656 const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); } 657 vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); } 658 const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); } 659 deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); } 660 vk::VkQueue Context::getUniversalQueue (void) const { return m_device->getUniversalQueue(); } 661 deUint32 Context::getSparseQueueFamilyIndex (void) const { return m_device->getSparseQueueFamilyIndex(); } 662 vk::VkQueue Context::getSparseQueue (void) const { return m_device->getSparseQueue(); } 663 vk::Allocator& Context::getDefaultAllocator (void) const { return *m_allocator; } 664 deUint32 Context::getUsedApiVersion (void) const { return m_device->getUsedApiVersion(); } 665 vr_executor* Context::getExecutor (void) const 666 { return m_executor; } 667 bool Context::contextSupports (const deUint32 majorNum, const deUint32 minorNum, const deUint32 patchNum) const 668 { return m_device->getUsedApiVersion() >= VK_MAKE_VERSION(majorNum, minorNum, patchNum); } 669 bool Context::contextSupports (const ApiVersion version) const 670 { return m_device->getUsedApiVersion() >= pack(version); } 671 bool Context::contextSupports (const deUint32 requiredApiVersionBits) const 672 { return m_device->getUsedApiVersion() >= requiredApiVersionBits; } 673 674 bool Context::requireDeviceExtension (const std::string& required) 675 { 676 if (!isDeviceExtensionSupported(getUsedApiVersion(), getDeviceExtensions(), required)) 677 TCU_THROW(NotSupportedError, required + " is not supported"); 678 679 return true; 680 } 681 682 bool Context::requireInstanceExtension (const std::string& required) 683 { 684 if (!isInstanceExtensionSupported(getUsedApiVersion(), getInstanceExtensions(), required)) 685 TCU_THROW(NotSupportedError, required + " is not supported"); 686 687 return true; 688 } 689 690 struct DeviceCoreFeaturesTable 691 { 692 const char* featureName; 693 const deUint32 featureArrayIndex; 694 const deUint32 featureArrayOffset; 695 }; 696 697 #define DEVICE_CORE_FEATURE_OFFSET(FEATURE_FIELD_NAME) DE_OFFSET_OF(VkPhysicalDeviceFeatures, FEATURE_FIELD_NAME) 698 #define DEVICE_CORE_FEATURE_ENTRY(BITNAME, FIELDNAME) { #FIELDNAME, BITNAME, DEVICE_CORE_FEATURE_OFFSET(FIELDNAME) } 699 700 const DeviceCoreFeaturesTable deviceCoreFeaturesTable[] = 701 { 702 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ROBUST_BUFFER_ACCESS , robustBufferAccess ), 703 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FULL_DRAW_INDEX_UINT32 , fullDrawIndexUint32 ), 704 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY , imageCubeArray ), 705 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INDEPENDENT_BLEND , independentBlend ), 706 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_GEOMETRY_SHADER , geometryShader ), 707 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TESSELLATION_SHADER , tessellationShader ), 708 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING , sampleRateShading ), 709 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DUAL_SRC_BLEND , dualSrcBlend ), 710 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LOGIC_OP , logicOp ), 711 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT , multiDrawIndirect ), 712 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE , drawIndirectFirstInstance ), 713 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_CLAMP , depthClamp ), 714 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP , depthBiasClamp ), 715 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FILL_MODE_NON_SOLID , fillModeNonSolid ), 716 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_DEPTH_BOUNDS , depthBounds ), 717 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_WIDE_LINES , wideLines ), 718 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_LARGE_POINTS , largePoints ), 719 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_ALPHA_TO_ONE , alphaToOne ), 720 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_MULTI_VIEWPORT , multiViewport ), 721 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SAMPLER_ANISOTROPY , samplerAnisotropy ), 722 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ETC2 , textureCompressionETC2 ), 723 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_ASTC_LDR , textureCompressionASTC_LDR ), 724 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_TEXTURE_COMPRESSION_BC , textureCompressionBC ), 725 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_OCCLUSION_QUERY_PRECISE , occlusionQueryPrecise ), 726 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY , pipelineStatisticsQuery ), 727 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS , vertexPipelineStoresAndAtomics ), 728 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS , fragmentStoresAndAtomics ), 729 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE , shaderTessellationAndGeometryPointSize ), 730 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_IMAGE_GATHER_EXTENDED , shaderImageGatherExtended ), 731 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS , shaderStorageImageExtendedFormats ), 732 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_MULTISAMPLE , shaderStorageImageMultisample ), 733 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT , shaderStorageImageReadWithoutFormat ), 734 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT , shaderStorageImageWriteWithoutFormat ), 735 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderUniformBufferArrayDynamicIndexing ), 736 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderSampledImageArrayDynamicIndexing ), 737 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING , shaderStorageBufferArrayDynamicIndexing ), 738 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING , shaderStorageImageArrayDynamicIndexing ), 739 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE , shaderClipDistance ), 740 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_CULL_DISTANCE , shaderCullDistance ), 741 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_FLOAT64 , shaderFloat64 ), 742 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT64 , shaderInt64 ), 743 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_INT16 , shaderInt16 ), 744 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY , shaderResourceResidency ), 745 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SHADER_RESOURCE_MIN_LOD , shaderResourceMinLod ), 746 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_BINDING , sparseBinding ), 747 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER , sparseResidencyBuffer ), 748 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D , sparseResidencyImage2D ), 749 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D , sparseResidencyImage3D ), 750 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY2_SAMPLES , sparseResidency2Samples ), 751 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY4_SAMPLES , sparseResidency4Samples ), 752 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY8_SAMPLES , sparseResidency8Samples ), 753 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY16_SAMPLES , sparseResidency16Samples ), 754 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED , sparseResidencyAliased ), 755 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_VARIABLE_MULTISAMPLE_RATE , variableMultisampleRate ), 756 DEVICE_CORE_FEATURE_ENTRY(DEVICE_CORE_FEATURE_INHERITED_QUERIES , inheritedQueries ), 757 }; 758 759 bool Context::requireDeviceCoreFeature (const DeviceCoreFeature requiredFeature) 760 { 761 const vk::VkPhysicalDeviceFeatures& featuresAvailable = getDeviceFeatures(); 762 const vk::VkBool32* featuresAvailableArray = (vk::VkBool32*)(&featuresAvailable); 763 const deUint32 requiredFeatureIndex = static_cast<deUint32>(requiredFeature); 764 765 DE_ASSERT(requiredFeatureIndex * sizeof(vk::VkBool32) < sizeof(featuresAvailable)); 766 DE_ASSERT(deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayIndex * sizeof(vk::VkBool32) == deviceCoreFeaturesTable[requiredFeatureIndex].featureArrayOffset); 767 768 if (featuresAvailableArray[requiredFeatureIndex] == DE_FALSE) 769 TCU_THROW(NotSupportedError, "Requested core feature is not supported: " + std::string(deviceCoreFeaturesTable[requiredFeatureIndex].featureName)); 770 771 return true; 772 } 773 774 void* Context::getInstanceProc (const char* name, void* user_data) 775 { 776 Context *context = (Context*) user_data; 777 return (void*) context->m_platformInterface.getInstanceProcAddr(context->getInstance(), name); 778 } 779 780 // TestCase 781 782 void TestCase::initPrograms (SourceCollections&) const 783 { 784 } 785 786 void TestCase::checkSupport (Context&) const 787 { 788 } 789 790 } // vkt 791