From 71da4ba35152561af11bf7a396059856e5609b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 29 Jun 2020 12:27:26 +0300 Subject: [PATCH 1/4] Add support for Vulkan 1.2 feature structures --- src/vulkan/device.cc | 275 +++++++++++++++++++++--------------- src/vulkan/device.h | 16 +-- src/vulkan/engine_vulkan.cc | 6 +- 3 files changed, 169 insertions(+), 128 deletions(-) diff --git a/src/vulkan/device.cc b/src/vulkan/device.cc index ab0ddfbda..89d9cb219 100644 --- a/src/vulkan/device.cc +++ b/src/vulkan/device.cc @@ -394,7 +394,6 @@ Result Device::Initialize( PFN_vkGetInstanceProcAddr getInstanceProcAddr, Delegate* delegate, const std::vector& required_features, - const std::vector& required_instance_extensions, const std::vector& required_device_extensions, const VkPhysicalDeviceFeatures& available_features, const VkPhysicalDeviceFeatures2KHR& available_features2, @@ -403,121 +402,134 @@ Result Device::Initialize( if (!r.IsSuccess()) return r; - bool use_physical_device_features_2 = false; - for (auto& ext : required_instance_extensions) { - if (ext == "VK_KHR_get_physical_device_properties2") - use_physical_device_features_2 = true; + // Check for the core features. We don't know if available_features or + // available_features2 is provided, so check both. + if (!AreAllRequiredFeaturesSupported(available_features, required_features) && + !AreAllRequiredFeaturesSupported(available_features2.features, + required_features)) { + return Result( + "Vulkan: Device::Initialize given physical device does not support " + "required features"); } - VkPhysicalDeviceFeatures available_vulkan_features = - VkPhysicalDeviceFeatures(); - if (use_physical_device_features_2) { - available_vulkan_features = available_features2.features; - - VkPhysicalDeviceVariablePointerFeaturesKHR* var_ptrs = nullptr; - VkPhysicalDeviceFloat16Int8FeaturesKHR* float16_ptrs = nullptr; - VkPhysicalDevice8BitStorageFeaturesKHR* storage8_ptrs = nullptr; - VkPhysicalDevice16BitStorageFeaturesKHR* storage16_ptrs = nullptr; - VkPhysicalDeviceSubgroupSizeControlFeaturesEXT* - subgroup_size_control_features = nullptr; - void* ptr = available_features2.pNext; - while (ptr != nullptr) { - BaseOutStructure* s = static_cast(ptr); - if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR) { - var_ptrs = - static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR) { - float16_ptrs = - static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR) { - storage8_ptrs = - static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR) { - storage16_ptrs = - static_cast(ptr); - } else if ( - s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT) { // NOLINT(whitespace/line_length) - subgroup_size_control_features = - static_cast(ptr); - } - ptr = s->pNext; + // Search for additional features in case they are found in pNext field of + // available_features2. + VkPhysicalDeviceVariablePointerFeaturesKHR* var_ptrs = nullptr; + VkPhysicalDeviceFloat16Int8FeaturesKHR* float16_ptrs = nullptr; + VkPhysicalDevice8BitStorageFeaturesKHR* storage8_ptrs = nullptr; + VkPhysicalDevice16BitStorageFeaturesKHR* storage16_ptrs = nullptr; + VkPhysicalDeviceVulkan11Features* vulkan11_ptrs = nullptr; + VkPhysicalDeviceVulkan12Features* vulkan12_ptrs = nullptr; + VkPhysicalDeviceSubgroupSizeControlFeaturesEXT* + subgroup_size_control_features = nullptr; + void* ptr = available_features2.pNext; + while (ptr != nullptr) { + BaseOutStructure* s = static_cast(ptr); + if (s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR) { + var_ptrs = static_cast(ptr); + } else if (s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR) { + float16_ptrs = static_cast(ptr); + } else if (s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR) { + storage8_ptrs = static_cast(ptr); + } else if (s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR) { + storage16_ptrs = + static_cast(ptr); + } else if ( + s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT) { // NOLINT(whitespace/line_length) + subgroup_size_control_features = + static_cast(ptr); + } else if (s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES) { + vulkan11_ptrs = static_cast(ptr); + } else if (s->sType == + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES) { + vulkan12_ptrs = static_cast(ptr); } + ptr = s->pNext; + } - std::vector required_features1; - for (const auto& feature : required_features) { - // No dot means this is a features1 feature. - if (feature.find_first_of('.') == std::string::npos) { - required_features1.push_back(feature); - continue; - } + // Compare the available additional (non-core) features against the + // requirements. + for (const auto& feature : required_features) { + // First check the feature structures are provided for the required + // features. + if ((feature == kVariablePointers || + feature == kVariablePointersStorageBuffer) && + var_ptrs == nullptr && vulkan11_ptrs == nullptr) { + return amber::Result( + "Variable pointers requested but feature not returned"); + } + if ((feature == k16BitStorage_Storage || + feature == k16BitStorage_UniformAndStorage || + feature == k16BitStorage_PushConstant || + feature == k16BitStorage_InputOutput) && + storage16_ptrs == nullptr && vulkan11_ptrs == nullptr) { + return amber::Result( + "Shader 16-bit storage requested but feature not returned"); + } + if ((feature == kFloat16Int8_Float16 || feature == kFloat16Int8_Int8) && + float16_ptrs == nullptr && vulkan12_ptrs == nullptr) { + return amber::Result( + "Shader float16/int8 requested but feature not returned"); + } + if ((feature == k8BitStorage_UniformAndStorage || + feature == k8BitStorage_Storage || + feature == k8BitStorage_PushConstant) && + storage8_ptrs == nullptr && vulkan12_ptrs == nullptr) { + return amber::Result( + "Shader 8-bit storage requested but feature not returned"); + } + if ((feature == kSubgroupSizeControl || feature == kComputeFullSubgroups) && + subgroup_size_control_features == nullptr) { + return amber::Result("Missing subgroup size control features"); + } - if ((feature == kVariablePointers || - feature == kVariablePointersStorageBuffer) && - var_ptrs == nullptr) { - return amber::Result( - "Variable pointers requested but feature not returned"); - } + // Next check the fields of the feature structures. + // If Vulkan 1.1 structure exists the features are set there. + if (vulkan11_ptrs) { if (feature == kVariablePointers && - var_ptrs->variablePointers != VK_TRUE) { + vulkan11_ptrs->variablePointers != VK_TRUE) { return amber::Result("Missing variable pointers feature"); } if (feature == kVariablePointersStorageBuffer && - var_ptrs->variablePointersStorageBuffer != VK_TRUE) { + vulkan11_ptrs->variablePointersStorageBuffer != VK_TRUE) { return amber::Result( "Missing variable pointers storage buffer feature"); } - - if ((feature == kFloat16Int8_Float16 || feature == kFloat16Int8_Int8) && - float16_ptrs == nullptr) { - return amber::Result( - "Shader float16/int8 requested but feature not returned"); - } - - if (feature == kFloat16Int8_Float16 && - float16_ptrs->shaderFloat16 != VK_TRUE) { - return amber::Result("Missing float16 feature"); - } - - if (feature == kFloat16Int8_Int8 && float16_ptrs->shaderInt8 != VK_TRUE) { - return amber::Result("Missing int8 feature"); + if (feature == k16BitStorage_Storage && + vulkan11_ptrs->storageBuffer16BitAccess != VK_TRUE) { + return amber::Result("Missing 16-bit storage access"); } - - if ((feature == k8BitStorage_UniformAndStorage || - feature == k8BitStorage_Storage || - feature == k8BitStorage_PushConstant) && - storage8_ptrs == nullptr) { - return amber::Result( - "Shader 8-bit storage requested but feature not returned"); + if (feature == k16BitStorage_UniformAndStorage && + vulkan11_ptrs->uniformAndStorageBuffer16BitAccess != VK_TRUE) { + return amber::Result("Missing 16-bit uniform and storage access"); } - - if (feature == k8BitStorage_Storage && - storage8_ptrs->storageBuffer8BitAccess != VK_TRUE) { - return amber::Result("Missing 8-bit storage access"); + if (feature == k16BitStorage_PushConstant && + vulkan11_ptrs->storagePushConstant16 != VK_TRUE) { + return amber::Result("Missing 16-bit push constant access"); } - if (feature == k8BitStorage_UniformAndStorage && - storage8_ptrs->uniformAndStorageBuffer8BitAccess != VK_TRUE) { - return amber::Result("Missing 8-bit uniform and storage access"); + if (feature == k16BitStorage_InputOutput && + vulkan11_ptrs->storageInputOutput16 != VK_TRUE) { + return amber::Result("Missing 16-bit input/output access"); } - if (feature == k8BitStorage_PushConstant && - storage8_ptrs->storagePushConstant8 != VK_TRUE) { - return amber::Result("Missing 8-bit push constant access"); + } else { + // Vulkan 1.1 structure was not found. Use separate structures per each + // feature. + if (feature == kVariablePointers && + var_ptrs->variablePointers != VK_TRUE) { + return amber::Result("Missing variable pointers feature"); } - - if ((feature == k16BitStorage_Storage || - feature == k16BitStorage_UniformAndStorage || - feature == k16BitStorage_PushConstant || - feature == k16BitStorage_InputOutput) && - storage16_ptrs == nullptr) { + if (feature == kVariablePointersStorageBuffer && + var_ptrs->variablePointersStorageBuffer != VK_TRUE) { return amber::Result( - "Shader 16-bit storage requested but feature not returned"); + "Missing variable pointers storage buffer feature"); } - if (feature == k16BitStorage_Storage && storage16_ptrs->storageBuffer16BitAccess != VK_TRUE) { return amber::Result("Missing 16-bit storage access"); @@ -534,31 +546,62 @@ Result Device::Initialize( storage16_ptrs->storageInputOutput16 != VK_TRUE) { return amber::Result("Missing 16-bit input/output access"); } + } - if ((feature == kSubgroupSizeControl || - feature == kComputeFullSubgroups) && - subgroup_size_control_features == nullptr) { - return amber::Result("Missing subgroup size control features"); + // If Vulkan 1.2 structure exists the features are set there. + if (vulkan12_ptrs) { + if (feature == kFloat16Int8_Float16 && + vulkan12_ptrs->shaderFloat16 != VK_TRUE) { + return amber::Result("Missing float16 feature"); + } + if (feature == kFloat16Int8_Int8 && + vulkan12_ptrs->shaderInt8 != VK_TRUE) { + return amber::Result("Missing int8 feature"); + } + if (feature == k8BitStorage_Storage && + vulkan12_ptrs->storageBuffer8BitAccess != VK_TRUE) { + return amber::Result("Missing 8-bit storage access"); + } + if (feature == k8BitStorage_UniformAndStorage && + vulkan12_ptrs->uniformAndStorageBuffer8BitAccess != VK_TRUE) { + return amber::Result("Missing 8-bit uniform and storage access"); + } + if (feature == k8BitStorage_PushConstant && + vulkan12_ptrs->storagePushConstant8 != VK_TRUE) { + return amber::Result("Missing 8-bit push constant access"); + } + } else { + // Vulkan 1.2 structure was not found. Use separate structures per each + // feature. + if (feature == kFloat16Int8_Float16 && + float16_ptrs->shaderFloat16 != VK_TRUE) { + return amber::Result("Missing float16 feature"); + } + if (feature == kFloat16Int8_Int8 && float16_ptrs->shaderInt8 != VK_TRUE) { + return amber::Result("Missing int8 feature"); } - if (feature == kSubgroupSizeControl && - subgroup_size_control_features->subgroupSizeControl != VK_TRUE) { - return amber::Result("Missing subgroup size control feature"); + if (feature == k8BitStorage_Storage && + storage8_ptrs->storageBuffer8BitAccess != VK_TRUE) { + return amber::Result("Missing 8-bit storage access"); + } + if (feature == k8BitStorage_UniformAndStorage && + storage8_ptrs->uniformAndStorageBuffer8BitAccess != VK_TRUE) { + return amber::Result("Missing 8-bit uniform and storage access"); } - if (feature == kComputeFullSubgroups && - subgroup_size_control_features->computeFullSubgroups != VK_TRUE) { - return amber::Result("Missing compute full subgroups feature"); + if (feature == k8BitStorage_PushConstant && + storage8_ptrs->storagePushConstant8 != VK_TRUE) { + return amber::Result("Missing 8-bit push constant access"); } } - } else { - available_vulkan_features = available_features; - } - - if (!AreAllRequiredFeaturesSupported(available_vulkan_features, - required_features)) { - return Result( - "Vulkan: Device::Initialize given physical device does not support " - "required features"); + if (feature == kSubgroupSizeControl && + subgroup_size_control_features->subgroupSizeControl != VK_TRUE) { + return amber::Result("Missing subgroup size control feature"); + } + if (feature == kComputeFullSubgroups && + subgroup_size_control_features->computeFullSubgroups != VK_TRUE) { + return amber::Result("Missing compute full subgroups feature"); + } } if (!AreAllExtensionsSupported(available_extensions, @@ -578,7 +621,7 @@ Result Device::Initialize( const bool needs_subgroup_size_control = std::find(required_features.begin(), required_features.end(), kSubgroupSizeControl) != required_features.end(); - if (needs_subgroup_size_control && use_physical_device_features_2) { + if (needs_subgroup_size_control) { PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = reinterpret_cast( getInstanceProcAddr(instance_, diff --git a/src/vulkan/device.h b/src/vulkan/device.h index eccab8b53..4912568cc 100644 --- a/src/vulkan/device.h +++ b/src/vulkan/device.h @@ -43,15 +43,13 @@ class Device { VkQueue queue); virtual ~Device(); - Result Initialize( - PFN_vkGetInstanceProcAddr getInstanceProcAddr, - Delegate* delegate, - const std::vector& required_features, - const std::vector& required_instance_extensions, - const std::vector& required_device_extensions, - const VkPhysicalDeviceFeatures& available_features, - const VkPhysicalDeviceFeatures2KHR& available_features2, - const std::vector& available_extensions); + Result Initialize(PFN_vkGetInstanceProcAddr getInstanceProcAddr, + Delegate* delegate, + const std::vector& required_features, + const std::vector& required_device_extensions, + const VkPhysicalDeviceFeatures& available_features, + const VkPhysicalDeviceFeatures2KHR& available_features2, + const std::vector& available_extensions); /// Returns true if |format| and the |buffer|s buffer type combination is /// supported by the physical device. diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index 97672cba2..6586ddde8 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -118,9 +118,9 @@ Result EngineVulkan::Initialize( vk_config->queue); Result r = device_->Initialize( - vk_config->vkGetInstanceProcAddr, delegate, features, instance_extensions, - device_extensions, vk_config->available_features, - vk_config->available_features2, vk_config->available_device_extensions); + vk_config->vkGetInstanceProcAddr, delegate, features, device_extensions, + vk_config->available_features, vk_config->available_features2, + vk_config->available_device_extensions); if (!r.IsSuccess()) return r; From d408519be5766a471a8200107d97e2de1dd5274c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 29 Jun 2020 14:41:23 +0300 Subject: [PATCH 2/4] Addressed review comments and enabled local Vulkan header for NDK builds --- Android.mk | 3 ++- src/vulkan/device.cc | 59 ++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Android.mk b/Android.mk index ae83c261d..3bd442dd9 100644 --- a/Android.mk +++ b/Android.mk @@ -20,7 +20,8 @@ LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti \ -Wno-unknown-pragmas \ -DAMBER_ENABLE_SPIRV_TOOLS=1 \ -DAMBER_ENABLE_SHADERC=1 \ - -DAMBER_ENGINE_VULKAN=1 + -DAMBER_ENGINE_VULKAN=1 \ + -DAMBER_USE_LOCAL_VULKAN=1 LOCAL_SRC_FILES:= \ src/amber.cc \ src/amberscript/parser.cc \ diff --git a/src/vulkan/device.cc b/src/vulkan/device.cc index 89d9cb219..030de9f91 100644 --- a/src/vulkan/device.cc +++ b/src/vulkan/device.cc @@ -425,36 +425,47 @@ Result Device::Initialize( void* ptr = available_features2.pNext; while (ptr != nullptr) { BaseOutStructure* s = static_cast(ptr); - if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR) { - var_ptrs = static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR) { - float16_ptrs = static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR) { - storage8_ptrs = static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR) { - storage16_ptrs = - static_cast(ptr); - } else if ( - s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT) { // NOLINT(whitespace/line_length) - subgroup_size_control_features = - static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES) { - vulkan11_ptrs = static_cast(ptr); - } else if (s->sType == - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES) { - vulkan12_ptrs = static_cast(ptr); + switch (s->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR: + var_ptrs = + static_cast(ptr); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: + float16_ptrs = + static_cast(ptr); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: + storage8_ptrs = + static_cast(ptr); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR: + storage16_ptrs = + static_cast(ptr); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT: + subgroup_size_control_features = + static_cast(ptr); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: + vulkan11_ptrs = static_cast(ptr); + break; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: + vulkan12_ptrs = static_cast(ptr); + break; + default: + break; } ptr = s->pNext; } // Compare the available additional (non-core) features against the // requirements. + // + // Vulkan 1.2 added support for defining non-core physical device features + // using VkPhysicalDeviceVulkan11Features and VkPhysicalDeviceVulkan12Features + // structures. If |vulkan11_ptrs| and/or |vulkan12_ptrs| are null, we must + // check for features using the old approach (by checking across various + // feature structs); otherwise, we can check features via the new structs. for (const auto& feature : required_features) { // First check the feature structures are provided for the required // features. From c6237bd8cb6c519d587982cfad70a65385dd8468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Mon, 29 Jun 2020 15:06:58 +0300 Subject: [PATCH 3/4] Another try to get NDK build working. --- Android.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Android.mk b/Android.mk index 3bd442dd9..d7fc39290 100644 --- a/Android.mk +++ b/Android.mk @@ -20,8 +20,7 @@ LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti \ -Wno-unknown-pragmas \ -DAMBER_ENABLE_SPIRV_TOOLS=1 \ -DAMBER_ENABLE_SHADERC=1 \ - -DAMBER_ENGINE_VULKAN=1 \ - -DAMBER_USE_LOCAL_VULKAN=1 + -DAMBER_ENGINE_VULKAN=1 LOCAL_SRC_FILES:= \ src/amber.cc \ src/amberscript/parser.cc \ @@ -76,7 +75,7 @@ LOCAL_SRC_FILES:= \ src/vulkan/vertex_buffer.cc \ src/vulkan_engine_config.cc LOCAL_STATIC_LIBRARIES:=glslang SPIRV-Tools shaderc -LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include +LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include $(LOCAL_PATH)/third_party/vulkan-headers/include LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/include include $(BUILD_STATIC_LIBRARY) From 9406e7063f6567551d50faf3cfff06c153893bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Suonp=C3=A4=C3=A4?= Date: Tue, 30 Jun 2020 07:52:13 +0300 Subject: [PATCH 4/4] Restored the checking of VK_KHR_get_physical_device_properties2 --- src/vulkan/device.cc | 14 ++++++++++++++ src/vulkan/device.h | 16 +++++++++------- src/vulkan/engine_vulkan.cc | 6 +++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/vulkan/device.cc b/src/vulkan/device.cc index 030de9f91..a1c05ea39 100644 --- a/src/vulkan/device.cc +++ b/src/vulkan/device.cc @@ -394,6 +394,7 @@ Result Device::Initialize( PFN_vkGetInstanceProcAddr getInstanceProcAddr, Delegate* delegate, const std::vector& required_features, + const std::vector& required_instance_extensions, const std::vector& required_device_extensions, const VkPhysicalDeviceFeatures& available_features, const VkPhysicalDeviceFeatures2KHR& available_features2, @@ -628,11 +629,24 @@ Result Device::Initialize( ptrs_.vkGetPhysicalDeviceMemoryProperties(physical_device_, &physical_memory_properties_); + bool use_physical_device_features_2 = false; + for (auto& ext : required_instance_extensions) { + if (ext == "VK_KHR_get_physical_device_properties2") + use_physical_device_features_2 = true; + } + subgroup_size_control_properties_ = {}; const bool needs_subgroup_size_control = std::find(required_features.begin(), required_features.end(), kSubgroupSizeControl) != required_features.end(); + if (needs_subgroup_size_control) { + if (!use_physical_device_features_2) { + return Result( + "Vulkan: Device::Initialize subgroup size control feature also " + "requires VK_KHR_get_physical_device_properties2"); + } + PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = reinterpret_cast( getInstanceProcAddr(instance_, diff --git a/src/vulkan/device.h b/src/vulkan/device.h index 4912568cc..eccab8b53 100644 --- a/src/vulkan/device.h +++ b/src/vulkan/device.h @@ -43,13 +43,15 @@ class Device { VkQueue queue); virtual ~Device(); - Result Initialize(PFN_vkGetInstanceProcAddr getInstanceProcAddr, - Delegate* delegate, - const std::vector& required_features, - const std::vector& required_device_extensions, - const VkPhysicalDeviceFeatures& available_features, - const VkPhysicalDeviceFeatures2KHR& available_features2, - const std::vector& available_extensions); + Result Initialize( + PFN_vkGetInstanceProcAddr getInstanceProcAddr, + Delegate* delegate, + const std::vector& required_features, + const std::vector& required_instance_extensions, + const std::vector& required_device_extensions, + const VkPhysicalDeviceFeatures& available_features, + const VkPhysicalDeviceFeatures2KHR& available_features2, + const std::vector& available_extensions); /// Returns true if |format| and the |buffer|s buffer type combination is /// supported by the physical device. diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index 6586ddde8..97672cba2 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -118,9 +118,9 @@ Result EngineVulkan::Initialize( vk_config->queue); Result r = device_->Initialize( - vk_config->vkGetInstanceProcAddr, delegate, features, device_extensions, - vk_config->available_features, vk_config->available_features2, - vk_config->available_device_extensions); + vk_config->vkGetInstanceProcAddr, delegate, features, instance_extensions, + device_extensions, vk_config->available_features, + vk_config->available_features2, vk_config->available_device_extensions); if (!r.IsSuccess()) return r;