1e5c31af7Sopenharmony_ci// Copyright 2019 The Amber Authors. 2e5c31af7Sopenharmony_ci// 3e5c31af7Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4e5c31af7Sopenharmony_ci// you may not use this file except in compliance with the License. 5e5c31af7Sopenharmony_ci// You may obtain a copy of the License at 6e5c31af7Sopenharmony_ci// 7e5c31af7Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8e5c31af7Sopenharmony_ci// 9e5c31af7Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10e5c31af7Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11e5c31af7Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e5c31af7Sopenharmony_ci// See the License for the specific language governing permissions and 13e5c31af7Sopenharmony_ci// limitations under the License. 14e5c31af7Sopenharmony_ci 15e5c31af7Sopenharmony_ci#include "samples/config_helper_vulkan.h" 16e5c31af7Sopenharmony_ci 17e5c31af7Sopenharmony_ci#include <vulkan/vulkan.h> 18e5c31af7Sopenharmony_ci 19e5c31af7Sopenharmony_ci#include <algorithm> 20e5c31af7Sopenharmony_ci#include <cstring> 21e5c31af7Sopenharmony_ci#include <iostream> 22e5c31af7Sopenharmony_ci#include <iterator> 23e5c31af7Sopenharmony_ci#include <set> 24e5c31af7Sopenharmony_ci#include <sstream> 25e5c31af7Sopenharmony_ci#include <utility> 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "samples/log.h" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_cinamespace sample { 30e5c31af7Sopenharmony_cinamespace { 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ciconst char* const kRequiredValidationLayers[] = { 33e5c31af7Sopenharmony_ci#ifdef __ANDROID__ 34e5c31af7Sopenharmony_ci // Note that the order of enabled layers is important. It is 35e5c31af7Sopenharmony_ci // based on Android NDK Vulkan document. 36e5c31af7Sopenharmony_ci "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", 37e5c31af7Sopenharmony_ci "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", 38e5c31af7Sopenharmony_ci "VK_LAYER_GOOGLE_unique_objects", 39e5c31af7Sopenharmony_ci#else // __ANDROID__ 40e5c31af7Sopenharmony_ci "VK_LAYER_KHRONOS_validation", 41e5c31af7Sopenharmony_ci#endif // __ANDROID__ 42e5c31af7Sopenharmony_ci}; 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ciconst size_t kNumberOfRequiredValidationLayers = 45e5c31af7Sopenharmony_ci sizeof(kRequiredValidationLayers) / sizeof(const char*); 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ciconst char kVariablePointers[] = "VariablePointerFeatures.variablePointers"; 48e5c31af7Sopenharmony_ciconst char kVariablePointersStorageBuffer[] = 49e5c31af7Sopenharmony_ci "VariablePointerFeatures.variablePointersStorageBuffer"; 50e5c31af7Sopenharmony_ciconst char kFloat16Int8_Float16[] = "Float16Int8Features.shaderFloat16"; 51e5c31af7Sopenharmony_ciconst char kFloat16Int8_Int8[] = "Float16Int8Features.shaderInt8"; 52e5c31af7Sopenharmony_ciconst char k8BitStorage_Storage[] = 53e5c31af7Sopenharmony_ci "Storage8BitFeatures.storageBuffer8BitAccess"; 54e5c31af7Sopenharmony_ciconst char k8BitStorage_UniformAndStorage[] = 55e5c31af7Sopenharmony_ci "Storage8BitFeatures.uniformAndStorageBuffer8BitAccess"; 56e5c31af7Sopenharmony_ciconst char k8BitStorage_PushConstant[] = 57e5c31af7Sopenharmony_ci "Storage8BitFeatures.storagePushConstant8"; 58e5c31af7Sopenharmony_ciconst char k16BitStorage_Storage[] = 59e5c31af7Sopenharmony_ci "Storage16BitFeatures.storageBuffer16BitAccess"; 60e5c31af7Sopenharmony_ciconst char k16BitStorage_UniformAndStorage[] = 61e5c31af7Sopenharmony_ci "Storage16BitFeatures.uniformAndStorageBuffer16BitAccess"; 62e5c31af7Sopenharmony_ciconst char k16BitStorage_PushConstant[] = 63e5c31af7Sopenharmony_ci "Storage16BitFeatures.storagePushConstant16"; 64e5c31af7Sopenharmony_ciconst char k16BitStorage_InputOutput[] = 65e5c31af7Sopenharmony_ci "Storage16BitFeatures.storageInputOutput16"; 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ciconst char kSubgroupSizeControl[] = "SubgroupSizeControl.subgroupSizeControl"; 68e5c31af7Sopenharmony_ciconst char kComputeFullSubgroups[] = "SubgroupSizeControl.computeFullSubgroups"; 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ciconst char kShaderSubgroupExtendedTypes[] = 71e5c31af7Sopenharmony_ci "ShaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes"; 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ciconst char kExtensionForValidationLayer[] = "VK_EXT_debug_report"; 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ciVKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT flag, 76e5c31af7Sopenharmony_ci VkDebugReportObjectTypeEXT, 77e5c31af7Sopenharmony_ci uint64_t, 78e5c31af7Sopenharmony_ci size_t, 79e5c31af7Sopenharmony_ci int32_t, 80e5c31af7Sopenharmony_ci const char* layerPrefix, 81e5c31af7Sopenharmony_ci const char* msg, 82e5c31af7Sopenharmony_ci void*) { 83e5c31af7Sopenharmony_ci std::string flag_message; 84e5c31af7Sopenharmony_ci switch (flag) { 85e5c31af7Sopenharmony_ci case VK_DEBUG_REPORT_ERROR_BIT_EXT: 86e5c31af7Sopenharmony_ci flag_message = "[ERROR]"; 87e5c31af7Sopenharmony_ci break; 88e5c31af7Sopenharmony_ci case VK_DEBUG_REPORT_WARNING_BIT_EXT: 89e5c31af7Sopenharmony_ci flag_message = "[WARNING]"; 90e5c31af7Sopenharmony_ci break; 91e5c31af7Sopenharmony_ci default: 92e5c31af7Sopenharmony_ci flag_message = "[UNKNOWN]"; 93e5c31af7Sopenharmony_ci break; 94e5c31af7Sopenharmony_ci } 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci LogError(flag_message + " validation layer (" + layerPrefix + "):\n" + msg); 97e5c31af7Sopenharmony_ci return VK_FALSE; 98e5c31af7Sopenharmony_ci} 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci// Convert required features given as a string array to 101e5c31af7Sopenharmony_ci// VkPhysicalDeviceFeatures. 102e5c31af7Sopenharmony_ciamber::Result NamesToVulkanFeatures( 103e5c31af7Sopenharmony_ci const std::vector<std::string>& required_feature_names, 104e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures* features) { 105e5c31af7Sopenharmony_ci for (const auto& name : required_feature_names) { 106e5c31af7Sopenharmony_ci if (name == "robustBufferAccess") { 107e5c31af7Sopenharmony_ci features->robustBufferAccess = VK_TRUE; 108e5c31af7Sopenharmony_ci } else if (name == "fullDrawIndexUint32") { 109e5c31af7Sopenharmony_ci features->fullDrawIndexUint32 = VK_TRUE; 110e5c31af7Sopenharmony_ci } else if (name == "imageCubeArray") { 111e5c31af7Sopenharmony_ci features->imageCubeArray = VK_TRUE; 112e5c31af7Sopenharmony_ci } else if (name == "independentBlend") { 113e5c31af7Sopenharmony_ci features->independentBlend = VK_TRUE; 114e5c31af7Sopenharmony_ci } else if (name == "geometryShader") { 115e5c31af7Sopenharmony_ci features->geometryShader = VK_TRUE; 116e5c31af7Sopenharmony_ci } else if (name == "tessellationShader") { 117e5c31af7Sopenharmony_ci features->tessellationShader = VK_TRUE; 118e5c31af7Sopenharmony_ci } else if (name == "sampleRateShading") { 119e5c31af7Sopenharmony_ci features->sampleRateShading = VK_TRUE; 120e5c31af7Sopenharmony_ci } else if (name == "dualSrcBlend") { 121e5c31af7Sopenharmony_ci features->dualSrcBlend = VK_TRUE; 122e5c31af7Sopenharmony_ci } else if (name == "logicOp") { 123e5c31af7Sopenharmony_ci features->logicOp = VK_TRUE; 124e5c31af7Sopenharmony_ci } else if (name == "multiDrawIndirect") { 125e5c31af7Sopenharmony_ci features->multiDrawIndirect = VK_TRUE; 126e5c31af7Sopenharmony_ci } else if (name == "drawIndirectFirstInstance") { 127e5c31af7Sopenharmony_ci features->drawIndirectFirstInstance = VK_TRUE; 128e5c31af7Sopenharmony_ci } else if (name == "depthClamp") { 129e5c31af7Sopenharmony_ci features->depthClamp = VK_TRUE; 130e5c31af7Sopenharmony_ci } else if (name == "depthBiasClamp") { 131e5c31af7Sopenharmony_ci features->depthBiasClamp = VK_TRUE; 132e5c31af7Sopenharmony_ci } else if (name == "fillModeNonSolid") { 133e5c31af7Sopenharmony_ci features->fillModeNonSolid = VK_TRUE; 134e5c31af7Sopenharmony_ci } else if (name == "depthBounds") { 135e5c31af7Sopenharmony_ci features->depthBounds = VK_TRUE; 136e5c31af7Sopenharmony_ci } else if (name == "wideLines") { 137e5c31af7Sopenharmony_ci features->wideLines = VK_TRUE; 138e5c31af7Sopenharmony_ci } else if (name == "largePoints") { 139e5c31af7Sopenharmony_ci features->largePoints = VK_TRUE; 140e5c31af7Sopenharmony_ci } else if (name == "alphaToOne") { 141e5c31af7Sopenharmony_ci features->alphaToOne = VK_TRUE; 142e5c31af7Sopenharmony_ci } else if (name == "multiViewport") { 143e5c31af7Sopenharmony_ci features->multiViewport = VK_TRUE; 144e5c31af7Sopenharmony_ci } else if (name == "samplerAnisotropy") { 145e5c31af7Sopenharmony_ci features->samplerAnisotropy = VK_TRUE; 146e5c31af7Sopenharmony_ci } else if (name == "textureCompressionETC2") { 147e5c31af7Sopenharmony_ci features->textureCompressionETC2 = VK_TRUE; 148e5c31af7Sopenharmony_ci } else if (name == "textureCompressionASTC_LDR") { 149e5c31af7Sopenharmony_ci features->textureCompressionASTC_LDR = VK_TRUE; 150e5c31af7Sopenharmony_ci } else if (name == "textureCompressionBC") { 151e5c31af7Sopenharmony_ci features->textureCompressionBC = VK_TRUE; 152e5c31af7Sopenharmony_ci } else if (name == "occlusionQueryPrecise") { 153e5c31af7Sopenharmony_ci features->occlusionQueryPrecise = VK_TRUE; 154e5c31af7Sopenharmony_ci } else if (name == "pipelineStatisticsQuery") { 155e5c31af7Sopenharmony_ci features->pipelineStatisticsQuery = VK_TRUE; 156e5c31af7Sopenharmony_ci } else if (name == "vertexPipelineStoresAndAtomics") { 157e5c31af7Sopenharmony_ci features->vertexPipelineStoresAndAtomics = VK_TRUE; 158e5c31af7Sopenharmony_ci } else if (name == "fragmentStoresAndAtomics") { 159e5c31af7Sopenharmony_ci features->fragmentStoresAndAtomics = VK_TRUE; 160e5c31af7Sopenharmony_ci } else if (name == "shaderTessellationAndGeometryPointSize") { 161e5c31af7Sopenharmony_ci features->shaderTessellationAndGeometryPointSize = VK_TRUE; 162e5c31af7Sopenharmony_ci } else if (name == "shaderImageGatherExtended") { 163e5c31af7Sopenharmony_ci features->shaderImageGatherExtended = VK_TRUE; 164e5c31af7Sopenharmony_ci } else if (name == "shaderStorageImageExtendedFormats") { 165e5c31af7Sopenharmony_ci features->shaderStorageImageExtendedFormats = VK_TRUE; 166e5c31af7Sopenharmony_ci } else if (name == "shaderStorageImageMultisample") { 167e5c31af7Sopenharmony_ci features->shaderStorageImageMultisample = VK_TRUE; 168e5c31af7Sopenharmony_ci } else if (name == "shaderStorageImageReadWithoutFormat") { 169e5c31af7Sopenharmony_ci features->shaderStorageImageReadWithoutFormat = VK_TRUE; 170e5c31af7Sopenharmony_ci } else if (name == "shaderStorageImageWriteWithoutFormat") { 171e5c31af7Sopenharmony_ci features->shaderStorageImageWriteWithoutFormat = VK_TRUE; 172e5c31af7Sopenharmony_ci } else if (name == "shaderUniformBufferArrayDynamicIndexing") { 173e5c31af7Sopenharmony_ci features->shaderUniformBufferArrayDynamicIndexing = VK_TRUE; 174e5c31af7Sopenharmony_ci } else if (name == "shaderSampledImageArrayDynamicIndexing") { 175e5c31af7Sopenharmony_ci features->shaderSampledImageArrayDynamicIndexing = VK_TRUE; 176e5c31af7Sopenharmony_ci } else if (name == "shaderStorageBufferArrayDynamicIndexing") { 177e5c31af7Sopenharmony_ci features->shaderStorageBufferArrayDynamicIndexing = VK_TRUE; 178e5c31af7Sopenharmony_ci } else if (name == "shaderStorageImageArrayDynamicIndexing") { 179e5c31af7Sopenharmony_ci features->shaderStorageImageArrayDynamicIndexing = VK_TRUE; 180e5c31af7Sopenharmony_ci } else if (name == "shaderClipDistance") { 181e5c31af7Sopenharmony_ci features->shaderClipDistance = VK_TRUE; 182e5c31af7Sopenharmony_ci } else if (name == "shaderCullDistance") { 183e5c31af7Sopenharmony_ci features->shaderCullDistance = VK_TRUE; 184e5c31af7Sopenharmony_ci } else if (name == "shaderFloat64") { 185e5c31af7Sopenharmony_ci features->shaderFloat64 = VK_TRUE; 186e5c31af7Sopenharmony_ci } else if (name == "shaderInt64") { 187e5c31af7Sopenharmony_ci features->shaderInt64 = VK_TRUE; 188e5c31af7Sopenharmony_ci } else if (name == "shaderInt16") { 189e5c31af7Sopenharmony_ci features->shaderInt16 = VK_TRUE; 190e5c31af7Sopenharmony_ci } else if (name == "shaderResourceResidency") { 191e5c31af7Sopenharmony_ci features->shaderResourceResidency = VK_TRUE; 192e5c31af7Sopenharmony_ci } else if (name == "shaderResourceMinLod") { 193e5c31af7Sopenharmony_ci features->shaderResourceMinLod = VK_TRUE; 194e5c31af7Sopenharmony_ci } else if (name == "sparseBinding") { 195e5c31af7Sopenharmony_ci features->sparseBinding = VK_TRUE; 196e5c31af7Sopenharmony_ci } else if (name == "sparseResidencyBuffer") { 197e5c31af7Sopenharmony_ci features->sparseResidencyBuffer = VK_TRUE; 198e5c31af7Sopenharmony_ci } else if (name == "sparseResidencyImage2D") { 199e5c31af7Sopenharmony_ci features->sparseResidencyImage2D = VK_TRUE; 200e5c31af7Sopenharmony_ci } else if (name == "sparseResidencyImage3D") { 201e5c31af7Sopenharmony_ci features->sparseResidencyImage3D = VK_TRUE; 202e5c31af7Sopenharmony_ci } else if (name == "sparseResidency2Samples") { 203e5c31af7Sopenharmony_ci features->sparseResidency2Samples = VK_TRUE; 204e5c31af7Sopenharmony_ci } else if (name == "sparseResidency4Samples") { 205e5c31af7Sopenharmony_ci features->sparseResidency4Samples = VK_TRUE; 206e5c31af7Sopenharmony_ci } else if (name == "sparseResidency8Samples") { 207e5c31af7Sopenharmony_ci features->sparseResidency8Samples = VK_TRUE; 208e5c31af7Sopenharmony_ci } else if (name == "sparseResidency16Samples") { 209e5c31af7Sopenharmony_ci features->sparseResidency16Samples = VK_TRUE; 210e5c31af7Sopenharmony_ci } else if (name == "sparseResidencyAliased") { 211e5c31af7Sopenharmony_ci features->sparseResidencyAliased = VK_TRUE; 212e5c31af7Sopenharmony_ci } else if (name == "variableMultisampleRate") { 213e5c31af7Sopenharmony_ci features->variableMultisampleRate = VK_TRUE; 214e5c31af7Sopenharmony_ci } else if (name == "inheritedQueries") { 215e5c31af7Sopenharmony_ci features->inheritedQueries = VK_TRUE; 216e5c31af7Sopenharmony_ci } else { 217e5c31af7Sopenharmony_ci return amber::Result("Sample: Unknown Vulkan feature: " + name); 218e5c31af7Sopenharmony_ci } 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci return {}; 221e5c31af7Sopenharmony_ci} 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_cibool AreAllValidationLayersSupported() { 224e5c31af7Sopenharmony_ci std::vector<VkLayerProperties> available_layer_properties; 225e5c31af7Sopenharmony_ci uint32_t available_layer_count = 0; 226e5c31af7Sopenharmony_ci if (vkEnumerateInstanceLayerProperties(&available_layer_count, nullptr) != 227e5c31af7Sopenharmony_ci VK_SUCCESS) { 228e5c31af7Sopenharmony_ci return false; 229e5c31af7Sopenharmony_ci } 230e5c31af7Sopenharmony_ci available_layer_properties.resize(available_layer_count); 231e5c31af7Sopenharmony_ci if (vkEnumerateInstanceLayerProperties(&available_layer_count, 232e5c31af7Sopenharmony_ci available_layer_properties.data()) != 233e5c31af7Sopenharmony_ci VK_SUCCESS) { 234e5c31af7Sopenharmony_ci return false; 235e5c31af7Sopenharmony_ci } 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci std::set<std::string> required_layer_set( 238e5c31af7Sopenharmony_ci kRequiredValidationLayers, 239e5c31af7Sopenharmony_ci &kRequiredValidationLayers[kNumberOfRequiredValidationLayers]); 240e5c31af7Sopenharmony_ci for (const auto& property : available_layer_properties) { 241e5c31af7Sopenharmony_ci required_layer_set.erase(property.layerName); 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci if (required_layer_set.empty()) 245e5c31af7Sopenharmony_ci return true; 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci std::string missing_layers; 248e5c31af7Sopenharmony_ci for (const auto& missing_layer : required_layer_set) 249e5c31af7Sopenharmony_ci missing_layers = missing_layers + missing_layer + ",\n\t\t"; 250e5c31af7Sopenharmony_ci LogError("Vulkan: missing validation layers:\n\t\t" + missing_layers); 251e5c31af7Sopenharmony_ci return true; 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_cibool AreAllValidationExtensionsSupported() { 255e5c31af7Sopenharmony_ci for (const auto& layer : kRequiredValidationLayers) { 256e5c31af7Sopenharmony_ci uint32_t available_extension_count = 0; 257e5c31af7Sopenharmony_ci std::vector<VkExtensionProperties> extension_properties; 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci if (vkEnumerateInstanceExtensionProperties( 260e5c31af7Sopenharmony_ci layer, &available_extension_count, nullptr) != VK_SUCCESS) { 261e5c31af7Sopenharmony_ci return false; 262e5c31af7Sopenharmony_ci } 263e5c31af7Sopenharmony_ci extension_properties.resize(available_extension_count); 264e5c31af7Sopenharmony_ci if (vkEnumerateInstanceExtensionProperties( 265e5c31af7Sopenharmony_ci layer, &available_extension_count, extension_properties.data()) != 266e5c31af7Sopenharmony_ci VK_SUCCESS) { 267e5c31af7Sopenharmony_ci return false; 268e5c31af7Sopenharmony_ci } 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci for (const auto& ext : extension_properties) { 271e5c31af7Sopenharmony_ci if (!strcmp(kExtensionForValidationLayer, ext.extensionName)) 272e5c31af7Sopenharmony_ci return true; 273e5c31af7Sopenharmony_ci } 274e5c31af7Sopenharmony_ci } 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci return false; 277e5c31af7Sopenharmony_ci} 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_ci// Check if |physical_device| supports all required features given 280e5c31af7Sopenharmony_ci// in |required_features|. 281e5c31af7Sopenharmony_cibool AreAllRequiredFeaturesSupported( 282e5c31af7Sopenharmony_ci const VkPhysicalDeviceFeatures& available_features, 283e5c31af7Sopenharmony_ci const VkPhysicalDeviceFeatures& required_features) { 284e5c31af7Sopenharmony_ci if (available_features.robustBufferAccess == VK_FALSE && 285e5c31af7Sopenharmony_ci required_features.robustBufferAccess == VK_TRUE) { 286e5c31af7Sopenharmony_ci return false; 287e5c31af7Sopenharmony_ci } 288e5c31af7Sopenharmony_ci if (available_features.fullDrawIndexUint32 == VK_FALSE && 289e5c31af7Sopenharmony_ci required_features.fullDrawIndexUint32 == VK_TRUE) { 290e5c31af7Sopenharmony_ci return false; 291e5c31af7Sopenharmony_ci } 292e5c31af7Sopenharmony_ci if (available_features.imageCubeArray == VK_FALSE && 293e5c31af7Sopenharmony_ci required_features.imageCubeArray == VK_TRUE) { 294e5c31af7Sopenharmony_ci return false; 295e5c31af7Sopenharmony_ci } 296e5c31af7Sopenharmony_ci if (available_features.independentBlend == VK_FALSE && 297e5c31af7Sopenharmony_ci required_features.independentBlend == VK_TRUE) { 298e5c31af7Sopenharmony_ci return false; 299e5c31af7Sopenharmony_ci } 300e5c31af7Sopenharmony_ci if (available_features.geometryShader == VK_FALSE && 301e5c31af7Sopenharmony_ci required_features.geometryShader == VK_TRUE) { 302e5c31af7Sopenharmony_ci return false; 303e5c31af7Sopenharmony_ci } 304e5c31af7Sopenharmony_ci if (available_features.tessellationShader == VK_FALSE && 305e5c31af7Sopenharmony_ci required_features.tessellationShader == VK_TRUE) { 306e5c31af7Sopenharmony_ci return false; 307e5c31af7Sopenharmony_ci } 308e5c31af7Sopenharmony_ci if (available_features.sampleRateShading == VK_FALSE && 309e5c31af7Sopenharmony_ci required_features.sampleRateShading == VK_TRUE) { 310e5c31af7Sopenharmony_ci return false; 311e5c31af7Sopenharmony_ci } 312e5c31af7Sopenharmony_ci if (available_features.dualSrcBlend == VK_FALSE && 313e5c31af7Sopenharmony_ci required_features.dualSrcBlend == VK_TRUE) { 314e5c31af7Sopenharmony_ci return false; 315e5c31af7Sopenharmony_ci } 316e5c31af7Sopenharmony_ci if (available_features.logicOp == VK_FALSE && 317e5c31af7Sopenharmony_ci required_features.logicOp == VK_TRUE) { 318e5c31af7Sopenharmony_ci return false; 319e5c31af7Sopenharmony_ci } 320e5c31af7Sopenharmony_ci if (available_features.multiDrawIndirect == VK_FALSE && 321e5c31af7Sopenharmony_ci required_features.multiDrawIndirect == VK_TRUE) { 322e5c31af7Sopenharmony_ci return false; 323e5c31af7Sopenharmony_ci } 324e5c31af7Sopenharmony_ci if (available_features.drawIndirectFirstInstance == VK_FALSE && 325e5c31af7Sopenharmony_ci required_features.drawIndirectFirstInstance == VK_TRUE) { 326e5c31af7Sopenharmony_ci return false; 327e5c31af7Sopenharmony_ci } 328e5c31af7Sopenharmony_ci if (available_features.depthClamp == VK_FALSE && 329e5c31af7Sopenharmony_ci required_features.depthClamp == VK_TRUE) { 330e5c31af7Sopenharmony_ci return false; 331e5c31af7Sopenharmony_ci } 332e5c31af7Sopenharmony_ci if (available_features.depthBiasClamp == VK_FALSE && 333e5c31af7Sopenharmony_ci required_features.depthBiasClamp == VK_TRUE) { 334e5c31af7Sopenharmony_ci return false; 335e5c31af7Sopenharmony_ci } 336e5c31af7Sopenharmony_ci if (available_features.fillModeNonSolid == VK_FALSE && 337e5c31af7Sopenharmony_ci required_features.fillModeNonSolid == VK_TRUE) { 338e5c31af7Sopenharmony_ci return false; 339e5c31af7Sopenharmony_ci } 340e5c31af7Sopenharmony_ci if (available_features.depthBounds == VK_FALSE && 341e5c31af7Sopenharmony_ci required_features.depthBounds == VK_TRUE) { 342e5c31af7Sopenharmony_ci return false; 343e5c31af7Sopenharmony_ci } 344e5c31af7Sopenharmony_ci if (available_features.wideLines == VK_FALSE && 345e5c31af7Sopenharmony_ci required_features.wideLines == VK_TRUE) { 346e5c31af7Sopenharmony_ci return false; 347e5c31af7Sopenharmony_ci } 348e5c31af7Sopenharmony_ci if (available_features.largePoints == VK_FALSE && 349e5c31af7Sopenharmony_ci required_features.largePoints == VK_TRUE) { 350e5c31af7Sopenharmony_ci return false; 351e5c31af7Sopenharmony_ci } 352e5c31af7Sopenharmony_ci if (available_features.alphaToOne == VK_FALSE && 353e5c31af7Sopenharmony_ci required_features.alphaToOne == VK_TRUE) { 354e5c31af7Sopenharmony_ci return false; 355e5c31af7Sopenharmony_ci } 356e5c31af7Sopenharmony_ci if (available_features.multiViewport == VK_FALSE && 357e5c31af7Sopenharmony_ci required_features.multiViewport == VK_TRUE) { 358e5c31af7Sopenharmony_ci return false; 359e5c31af7Sopenharmony_ci } 360e5c31af7Sopenharmony_ci if (available_features.samplerAnisotropy == VK_FALSE && 361e5c31af7Sopenharmony_ci required_features.samplerAnisotropy == VK_TRUE) { 362e5c31af7Sopenharmony_ci return false; 363e5c31af7Sopenharmony_ci } 364e5c31af7Sopenharmony_ci if (available_features.textureCompressionETC2 == VK_FALSE && 365e5c31af7Sopenharmony_ci required_features.textureCompressionETC2 == VK_TRUE) { 366e5c31af7Sopenharmony_ci return false; 367e5c31af7Sopenharmony_ci } 368e5c31af7Sopenharmony_ci if (available_features.textureCompressionASTC_LDR == VK_FALSE && 369e5c31af7Sopenharmony_ci required_features.textureCompressionASTC_LDR == VK_TRUE) { 370e5c31af7Sopenharmony_ci return false; 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci if (available_features.textureCompressionBC == VK_FALSE && 373e5c31af7Sopenharmony_ci required_features.textureCompressionBC == VK_TRUE) { 374e5c31af7Sopenharmony_ci return false; 375e5c31af7Sopenharmony_ci } 376e5c31af7Sopenharmony_ci if (available_features.occlusionQueryPrecise == VK_FALSE && 377e5c31af7Sopenharmony_ci required_features.occlusionQueryPrecise == VK_TRUE) { 378e5c31af7Sopenharmony_ci return false; 379e5c31af7Sopenharmony_ci } 380e5c31af7Sopenharmony_ci if (available_features.pipelineStatisticsQuery == VK_FALSE && 381e5c31af7Sopenharmony_ci required_features.pipelineStatisticsQuery == VK_TRUE) { 382e5c31af7Sopenharmony_ci return false; 383e5c31af7Sopenharmony_ci } 384e5c31af7Sopenharmony_ci if (available_features.vertexPipelineStoresAndAtomics == VK_FALSE && 385e5c31af7Sopenharmony_ci required_features.vertexPipelineStoresAndAtomics == VK_TRUE) { 386e5c31af7Sopenharmony_ci return false; 387e5c31af7Sopenharmony_ci } 388e5c31af7Sopenharmony_ci if (available_features.fragmentStoresAndAtomics == VK_FALSE && 389e5c31af7Sopenharmony_ci required_features.fragmentStoresAndAtomics == VK_TRUE) { 390e5c31af7Sopenharmony_ci return false; 391e5c31af7Sopenharmony_ci } 392e5c31af7Sopenharmony_ci if (available_features.shaderTessellationAndGeometryPointSize == VK_FALSE && 393e5c31af7Sopenharmony_ci required_features.shaderTessellationAndGeometryPointSize == VK_TRUE) { 394e5c31af7Sopenharmony_ci return false; 395e5c31af7Sopenharmony_ci } 396e5c31af7Sopenharmony_ci if (available_features.shaderImageGatherExtended == VK_FALSE && 397e5c31af7Sopenharmony_ci required_features.shaderImageGatherExtended == VK_TRUE) { 398e5c31af7Sopenharmony_ci return false; 399e5c31af7Sopenharmony_ci } 400e5c31af7Sopenharmony_ci if (available_features.shaderStorageImageExtendedFormats == VK_FALSE && 401e5c31af7Sopenharmony_ci required_features.shaderStorageImageExtendedFormats == VK_TRUE) { 402e5c31af7Sopenharmony_ci return false; 403e5c31af7Sopenharmony_ci } 404e5c31af7Sopenharmony_ci if (available_features.shaderStorageImageMultisample == VK_FALSE && 405e5c31af7Sopenharmony_ci required_features.shaderStorageImageMultisample == VK_TRUE) { 406e5c31af7Sopenharmony_ci return false; 407e5c31af7Sopenharmony_ci } 408e5c31af7Sopenharmony_ci if (available_features.shaderStorageImageReadWithoutFormat == VK_FALSE && 409e5c31af7Sopenharmony_ci required_features.shaderStorageImageReadWithoutFormat == VK_TRUE) { 410e5c31af7Sopenharmony_ci return false; 411e5c31af7Sopenharmony_ci } 412e5c31af7Sopenharmony_ci if (available_features.shaderStorageImageWriteWithoutFormat == VK_FALSE && 413e5c31af7Sopenharmony_ci required_features.shaderStorageImageWriteWithoutFormat == VK_TRUE) { 414e5c31af7Sopenharmony_ci return false; 415e5c31af7Sopenharmony_ci } 416e5c31af7Sopenharmony_ci if (available_features.shaderUniformBufferArrayDynamicIndexing == VK_FALSE && 417e5c31af7Sopenharmony_ci required_features.shaderUniformBufferArrayDynamicIndexing == VK_TRUE) { 418e5c31af7Sopenharmony_ci return false; 419e5c31af7Sopenharmony_ci } 420e5c31af7Sopenharmony_ci if (available_features.shaderSampledImageArrayDynamicIndexing == VK_FALSE && 421e5c31af7Sopenharmony_ci required_features.shaderSampledImageArrayDynamicIndexing == VK_TRUE) { 422e5c31af7Sopenharmony_ci return false; 423e5c31af7Sopenharmony_ci } 424e5c31af7Sopenharmony_ci if (available_features.shaderStorageBufferArrayDynamicIndexing == VK_FALSE && 425e5c31af7Sopenharmony_ci required_features.shaderStorageBufferArrayDynamicIndexing == VK_TRUE) { 426e5c31af7Sopenharmony_ci return false; 427e5c31af7Sopenharmony_ci } 428e5c31af7Sopenharmony_ci if (available_features.shaderStorageImageArrayDynamicIndexing == VK_FALSE && 429e5c31af7Sopenharmony_ci required_features.shaderStorageImageArrayDynamicIndexing == VK_TRUE) { 430e5c31af7Sopenharmony_ci return false; 431e5c31af7Sopenharmony_ci } 432e5c31af7Sopenharmony_ci if (available_features.shaderClipDistance == VK_FALSE && 433e5c31af7Sopenharmony_ci required_features.shaderClipDistance == VK_TRUE) { 434e5c31af7Sopenharmony_ci return false; 435e5c31af7Sopenharmony_ci } 436e5c31af7Sopenharmony_ci if (available_features.shaderCullDistance == VK_FALSE && 437e5c31af7Sopenharmony_ci required_features.shaderCullDistance == VK_TRUE) { 438e5c31af7Sopenharmony_ci return false; 439e5c31af7Sopenharmony_ci } 440e5c31af7Sopenharmony_ci if (available_features.shaderFloat64 == VK_FALSE && 441e5c31af7Sopenharmony_ci required_features.shaderFloat64 == VK_TRUE) { 442e5c31af7Sopenharmony_ci return false; 443e5c31af7Sopenharmony_ci } 444e5c31af7Sopenharmony_ci if (available_features.shaderInt64 == VK_FALSE && 445e5c31af7Sopenharmony_ci required_features.shaderInt64 == VK_TRUE) { 446e5c31af7Sopenharmony_ci return false; 447e5c31af7Sopenharmony_ci } 448e5c31af7Sopenharmony_ci if (available_features.shaderInt16 == VK_FALSE && 449e5c31af7Sopenharmony_ci required_features.shaderInt16 == VK_TRUE) { 450e5c31af7Sopenharmony_ci return false; 451e5c31af7Sopenharmony_ci } 452e5c31af7Sopenharmony_ci if (available_features.shaderResourceResidency == VK_FALSE && 453e5c31af7Sopenharmony_ci required_features.shaderResourceResidency == VK_TRUE) { 454e5c31af7Sopenharmony_ci return false; 455e5c31af7Sopenharmony_ci } 456e5c31af7Sopenharmony_ci if (available_features.shaderResourceMinLod == VK_FALSE && 457e5c31af7Sopenharmony_ci required_features.shaderResourceMinLod == VK_TRUE) { 458e5c31af7Sopenharmony_ci return false; 459e5c31af7Sopenharmony_ci } 460e5c31af7Sopenharmony_ci if (available_features.sparseBinding == VK_FALSE && 461e5c31af7Sopenharmony_ci required_features.sparseBinding == VK_TRUE) { 462e5c31af7Sopenharmony_ci return false; 463e5c31af7Sopenharmony_ci } 464e5c31af7Sopenharmony_ci if (available_features.sparseResidencyBuffer == VK_FALSE && 465e5c31af7Sopenharmony_ci required_features.sparseResidencyBuffer == VK_TRUE) { 466e5c31af7Sopenharmony_ci return false; 467e5c31af7Sopenharmony_ci } 468e5c31af7Sopenharmony_ci if (available_features.sparseResidencyImage2D == VK_FALSE && 469e5c31af7Sopenharmony_ci required_features.sparseResidencyImage2D == VK_TRUE) { 470e5c31af7Sopenharmony_ci return false; 471e5c31af7Sopenharmony_ci } 472e5c31af7Sopenharmony_ci if (available_features.sparseResidencyImage3D == VK_FALSE && 473e5c31af7Sopenharmony_ci required_features.sparseResidencyImage3D == VK_TRUE) { 474e5c31af7Sopenharmony_ci return false; 475e5c31af7Sopenharmony_ci } 476e5c31af7Sopenharmony_ci if (available_features.sparseResidency2Samples == VK_FALSE && 477e5c31af7Sopenharmony_ci required_features.sparseResidency2Samples == VK_TRUE) { 478e5c31af7Sopenharmony_ci return false; 479e5c31af7Sopenharmony_ci } 480e5c31af7Sopenharmony_ci if (available_features.sparseResidency4Samples == VK_FALSE && 481e5c31af7Sopenharmony_ci required_features.sparseResidency4Samples == VK_TRUE) { 482e5c31af7Sopenharmony_ci return false; 483e5c31af7Sopenharmony_ci } 484e5c31af7Sopenharmony_ci if (available_features.sparseResidency8Samples == VK_FALSE && 485e5c31af7Sopenharmony_ci required_features.sparseResidency8Samples == VK_TRUE) { 486e5c31af7Sopenharmony_ci return false; 487e5c31af7Sopenharmony_ci } 488e5c31af7Sopenharmony_ci if (available_features.sparseResidency16Samples == VK_FALSE && 489e5c31af7Sopenharmony_ci required_features.sparseResidency16Samples == VK_TRUE) { 490e5c31af7Sopenharmony_ci return false; 491e5c31af7Sopenharmony_ci } 492e5c31af7Sopenharmony_ci if (available_features.sparseResidencyAliased == VK_FALSE && 493e5c31af7Sopenharmony_ci required_features.sparseResidencyAliased == VK_TRUE) { 494e5c31af7Sopenharmony_ci return false; 495e5c31af7Sopenharmony_ci } 496e5c31af7Sopenharmony_ci if (available_features.variableMultisampleRate == VK_FALSE && 497e5c31af7Sopenharmony_ci required_features.variableMultisampleRate == VK_TRUE) { 498e5c31af7Sopenharmony_ci return false; 499e5c31af7Sopenharmony_ci } 500e5c31af7Sopenharmony_ci if (available_features.inheritedQueries == VK_FALSE && 501e5c31af7Sopenharmony_ci required_features.inheritedQueries == VK_TRUE) { 502e5c31af7Sopenharmony_ci return false; 503e5c31af7Sopenharmony_ci } 504e5c31af7Sopenharmony_ci return true; 505e5c31af7Sopenharmony_ci} 506e5c31af7Sopenharmony_ci 507e5c31af7Sopenharmony_ci// Get all available instance extensions. 508e5c31af7Sopenharmony_cistd::vector<std::string> GetAvailableInstanceExtensions() { 509e5c31af7Sopenharmony_ci std::vector<std::string> available_extensions; 510e5c31af7Sopenharmony_ci uint32_t available_extension_count = 0; 511e5c31af7Sopenharmony_ci std::vector<VkExtensionProperties> available_extension_properties; 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci if (vkEnumerateInstanceExtensionProperties( 514e5c31af7Sopenharmony_ci nullptr, &available_extension_count, nullptr) != VK_SUCCESS) { 515e5c31af7Sopenharmony_ci return available_extensions; 516e5c31af7Sopenharmony_ci } 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci if (available_extension_count == 0) 519e5c31af7Sopenharmony_ci return available_extensions; 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ci available_extension_properties.resize(available_extension_count); 522e5c31af7Sopenharmony_ci if (vkEnumerateInstanceExtensionProperties( 523e5c31af7Sopenharmony_ci nullptr, &available_extension_count, 524e5c31af7Sopenharmony_ci available_extension_properties.data()) != VK_SUCCESS) { 525e5c31af7Sopenharmony_ci return available_extensions; 526e5c31af7Sopenharmony_ci } 527e5c31af7Sopenharmony_ci 528e5c31af7Sopenharmony_ci for (const auto& property : available_extension_properties) 529e5c31af7Sopenharmony_ci available_extensions.push_back(property.extensionName); 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci return available_extensions; 532e5c31af7Sopenharmony_ci} 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci// Get all available extensions of |physical_device|. 535e5c31af7Sopenharmony_cistd::vector<std::string> GetAvailableDeviceExtensions( 536e5c31af7Sopenharmony_ci const VkPhysicalDevice& physical_device) { 537e5c31af7Sopenharmony_ci std::vector<std::string> available_extensions; 538e5c31af7Sopenharmony_ci uint32_t available_extension_count = 0; 539e5c31af7Sopenharmony_ci std::vector<VkExtensionProperties> available_extension_properties; 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci if (vkEnumerateDeviceExtensionProperties(physical_device, nullptr, 542e5c31af7Sopenharmony_ci &available_extension_count, 543e5c31af7Sopenharmony_ci nullptr) != VK_SUCCESS) { 544e5c31af7Sopenharmony_ci return available_extensions; 545e5c31af7Sopenharmony_ci } 546e5c31af7Sopenharmony_ci 547e5c31af7Sopenharmony_ci if (available_extension_count == 0) 548e5c31af7Sopenharmony_ci return available_extensions; 549e5c31af7Sopenharmony_ci 550e5c31af7Sopenharmony_ci available_extension_properties.resize(available_extension_count); 551e5c31af7Sopenharmony_ci if (vkEnumerateDeviceExtensionProperties( 552e5c31af7Sopenharmony_ci physical_device, nullptr, &available_extension_count, 553e5c31af7Sopenharmony_ci available_extension_properties.data()) != VK_SUCCESS) { 554e5c31af7Sopenharmony_ci return available_extensions; 555e5c31af7Sopenharmony_ci } 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci for (const auto& property : available_extension_properties) 558e5c31af7Sopenharmony_ci available_extensions.push_back(property.extensionName); 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci return available_extensions; 561e5c31af7Sopenharmony_ci} 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci// Check if |physical_device| supports all required extensions given 564e5c31af7Sopenharmony_ci// in |required_extensions|. 565e5c31af7Sopenharmony_cibool AreAllExtensionsSupported( 566e5c31af7Sopenharmony_ci const std::vector<std::string>& available_extensions, 567e5c31af7Sopenharmony_ci const std::vector<std::string>& required_extensions) { 568e5c31af7Sopenharmony_ci if (required_extensions.empty()) 569e5c31af7Sopenharmony_ci return true; 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci std::set<std::string> required_extension_set(required_extensions.begin(), 572e5c31af7Sopenharmony_ci required_extensions.end()); 573e5c31af7Sopenharmony_ci for (const auto& extension : available_extensions) { 574e5c31af7Sopenharmony_ci required_extension_set.erase(extension); 575e5c31af7Sopenharmony_ci } 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci return required_extension_set.empty(); 578e5c31af7Sopenharmony_ci} 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci// Check if |physical_device| supports both compute and graphics 581e5c31af7Sopenharmony_ci// pipelines. 582e5c31af7Sopenharmony_ciuint32_t ChooseQueueFamilyIndex(const VkPhysicalDevice& physical_device) { 583e5c31af7Sopenharmony_ci uint32_t count = 0; 584e5c31af7Sopenharmony_ci std::vector<VkQueueFamilyProperties> properties; 585e5c31af7Sopenharmony_ci 586e5c31af7Sopenharmony_ci vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, nullptr); 587e5c31af7Sopenharmony_ci properties.resize(count); 588e5c31af7Sopenharmony_ci vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, 589e5c31af7Sopenharmony_ci properties.data()); 590e5c31af7Sopenharmony_ci 591e5c31af7Sopenharmony_ci for (uint32_t i = 0; i < count; ++i) { 592e5c31af7Sopenharmony_ci if (properties[i].queueFlags & 593e5c31af7Sopenharmony_ci (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)) { 594e5c31af7Sopenharmony_ci return i; 595e5c31af7Sopenharmony_ci } 596e5c31af7Sopenharmony_ci } 597e5c31af7Sopenharmony_ci 598e5c31af7Sopenharmony_ci return std::numeric_limits<uint32_t>::max(); 599e5c31af7Sopenharmony_ci} 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_cistd::string deviceTypeToName(VkPhysicalDeviceType type) { 602e5c31af7Sopenharmony_ci switch (type) { 603e5c31af7Sopenharmony_ci case VK_PHYSICAL_DEVICE_TYPE_OTHER: 604e5c31af7Sopenharmony_ci return "other"; 605e5c31af7Sopenharmony_ci case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: 606e5c31af7Sopenharmony_ci return "integrated gpu"; 607e5c31af7Sopenharmony_ci case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: 608e5c31af7Sopenharmony_ci return "discrete gpu"; 609e5c31af7Sopenharmony_ci case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: 610e5c31af7Sopenharmony_ci return "virtual gpu"; 611e5c31af7Sopenharmony_ci case VK_PHYSICAL_DEVICE_TYPE_CPU: 612e5c31af7Sopenharmony_ci return "cpu"; 613e5c31af7Sopenharmony_ci default: 614e5c31af7Sopenharmony_ci break; 615e5c31af7Sopenharmony_ci } 616e5c31af7Sopenharmony_ci return "unknown"; 617e5c31af7Sopenharmony_ci} 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_cistd::string stageFlagBitsToNames(const VkShaderStageFlags bits) { 620e5c31af7Sopenharmony_ci static const std::pair<VkShaderStageFlagBits, const char*> stages[] = { 621e5c31af7Sopenharmony_ci std::make_pair(VK_SHADER_STAGE_VERTEX_BIT, "vert"), 622e5c31af7Sopenharmony_ci std::make_pair(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tessc"), 623e5c31af7Sopenharmony_ci std::make_pair(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tesse"), 624e5c31af7Sopenharmony_ci std::make_pair(VK_SHADER_STAGE_GEOMETRY_BIT, "geom"), 625e5c31af7Sopenharmony_ci std::make_pair(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"), 626e5c31af7Sopenharmony_ci std::make_pair(VK_SHADER_STAGE_COMPUTE_BIT, "comp")}; 627e5c31af7Sopenharmony_ci std::ostringstream result; 628e5c31af7Sopenharmony_ci bool addSeparator = false; 629e5c31af7Sopenharmony_ci for (const auto& stage : stages) { 630e5c31af7Sopenharmony_ci if ((bits & stage.first) != 0) { 631e5c31af7Sopenharmony_ci if (addSeparator) 632e5c31af7Sopenharmony_ci result << ", "; 633e5c31af7Sopenharmony_ci result << stage.second; 634e5c31af7Sopenharmony_ci addSeparator = true; 635e5c31af7Sopenharmony_ci } 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci return result.str(); 638e5c31af7Sopenharmony_ci} 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci} // namespace 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ciConfigHelperVulkan::ConfigHelperVulkan() 643e5c31af7Sopenharmony_ci : available_features_(VkPhysicalDeviceFeatures()), 644e5c31af7Sopenharmony_ci available_features2_(VkPhysicalDeviceFeatures2KHR()), 645e5c31af7Sopenharmony_ci variable_pointers_feature_(VkPhysicalDeviceVariablePointerFeaturesKHR()), 646e5c31af7Sopenharmony_ci float16_int8_feature_(VkPhysicalDeviceFloat16Int8FeaturesKHR()), 647e5c31af7Sopenharmony_ci storage_8bit_feature_(VkPhysicalDevice8BitStorageFeaturesKHR()), 648e5c31af7Sopenharmony_ci storage_16bit_feature_(VkPhysicalDevice16BitStorageFeaturesKHR()), 649e5c31af7Sopenharmony_ci subgroup_size_control_feature_( 650e5c31af7Sopenharmony_ci VkPhysicalDeviceSubgroupSizeControlFeaturesEXT()) {} 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ciConfigHelperVulkan::~ConfigHelperVulkan() { 653e5c31af7Sopenharmony_ci if (vulkan_device_) 654e5c31af7Sopenharmony_ci vkDestroyDevice(vulkan_device_, nullptr); 655e5c31af7Sopenharmony_ci 656e5c31af7Sopenharmony_ci if (vulkan_callback_) { 657e5c31af7Sopenharmony_ci auto vkDestroyDebugReportCallbackEXT = 658e5c31af7Sopenharmony_ci reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>( 659e5c31af7Sopenharmony_ci vkGetInstanceProcAddr(vulkan_instance_, 660e5c31af7Sopenharmony_ci "vkDestroyDebugReportCallbackEXT")); 661e5c31af7Sopenharmony_ci if (vkDestroyDebugReportCallbackEXT) { 662e5c31af7Sopenharmony_ci vkDestroyDebugReportCallbackEXT(vulkan_instance_, vulkan_callback_, 663e5c31af7Sopenharmony_ci nullptr); 664e5c31af7Sopenharmony_ci } 665e5c31af7Sopenharmony_ci } 666e5c31af7Sopenharmony_ci 667e5c31af7Sopenharmony_ci if (vulkan_instance_) 668e5c31af7Sopenharmony_ci vkDestroyInstance(vulkan_instance_, nullptr); 669e5c31af7Sopenharmony_ci} 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CreateVulkanInstance( 672e5c31af7Sopenharmony_ci uint32_t engine_major, 673e5c31af7Sopenharmony_ci uint32_t engine_minor, 674e5c31af7Sopenharmony_ci std::vector<std::string> required_extensions, 675e5c31af7Sopenharmony_ci bool disable_validation_layer) { 676e5c31af7Sopenharmony_ci VkApplicationInfo app_info = VkApplicationInfo(); 677e5c31af7Sopenharmony_ci app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 678e5c31af7Sopenharmony_ci 679e5c31af7Sopenharmony_ci#pragma clang diagnostic push 680e5c31af7Sopenharmony_ci#pragma clang diagnostic ignored "-Wold-style-cast" 681e5c31af7Sopenharmony_ci app_info.apiVersion = VK_MAKE_VERSION(engine_major, engine_minor, 0); 682e5c31af7Sopenharmony_ci#pragma clang diagnostic pop 683e5c31af7Sopenharmony_ci 684e5c31af7Sopenharmony_ci VkInstanceCreateInfo instance_info = VkInstanceCreateInfo(); 685e5c31af7Sopenharmony_ci instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 686e5c31af7Sopenharmony_ci instance_info.pApplicationInfo = &app_info; 687e5c31af7Sopenharmony_ci 688e5c31af7Sopenharmony_ci if (!disable_validation_layer) { 689e5c31af7Sopenharmony_ci if (!AreAllValidationLayersSupported()) 690e5c31af7Sopenharmony_ci return amber::Result("Sample: not all validation layers are supported"); 691e5c31af7Sopenharmony_ci if (!AreAllValidationExtensionsSupported()) { 692e5c31af7Sopenharmony_ci return amber::Result( 693e5c31af7Sopenharmony_ci "Sample: extensions of validation layers are not supported"); 694e5c31af7Sopenharmony_ci } 695e5c31af7Sopenharmony_ci instance_info.enabledLayerCount = kNumberOfRequiredValidationLayers; 696e5c31af7Sopenharmony_ci instance_info.ppEnabledLayerNames = kRequiredValidationLayers; 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci required_extensions.push_back(kExtensionForValidationLayer); 699e5c31af7Sopenharmony_ci } 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_ci available_instance_extensions_ = GetAvailableInstanceExtensions(); 702e5c31af7Sopenharmony_ci if (!required_extensions.empty()) { 703e5c31af7Sopenharmony_ci if (!AreAllExtensionsSupported(available_instance_extensions_, 704e5c31af7Sopenharmony_ci required_extensions)) { 705e5c31af7Sopenharmony_ci return amber::Result("Missing required instance extensions"); 706e5c31af7Sopenharmony_ci } 707e5c31af7Sopenharmony_ci } 708e5c31af7Sopenharmony_ci 709e5c31af7Sopenharmony_ci if (std::find(available_instance_extensions_.begin(), 710e5c31af7Sopenharmony_ci available_instance_extensions_.end(), 711e5c31af7Sopenharmony_ci "VK_KHR_get_physical_device_properties2") != 712e5c31af7Sopenharmony_ci available_instance_extensions_.end()) { 713e5c31af7Sopenharmony_ci required_extensions.push_back("VK_KHR_get_physical_device_properties2"); 714e5c31af7Sopenharmony_ci } 715e5c31af7Sopenharmony_ci 716e5c31af7Sopenharmony_ci // Determine if VkPhysicalDeviceProperties2KHR should be used 717e5c31af7Sopenharmony_ci for (auto& ext : required_extensions) { 718e5c31af7Sopenharmony_ci if (ext == "VK_KHR_get_physical_device_properties2") 719e5c31af7Sopenharmony_ci supports_get_physical_device_properties2_ = true; 720e5c31af7Sopenharmony_ci } 721e5c31af7Sopenharmony_ci 722e5c31af7Sopenharmony_ci std::vector<const char*> required_extensions_in_char; 723e5c31af7Sopenharmony_ci std::transform( 724e5c31af7Sopenharmony_ci required_extensions.begin(), required_extensions.end(), 725e5c31af7Sopenharmony_ci std::back_inserter(required_extensions_in_char), 726e5c31af7Sopenharmony_ci [](const std::string& ext) -> const char* { return ext.c_str(); }); 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci instance_info.enabledExtensionCount = 729e5c31af7Sopenharmony_ci static_cast<uint32_t>(required_extensions_in_char.size()); 730e5c31af7Sopenharmony_ci instance_info.ppEnabledExtensionNames = required_extensions_in_char.data(); 731e5c31af7Sopenharmony_ci 732e5c31af7Sopenharmony_ci if (vkCreateInstance(&instance_info, nullptr, &vulkan_instance_) != 733e5c31af7Sopenharmony_ci VK_SUCCESS) { 734e5c31af7Sopenharmony_ci return amber::Result("Unable to create vulkan instance"); 735e5c31af7Sopenharmony_ci } 736e5c31af7Sopenharmony_ci return {}; 737e5c31af7Sopenharmony_ci} 738e5c31af7Sopenharmony_ci 739e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CreateDebugReportCallback() { 740e5c31af7Sopenharmony_ci VkDebugReportCallbackCreateInfoEXT info = 741e5c31af7Sopenharmony_ci VkDebugReportCallbackCreateInfoEXT(); 742e5c31af7Sopenharmony_ci info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; 743e5c31af7Sopenharmony_ci info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; 744e5c31af7Sopenharmony_ci info.pfnCallback = debugCallback; 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_ci auto vkCreateDebugReportCallbackEXT = 747e5c31af7Sopenharmony_ci reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>( 748e5c31af7Sopenharmony_ci vkGetInstanceProcAddr(vulkan_instance_, 749e5c31af7Sopenharmony_ci "vkCreateDebugReportCallbackEXT")); 750e5c31af7Sopenharmony_ci if (!vkCreateDebugReportCallbackEXT) 751e5c31af7Sopenharmony_ci return amber::Result("Sample: vkCreateDebugReportCallbackEXT is nullptr"); 752e5c31af7Sopenharmony_ci 753e5c31af7Sopenharmony_ci if (vkCreateDebugReportCallbackEXT(vulkan_instance_, &info, nullptr, 754e5c31af7Sopenharmony_ci &vulkan_callback_) != VK_SUCCESS) { 755e5c31af7Sopenharmony_ci return amber::Result("Sample: vkCreateDebugReportCallbackEXT fail"); 756e5c31af7Sopenharmony_ci } 757e5c31af7Sopenharmony_ci return {}; 758e5c31af7Sopenharmony_ci} 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CheckVulkanPhysicalDeviceRequirements( 761e5c31af7Sopenharmony_ci const VkPhysicalDevice physical_device, 762e5c31af7Sopenharmony_ci const std::vector<std::string>& required_features, 763e5c31af7Sopenharmony_ci const std::vector<std::string>& required_extensions) { 764e5c31af7Sopenharmony_ci available_device_extensions_ = GetAvailableDeviceExtensions(physical_device); 765e5c31af7Sopenharmony_ci if (!AreAllExtensionsSupported(available_device_extensions_, 766e5c31af7Sopenharmony_ci required_extensions)) { 767e5c31af7Sopenharmony_ci return amber::Result("Device does not support all required extensions"); 768e5c31af7Sopenharmony_ci } 769e5c31af7Sopenharmony_ci for (const auto& ext : available_device_extensions_) { 770e5c31af7Sopenharmony_ci if (ext == "VK_KHR_shader_float16_int8") 771e5c31af7Sopenharmony_ci supports_shader_float16_int8_ = true; 772e5c31af7Sopenharmony_ci else if (ext == "VK_KHR_8bit_storage") 773e5c31af7Sopenharmony_ci supports_shader_8bit_storage_ = true; 774e5c31af7Sopenharmony_ci else if (ext == "VK_KHR_16bit_storage") 775e5c31af7Sopenharmony_ci supports_shader_16bit_storage_ = true; 776e5c31af7Sopenharmony_ci else if (ext == "VK_EXT_subgroup_size_control") 777e5c31af7Sopenharmony_ci supports_subgroup_size_control_ = true; 778e5c31af7Sopenharmony_ci else if (ext == "VK_KHR_shader_subgroup_extended_types") 779e5c31af7Sopenharmony_ci supports_shader_subgroup_extended_types_ = true; 780e5c31af7Sopenharmony_ci } 781e5c31af7Sopenharmony_ci 782e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures required_vulkan_features = 783e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures(); 784e5c31af7Sopenharmony_ci 785e5c31af7Sopenharmony_ci if (supports_get_physical_device_properties2_) { 786e5c31af7Sopenharmony_ci VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures 787e5c31af7Sopenharmony_ci shader_subgroup_extended_types_features = {}; 788e5c31af7Sopenharmony_ci VkPhysicalDeviceSubgroupSizeControlFeaturesEXT 789e5c31af7Sopenharmony_ci subgroup_size_control_features = {}; 790e5c31af7Sopenharmony_ci VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers_features = {}; 791e5c31af7Sopenharmony_ci VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features = {}; 792e5c31af7Sopenharmony_ci VkPhysicalDevice8BitStorageFeaturesKHR storage_8bit_features = {}; 793e5c31af7Sopenharmony_ci VkPhysicalDevice16BitStorageFeaturesKHR storage_16bit_features = {}; 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci subgroup_size_control_features.sType = 796e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT; 797e5c31af7Sopenharmony_ci subgroup_size_control_features.pNext = nullptr; 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_ci // Add subgroup size control struct into the chain only if 800e5c31af7Sopenharmony_ci // VK_EXT_subgroup_size_control is supported. 801e5c31af7Sopenharmony_ci variable_pointers_features.sType = 802e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR; 803e5c31af7Sopenharmony_ci variable_pointers_features.pNext = supports_subgroup_size_control_ 804e5c31af7Sopenharmony_ci ? &subgroup_size_control_features 805e5c31af7Sopenharmony_ci : nullptr; 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci shader_subgroup_extended_types_features.sType = 808e5c31af7Sopenharmony_ci // NOLINTNEXTLINE(whitespace/line_length) 809e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES; 810e5c31af7Sopenharmony_ci shader_subgroup_extended_types_features.pNext = &variable_pointers_features; 811e5c31af7Sopenharmony_ci 812e5c31af7Sopenharmony_ci float16_int8_features.sType = 813e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; 814e5c31af7Sopenharmony_ci float16_int8_features.pNext = &shader_subgroup_extended_types_features; 815e5c31af7Sopenharmony_ci 816e5c31af7Sopenharmony_ci storage_8bit_features.sType = 817e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR; 818e5c31af7Sopenharmony_ci storage_8bit_features.pNext = &float16_int8_features; 819e5c31af7Sopenharmony_ci 820e5c31af7Sopenharmony_ci storage_16bit_features.sType = 821e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR; 822e5c31af7Sopenharmony_ci storage_16bit_features.pNext = &storage_8bit_features; 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2KHR features2 = VkPhysicalDeviceFeatures2KHR(); 825e5c31af7Sopenharmony_ci features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 826e5c31af7Sopenharmony_ci features2.pNext = &storage_16bit_features; 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci auto vkGetPhysicalDeviceFeatures2KHR = 829e5c31af7Sopenharmony_ci reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>( 830e5c31af7Sopenharmony_ci vkGetInstanceProcAddr(vulkan_instance_, 831e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceFeatures2KHR")); 832e5c31af7Sopenharmony_ci vkGetPhysicalDeviceFeatures2KHR(physical_device, &features2); 833e5c31af7Sopenharmony_ci available_features_ = features2.features; 834e5c31af7Sopenharmony_ci 835e5c31af7Sopenharmony_ci std::vector<std::string> required_features1; 836e5c31af7Sopenharmony_ci for (const auto& feature : required_features) { 837e5c31af7Sopenharmony_ci // No dot means this is a features1 feature. 838e5c31af7Sopenharmony_ci if (feature.find_first_of('.') == std::string::npos) { 839e5c31af7Sopenharmony_ci required_features1.push_back(feature); 840e5c31af7Sopenharmony_ci continue; 841e5c31af7Sopenharmony_ci } 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_ci if ((feature == kVariablePointers && 844e5c31af7Sopenharmony_ci variable_pointers_features.variablePointers == VK_FALSE) || 845e5c31af7Sopenharmony_ci (feature == kVariablePointersStorageBuffer && 846e5c31af7Sopenharmony_ci variable_pointers_features.variablePointersStorageBuffer == 847e5c31af7Sopenharmony_ci VK_FALSE) || 848e5c31af7Sopenharmony_ci (feature == kSubgroupSizeControl && 849e5c31af7Sopenharmony_ci subgroup_size_control_features.subgroupSizeControl == VK_FALSE) || 850e5c31af7Sopenharmony_ci (feature == kComputeFullSubgroups && 851e5c31af7Sopenharmony_ci subgroup_size_control_features.computeFullSubgroups == VK_FALSE) || 852e5c31af7Sopenharmony_ci (feature == kFloat16Int8_Float16 && 853e5c31af7Sopenharmony_ci float16_int8_features.shaderFloat16 == VK_FALSE) || 854e5c31af7Sopenharmony_ci (feature == kFloat16Int8_Int8 && 855e5c31af7Sopenharmony_ci float16_int8_features.shaderInt8 == VK_FALSE) || 856e5c31af7Sopenharmony_ci (feature == k8BitStorage_Storage && 857e5c31af7Sopenharmony_ci storage_8bit_features.storageBuffer8BitAccess == VK_FALSE) || 858e5c31af7Sopenharmony_ci (feature == k8BitStorage_UniformAndStorage && 859e5c31af7Sopenharmony_ci storage_8bit_features.uniformAndStorageBuffer8BitAccess == 860e5c31af7Sopenharmony_ci VK_FALSE) || 861e5c31af7Sopenharmony_ci (feature == k8BitStorage_PushConstant && 862e5c31af7Sopenharmony_ci storage_8bit_features.storagePushConstant8 == VK_FALSE) || 863e5c31af7Sopenharmony_ci (feature == k16BitStorage_Storage && 864e5c31af7Sopenharmony_ci storage_16bit_features.storageBuffer16BitAccess == VK_FALSE) || 865e5c31af7Sopenharmony_ci (feature == k16BitStorage_InputOutput && 866e5c31af7Sopenharmony_ci storage_16bit_features.storageInputOutput16 == VK_FALSE) || 867e5c31af7Sopenharmony_ci (feature == k16BitStorage_PushConstant && 868e5c31af7Sopenharmony_ci storage_16bit_features.storagePushConstant16 == VK_FALSE) || 869e5c31af7Sopenharmony_ci (feature == k16BitStorage_UniformAndStorage && 870e5c31af7Sopenharmony_ci storage_16bit_features.uniformAndStorageBuffer16BitAccess == 871e5c31af7Sopenharmony_ci VK_FALSE) || 872e5c31af7Sopenharmony_ci (feature == kShaderSubgroupExtendedTypes && 873e5c31af7Sopenharmony_ci shader_subgroup_extended_types_features 874e5c31af7Sopenharmony_ci .shaderSubgroupExtendedTypes == VK_FALSE)) { 875e5c31af7Sopenharmony_ci return amber::Result("Device does not support all required features"); 876e5c31af7Sopenharmony_ci } 877e5c31af7Sopenharmony_ci } 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci amber::Result r = 880e5c31af7Sopenharmony_ci NamesToVulkanFeatures(required_features1, &required_vulkan_features); 881e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 882e5c31af7Sopenharmony_ci return r; 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_ci } else { 885e5c31af7Sopenharmony_ci amber::Result r = 886e5c31af7Sopenharmony_ci NamesToVulkanFeatures(required_features, &required_vulkan_features); 887e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 888e5c31af7Sopenharmony_ci return r; 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_ci vkGetPhysicalDeviceFeatures(physical_device, &available_features_); 891e5c31af7Sopenharmony_ci } 892e5c31af7Sopenharmony_ci if (!AreAllRequiredFeaturesSupported(available_features_, 893e5c31af7Sopenharmony_ci required_vulkan_features)) { 894e5c31af7Sopenharmony_ci return amber::Result("Device does not support all required features"); 895e5c31af7Sopenharmony_ci } 896e5c31af7Sopenharmony_ci 897e5c31af7Sopenharmony_ci vulkan_queue_family_index_ = ChooseQueueFamilyIndex(physical_device); 898e5c31af7Sopenharmony_ci if (vulkan_queue_family_index_ == std::numeric_limits<uint32_t>::max()) { 899e5c31af7Sopenharmony_ci return amber::Result("Device does not support required queue flags"); 900e5c31af7Sopenharmony_ci } 901e5c31af7Sopenharmony_ci 902e5c31af7Sopenharmony_ci return {}; 903e5c31af7Sopenharmony_ci} 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::ChooseVulkanPhysicalDevice( 906e5c31af7Sopenharmony_ci const std::vector<std::string>& required_features, 907e5c31af7Sopenharmony_ci const std::vector<std::string>& required_extensions, 908e5c31af7Sopenharmony_ci const int32_t selected_device) { 909e5c31af7Sopenharmony_ci uint32_t count = 0; 910e5c31af7Sopenharmony_ci std::vector<VkPhysicalDevice> physical_devices; 911e5c31af7Sopenharmony_ci 912e5c31af7Sopenharmony_ci if (vkEnumeratePhysicalDevices(vulkan_instance_, &count, nullptr) != 913e5c31af7Sopenharmony_ci VK_SUCCESS) { 914e5c31af7Sopenharmony_ci return amber::Result("Unable to enumerate physical devices"); 915e5c31af7Sopenharmony_ci } 916e5c31af7Sopenharmony_ci 917e5c31af7Sopenharmony_ci physical_devices.resize(count); 918e5c31af7Sopenharmony_ci if (vkEnumeratePhysicalDevices(vulkan_instance_, &count, 919e5c31af7Sopenharmony_ci physical_devices.data()) != VK_SUCCESS) { 920e5c31af7Sopenharmony_ci return amber::Result("Unable to enumerate physical devices"); 921e5c31af7Sopenharmony_ci } 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci if (selected_device > -1) { 924e5c31af7Sopenharmony_ci uint32_t deviceID = static_cast<uint32_t>(selected_device); 925e5c31af7Sopenharmony_ci if (deviceID >= count) { 926e5c31af7Sopenharmony_ci return amber::Result("Unable to find Vulkan device with ID " + 927e5c31af7Sopenharmony_ci std::to_string(deviceID)); 928e5c31af7Sopenharmony_ci } 929e5c31af7Sopenharmony_ci amber::Result r = CheckVulkanPhysicalDeviceRequirements( 930e5c31af7Sopenharmony_ci physical_devices[deviceID], required_features, required_extensions); 931e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 932e5c31af7Sopenharmony_ci return r; 933e5c31af7Sopenharmony_ci vulkan_physical_device_ = physical_devices[deviceID]; 934e5c31af7Sopenharmony_ci return {}; 935e5c31af7Sopenharmony_ci } else { 936e5c31af7Sopenharmony_ci for (uint32_t i = 0; i < count; ++i) { 937e5c31af7Sopenharmony_ci amber::Result r = CheckVulkanPhysicalDeviceRequirements( 938e5c31af7Sopenharmony_ci physical_devices[i], required_features, required_extensions); 939e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 940e5c31af7Sopenharmony_ci continue; 941e5c31af7Sopenharmony_ci vulkan_physical_device_ = physical_devices[i]; 942e5c31af7Sopenharmony_ci return {}; 943e5c31af7Sopenharmony_ci } 944e5c31af7Sopenharmony_ci } 945e5c31af7Sopenharmony_ci 946e5c31af7Sopenharmony_ci std::ostringstream out; 947e5c31af7Sopenharmony_ci out << "Unable to find Vulkan device supporting:" << std::endl; 948e5c31af7Sopenharmony_ci for (const auto& str : required_features) 949e5c31af7Sopenharmony_ci out << " " << str << std::endl; 950e5c31af7Sopenharmony_ci for (const auto& str : required_extensions) 951e5c31af7Sopenharmony_ci out << " " << str << std::endl; 952e5c31af7Sopenharmony_ci 953e5c31af7Sopenharmony_ci return amber::Result(out.str()); 954e5c31af7Sopenharmony_ci} 955e5c31af7Sopenharmony_ci 956e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CreateVulkanDevice( 957e5c31af7Sopenharmony_ci const std::vector<std::string>& required_features, 958e5c31af7Sopenharmony_ci const std::vector<std::string>& required_extensions) { 959e5c31af7Sopenharmony_ci VkDeviceQueueCreateInfo queue_info = VkDeviceQueueCreateInfo(); 960e5c31af7Sopenharmony_ci const float priorities[] = {1.0f}; 961e5c31af7Sopenharmony_ci 962e5c31af7Sopenharmony_ci queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 963e5c31af7Sopenharmony_ci queue_info.queueFamilyIndex = vulkan_queue_family_index_; 964e5c31af7Sopenharmony_ci queue_info.queueCount = 1; 965e5c31af7Sopenharmony_ci queue_info.pQueuePriorities = priorities; 966e5c31af7Sopenharmony_ci 967e5c31af7Sopenharmony_ci std::vector<const char*> required_extensions_in_char; 968e5c31af7Sopenharmony_ci std::transform( 969e5c31af7Sopenharmony_ci required_extensions.begin(), required_extensions.end(), 970e5c31af7Sopenharmony_ci std::back_inserter(required_extensions_in_char), 971e5c31af7Sopenharmony_ci [](const std::string& ext) -> const char* { return ext.c_str(); }); 972e5c31af7Sopenharmony_ci 973e5c31af7Sopenharmony_ci VkDeviceCreateInfo info = VkDeviceCreateInfo(); 974e5c31af7Sopenharmony_ci info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 975e5c31af7Sopenharmony_ci info.pQueueCreateInfos = &queue_info; 976e5c31af7Sopenharmony_ci info.queueCreateInfoCount = 1; 977e5c31af7Sopenharmony_ci info.enabledExtensionCount = 978e5c31af7Sopenharmony_ci static_cast<uint32_t>(required_extensions_in_char.size()); 979e5c31af7Sopenharmony_ci info.ppEnabledExtensionNames = required_extensions_in_char.data(); 980e5c31af7Sopenharmony_ci 981e5c31af7Sopenharmony_ci if (supports_get_physical_device_properties2_) 982e5c31af7Sopenharmony_ci return CreateDeviceWithFeatures2(required_features, &info); 983e5c31af7Sopenharmony_ci return CreateDeviceWithFeatures1(required_features, &info); 984e5c31af7Sopenharmony_ci} 985e5c31af7Sopenharmony_ci 986e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CreateDeviceWithFeatures1( 987e5c31af7Sopenharmony_ci const std::vector<std::string>& required_features, 988e5c31af7Sopenharmony_ci VkDeviceCreateInfo* info) { 989e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures required_vulkan_features = 990e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures(); 991e5c31af7Sopenharmony_ci amber::Result r = 992e5c31af7Sopenharmony_ci NamesToVulkanFeatures(required_features, &required_vulkan_features); 993e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 994e5c31af7Sopenharmony_ci return r; 995e5c31af7Sopenharmony_ci 996e5c31af7Sopenharmony_ci info->pEnabledFeatures = &required_vulkan_features; 997e5c31af7Sopenharmony_ci return DoCreateDevice(info); 998e5c31af7Sopenharmony_ci} 999e5c31af7Sopenharmony_ci 1000e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CreateDeviceWithFeatures2( 1001e5c31af7Sopenharmony_ci const std::vector<std::string>& required_features, 1002e5c31af7Sopenharmony_ci VkDeviceCreateInfo* info) { 1003e5c31af7Sopenharmony_ci variable_pointers_feature_.sType = 1004e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR; 1005e5c31af7Sopenharmony_ci variable_pointers_feature_.pNext = nullptr; 1006e5c31af7Sopenharmony_ci 1007e5c31af7Sopenharmony_ci float16_int8_feature_.sType = 1008e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; 1009e5c31af7Sopenharmony_ci float16_int8_feature_.pNext = nullptr; 1010e5c31af7Sopenharmony_ci 1011e5c31af7Sopenharmony_ci storage_8bit_feature_.sType = 1012e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR; 1013e5c31af7Sopenharmony_ci storage_8bit_feature_.pNext = nullptr; 1014e5c31af7Sopenharmony_ci 1015e5c31af7Sopenharmony_ci storage_16bit_feature_.sType = 1016e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR; 1017e5c31af7Sopenharmony_ci storage_16bit_feature_.pNext = nullptr; 1018e5c31af7Sopenharmony_ci 1019e5c31af7Sopenharmony_ci subgroup_size_control_feature_.sType = 1020e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT; 1021e5c31af7Sopenharmony_ci subgroup_size_control_feature_.pNext = nullptr; 1022e5c31af7Sopenharmony_ci 1023e5c31af7Sopenharmony_ci shader_subgroup_extended_types_feature_.sType = 1024e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES; 1025e5c31af7Sopenharmony_ci shader_subgroup_extended_types_feature_.pNext = nullptr; 1026e5c31af7Sopenharmony_ci 1027e5c31af7Sopenharmony_ci void** next_ptr = &variable_pointers_feature_.pNext; 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci if (supports_shader_float16_int8_) { 1030e5c31af7Sopenharmony_ci *next_ptr = &float16_int8_feature_; 1031e5c31af7Sopenharmony_ci next_ptr = &float16_int8_feature_.pNext; 1032e5c31af7Sopenharmony_ci } 1033e5c31af7Sopenharmony_ci 1034e5c31af7Sopenharmony_ci if (supports_shader_8bit_storage_) { 1035e5c31af7Sopenharmony_ci *next_ptr = &storage_8bit_feature_; 1036e5c31af7Sopenharmony_ci next_ptr = &storage_8bit_feature_.pNext; 1037e5c31af7Sopenharmony_ci } 1038e5c31af7Sopenharmony_ci 1039e5c31af7Sopenharmony_ci if (supports_shader_16bit_storage_) { 1040e5c31af7Sopenharmony_ci *next_ptr = &storage_16bit_feature_; 1041e5c31af7Sopenharmony_ci next_ptr = &storage_16bit_feature_.pNext; 1042e5c31af7Sopenharmony_ci } 1043e5c31af7Sopenharmony_ci 1044e5c31af7Sopenharmony_ci if (supports_subgroup_size_control_) { 1045e5c31af7Sopenharmony_ci *next_ptr = &subgroup_size_control_feature_; 1046e5c31af7Sopenharmony_ci next_ptr = &subgroup_size_control_feature_.pNext; 1047e5c31af7Sopenharmony_ci } 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci if (supports_shader_subgroup_extended_types_) { 1050e5c31af7Sopenharmony_ci *next_ptr = &shader_subgroup_extended_types_feature_; 1051e5c31af7Sopenharmony_ci next_ptr = &shader_subgroup_extended_types_feature_.pNext; 1052e5c31af7Sopenharmony_ci } 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci available_features2_.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 1055e5c31af7Sopenharmony_ci available_features2_.pNext = &variable_pointers_feature_; 1056e5c31af7Sopenharmony_ci 1057e5c31af7Sopenharmony_ci std::vector<std::string> feature1_names; 1058e5c31af7Sopenharmony_ci for (const auto& feature : required_features) { 1059e5c31af7Sopenharmony_ci // No dot means this is a features1 feature. 1060e5c31af7Sopenharmony_ci if (feature.find_first_of('.') == std::string::npos) { 1061e5c31af7Sopenharmony_ci feature1_names.push_back(feature); 1062e5c31af7Sopenharmony_ci continue; 1063e5c31af7Sopenharmony_ci } 1064e5c31af7Sopenharmony_ci 1065e5c31af7Sopenharmony_ci if (feature == kVariablePointers) 1066e5c31af7Sopenharmony_ci variable_pointers_feature_.variablePointers = VK_TRUE; 1067e5c31af7Sopenharmony_ci else if (feature == kVariablePointersStorageBuffer) 1068e5c31af7Sopenharmony_ci variable_pointers_feature_.variablePointersStorageBuffer = VK_TRUE; 1069e5c31af7Sopenharmony_ci else if (feature == kFloat16Int8_Float16) 1070e5c31af7Sopenharmony_ci float16_int8_feature_.shaderFloat16 = VK_TRUE; 1071e5c31af7Sopenharmony_ci else if (feature == kFloat16Int8_Int8) 1072e5c31af7Sopenharmony_ci float16_int8_feature_.shaderInt8 = VK_TRUE; 1073e5c31af7Sopenharmony_ci else if (feature == k8BitStorage_Storage) 1074e5c31af7Sopenharmony_ci storage_8bit_feature_.storageBuffer8BitAccess = VK_TRUE; 1075e5c31af7Sopenharmony_ci else if (feature == k8BitStorage_UniformAndStorage) 1076e5c31af7Sopenharmony_ci storage_8bit_feature_.uniformAndStorageBuffer8BitAccess = VK_TRUE; 1077e5c31af7Sopenharmony_ci else if (feature == k8BitStorage_PushConstant) 1078e5c31af7Sopenharmony_ci storage_8bit_feature_.storagePushConstant8 = VK_TRUE; 1079e5c31af7Sopenharmony_ci else if (feature == k16BitStorage_Storage) 1080e5c31af7Sopenharmony_ci storage_16bit_feature_.storageBuffer16BitAccess = VK_TRUE; 1081e5c31af7Sopenharmony_ci else if (feature == k16BitStorage_UniformAndStorage) 1082e5c31af7Sopenharmony_ci storage_16bit_feature_.uniformAndStorageBuffer16BitAccess = VK_TRUE; 1083e5c31af7Sopenharmony_ci else if (feature == k16BitStorage_PushConstant) 1084e5c31af7Sopenharmony_ci storage_16bit_feature_.storagePushConstant16 = VK_TRUE; 1085e5c31af7Sopenharmony_ci else if (feature == k16BitStorage_InputOutput) 1086e5c31af7Sopenharmony_ci storage_16bit_feature_.storageInputOutput16 = VK_TRUE; 1087e5c31af7Sopenharmony_ci else if (feature == kSubgroupSizeControl) 1088e5c31af7Sopenharmony_ci subgroup_size_control_feature_.subgroupSizeControl = VK_TRUE; 1089e5c31af7Sopenharmony_ci else if (feature == kComputeFullSubgroups) 1090e5c31af7Sopenharmony_ci subgroup_size_control_feature_.computeFullSubgroups = VK_TRUE; 1091e5c31af7Sopenharmony_ci else if (feature == kShaderSubgroupExtendedTypes) 1092e5c31af7Sopenharmony_ci shader_subgroup_extended_types_feature_.shaderSubgroupExtendedTypes = 1093e5c31af7Sopenharmony_ci VK_TRUE; 1094e5c31af7Sopenharmony_ci } 1095e5c31af7Sopenharmony_ci 1096e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures required_vulkan_features = 1097e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures(); 1098e5c31af7Sopenharmony_ci amber::Result r = 1099e5c31af7Sopenharmony_ci NamesToVulkanFeatures(feature1_names, &required_vulkan_features); 1100e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 1101e5c31af7Sopenharmony_ci return r; 1102e5c31af7Sopenharmony_ci 1103e5c31af7Sopenharmony_ci available_features2_.features = required_vulkan_features; 1104e5c31af7Sopenharmony_ci 1105e5c31af7Sopenharmony_ci info->pNext = &available_features2_; 1106e5c31af7Sopenharmony_ci info->pEnabledFeatures = nullptr; 1107e5c31af7Sopenharmony_ci return DoCreateDevice(info); 1108e5c31af7Sopenharmony_ci} 1109e5c31af7Sopenharmony_ci 1110e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::DoCreateDevice(VkDeviceCreateInfo* info) { 1111e5c31af7Sopenharmony_ci if (vkCreateDevice(vulkan_physical_device_, info, nullptr, &vulkan_device_) != 1112e5c31af7Sopenharmony_ci VK_SUCCESS) { 1113e5c31af7Sopenharmony_ci return amber::Result("Unable to create vulkan device"); 1114e5c31af7Sopenharmony_ci } 1115e5c31af7Sopenharmony_ci return {}; 1116e5c31af7Sopenharmony_ci} 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_civoid ConfigHelperVulkan::DumpPhysicalDeviceInfo() { 1119e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2KHR properties2 = { 1120e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR, 1121e5c31af7Sopenharmony_ci nullptr, // pNext: will point to our driver_properties struct if the 1122e5c31af7Sopenharmony_ci // "VK_KHR_get_physical_device_properties2" and 1123e5c31af7Sopenharmony_ci // "VK_KHR_driver_properties" extensions are both available. 1124e5c31af7Sopenharmony_ci {}, // properties: this is the older VkPhysicalDeviceProperties struct, 1125e5c31af7Sopenharmony_ci // wrapped by this newer struct that adds the pNext member. We use 1126e5c31af7Sopenharmony_ci // this older struct if the "VK_KHR_get_physical_device_properties2" 1127e5c31af7Sopenharmony_ci // extension is unavailable. 1128e5c31af7Sopenharmony_ci }; 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci VkPhysicalDeviceDriverPropertiesKHR driver_properties = { 1131e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR, 1132e5c31af7Sopenharmony_ci nullptr, 1133e5c31af7Sopenharmony_ci {}, 1134e5c31af7Sopenharmony_ci {}, 1135e5c31af7Sopenharmony_ci {}, 1136e5c31af7Sopenharmony_ci {}, 1137e5c31af7Sopenharmony_ci }; 1138e5c31af7Sopenharmony_ci 1139e5c31af7Sopenharmony_ci VkPhysicalDeviceSubgroupSizeControlPropertiesEXT 1140e5c31af7Sopenharmony_ci subgroup_size_control_properties = { 1141e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT, // NOLINT(whitespace/line_length) 1142e5c31af7Sopenharmony_ci nullptr, 1143e5c31af7Sopenharmony_ci {}, 1144e5c31af7Sopenharmony_ci {}, 1145e5c31af7Sopenharmony_ci {}, 1146e5c31af7Sopenharmony_ci {}}; 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci // If the vkGetPhysicalDeviceProperties2KHR function is unavailable (because 1149e5c31af7Sopenharmony_ci // the "VK_KHR_get_physical_device_properties2" extension is unavailable or 1150e5c31af7Sopenharmony_ci // because vkGetInstanceProcAddr failed) or the "VK_KHR_driver_properties" 1151e5c31af7Sopenharmony_ci // extension is unavailable, then this will stay as nullptr and we will 1152e5c31af7Sopenharmony_ci // instead call the older vkGetPhysicalDeviceProperties function. 1153e5c31af7Sopenharmony_ci PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = 1154e5c31af7Sopenharmony_ci nullptr; 1155e5c31af7Sopenharmony_ci 1156e5c31af7Sopenharmony_ci if (supports_get_physical_device_properties2_ && 1157e5c31af7Sopenharmony_ci std::find(available_device_extensions_.begin(), 1158e5c31af7Sopenharmony_ci available_device_extensions_.end(), 1159e5c31af7Sopenharmony_ci "VK_KHR_driver_properties") != 1160e5c31af7Sopenharmony_ci available_device_extensions_.end()) { 1161e5c31af7Sopenharmony_ci properties2.pNext = &driver_properties; 1162e5c31af7Sopenharmony_ci 1163e5c31af7Sopenharmony_ci vkGetPhysicalDeviceProperties2KHR = 1164e5c31af7Sopenharmony_ci reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>( 1165e5c31af7Sopenharmony_ci vkGetInstanceProcAddr(vulkan_instance_, 1166e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceProperties2KHR")); 1167e5c31af7Sopenharmony_ci if (!vkGetPhysicalDeviceProperties2KHR) { 1168e5c31af7Sopenharmony_ci std::cout << "Warning: device claimed to support " 1169e5c31af7Sopenharmony_ci "vkGetPhysicalDeviceProperties2KHR but could not find this " 1170e5c31af7Sopenharmony_ci "function." 1171e5c31af7Sopenharmony_ci << std::endl; 1172e5c31af7Sopenharmony_ci } 1173e5c31af7Sopenharmony_ci if (supports_subgroup_size_control_) { 1174e5c31af7Sopenharmony_ci driver_properties.pNext = &subgroup_size_control_properties; 1175e5c31af7Sopenharmony_ci } 1176e5c31af7Sopenharmony_ci } 1177e5c31af7Sopenharmony_ci 1178e5c31af7Sopenharmony_ci if (vkGetPhysicalDeviceProperties2KHR) { 1179e5c31af7Sopenharmony_ci vkGetPhysicalDeviceProperties2KHR(vulkan_physical_device_, &properties2); 1180e5c31af7Sopenharmony_ci } else { 1181e5c31af7Sopenharmony_ci vkGetPhysicalDeviceProperties(vulkan_physical_device_, 1182e5c31af7Sopenharmony_ci &properties2.properties); 1183e5c31af7Sopenharmony_ci } 1184e5c31af7Sopenharmony_ci 1185e5c31af7Sopenharmony_ci const VkPhysicalDeviceProperties& props = properties2.properties; 1186e5c31af7Sopenharmony_ci 1187e5c31af7Sopenharmony_ci uint32_t api_version = props.apiVersion; 1188e5c31af7Sopenharmony_ci 1189e5c31af7Sopenharmony_ci std::cout << std::endl; 1190e5c31af7Sopenharmony_ci std::cout << "Physical device properties:" << std::endl; 1191e5c31af7Sopenharmony_ci std::cout << " apiVersion: " << static_cast<uint32_t>(api_version >> 22u) 1192e5c31af7Sopenharmony_ci << "." << static_cast<uint32_t>((api_version >> 12u) & 0x3ffu) 1193e5c31af7Sopenharmony_ci << "." << static_cast<uint32_t>(api_version & 0xfffu) << std::endl; 1194e5c31af7Sopenharmony_ci std::cout << " driverVersion: " << props.driverVersion << std::endl; 1195e5c31af7Sopenharmony_ci std::cout << " vendorID: " << props.vendorID << std::endl; 1196e5c31af7Sopenharmony_ci std::cout << " deviceID: " << props.deviceID << std::endl; 1197e5c31af7Sopenharmony_ci std::cout << " deviceType: " << deviceTypeToName(props.deviceType) 1198e5c31af7Sopenharmony_ci << std::endl; 1199e5c31af7Sopenharmony_ci std::cout << " deviceName: " << props.deviceName << std::endl; 1200e5c31af7Sopenharmony_ci if (vkGetPhysicalDeviceProperties2KHR) { 1201e5c31af7Sopenharmony_ci std::cout << " driverName: " << driver_properties.driverName << std::endl; 1202e5c31af7Sopenharmony_ci std::cout << " driverInfo: " << driver_properties.driverInfo << std::endl; 1203e5c31af7Sopenharmony_ci if (supports_subgroup_size_control_) { 1204e5c31af7Sopenharmony_ci std::cout << " minSubgroupSize: " 1205e5c31af7Sopenharmony_ci << subgroup_size_control_properties.minSubgroupSize 1206e5c31af7Sopenharmony_ci << std::endl; 1207e5c31af7Sopenharmony_ci std::cout << " maxSubgroupSize: " 1208e5c31af7Sopenharmony_ci << subgroup_size_control_properties.maxSubgroupSize 1209e5c31af7Sopenharmony_ci << std::endl; 1210e5c31af7Sopenharmony_ci std::cout << " maxComputeWorkgroupSubgroups: " 1211e5c31af7Sopenharmony_ci << subgroup_size_control_properties.maxComputeWorkgroupSubgroups 1212e5c31af7Sopenharmony_ci << std::endl; 1213e5c31af7Sopenharmony_ci std::cout << " requiredSubgroupSizeStages: " 1214e5c31af7Sopenharmony_ci << stageFlagBitsToNames(subgroup_size_control_properties 1215e5c31af7Sopenharmony_ci .requiredSubgroupSizeStages) 1216e5c31af7Sopenharmony_ci << std::endl; 1217e5c31af7Sopenharmony_ci } 1218e5c31af7Sopenharmony_ci } 1219e5c31af7Sopenharmony_ci std::cout << "End of physical device properties." << std::endl; 1220e5c31af7Sopenharmony_ci} 1221e5c31af7Sopenharmony_ci 1222e5c31af7Sopenharmony_ciamber::Result ConfigHelperVulkan::CreateConfig( 1223e5c31af7Sopenharmony_ci uint32_t engine_major, 1224e5c31af7Sopenharmony_ci uint32_t engine_minor, 1225e5c31af7Sopenharmony_ci int32_t selected_device, 1226e5c31af7Sopenharmony_ci const std::vector<std::string>& required_features, 1227e5c31af7Sopenharmony_ci const std::vector<std::string>& required_instance_extensions, 1228e5c31af7Sopenharmony_ci const std::vector<std::string>& required_device_extensions, 1229e5c31af7Sopenharmony_ci bool disable_validation_layer, 1230e5c31af7Sopenharmony_ci bool show_version_info, 1231e5c31af7Sopenharmony_ci std::unique_ptr<amber::EngineConfig>* cfg_holder) { 1232e5c31af7Sopenharmony_ci amber::Result r = CreateVulkanInstance(engine_major, engine_minor, 1233e5c31af7Sopenharmony_ci required_instance_extensions, 1234e5c31af7Sopenharmony_ci disable_validation_layer); 1235e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 1236e5c31af7Sopenharmony_ci return r; 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci if (!disable_validation_layer) { 1239e5c31af7Sopenharmony_ci r = CreateDebugReportCallback(); 1240e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 1241e5c31af7Sopenharmony_ci return r; 1242e5c31af7Sopenharmony_ci } 1243e5c31af7Sopenharmony_ci 1244e5c31af7Sopenharmony_ci r = ChooseVulkanPhysicalDevice(required_features, required_device_extensions, 1245e5c31af7Sopenharmony_ci selected_device); 1246e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 1247e5c31af7Sopenharmony_ci return r; 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci if (show_version_info) 1250e5c31af7Sopenharmony_ci DumpPhysicalDeviceInfo(); 1251e5c31af7Sopenharmony_ci 1252e5c31af7Sopenharmony_ci r = CreateVulkanDevice(required_features, required_device_extensions); 1253e5c31af7Sopenharmony_ci if (!r.IsSuccess()) 1254e5c31af7Sopenharmony_ci return r; 1255e5c31af7Sopenharmony_ci 1256e5c31af7Sopenharmony_ci vkGetDeviceQueue(vulkan_device_, vulkan_queue_family_index_, 0, 1257e5c31af7Sopenharmony_ci &vulkan_queue_); 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci *cfg_holder = 1260e5c31af7Sopenharmony_ci std::unique_ptr<amber::EngineConfig>(new amber::VulkanEngineConfig()); 1261e5c31af7Sopenharmony_ci amber::VulkanEngineConfig* config = 1262e5c31af7Sopenharmony_ci static_cast<amber::VulkanEngineConfig*>(cfg_holder->get()); 1263e5c31af7Sopenharmony_ci config->physical_device = vulkan_physical_device_; 1264e5c31af7Sopenharmony_ci config->available_features = available_features_; 1265e5c31af7Sopenharmony_ci config->available_features2 = available_features2_; 1266e5c31af7Sopenharmony_ci config->available_instance_extensions = available_instance_extensions_; 1267e5c31af7Sopenharmony_ci config->available_device_extensions = available_device_extensions_; 1268e5c31af7Sopenharmony_ci config->instance = vulkan_instance_; 1269e5c31af7Sopenharmony_ci config->queue_family_index = vulkan_queue_family_index_; 1270e5c31af7Sopenharmony_ci config->queue = vulkan_queue_; 1271e5c31af7Sopenharmony_ci config->device = vulkan_device_; 1272e5c31af7Sopenharmony_ci config->vkGetInstanceProcAddr = vkGetInstanceProcAddr; 1273e5c31af7Sopenharmony_ci 1274e5c31af7Sopenharmony_ci return {}; 1275e5c31af7Sopenharmony_ci} 1276e5c31af7Sopenharmony_ci 1277e5c31af7Sopenharmony_ci} // namespace sample 1278