Merge pull request #48439 from BastiaanOlij/cleanup_vulkan_checks
Cleanup vulkan capabilities check and add multiview check
This commit is contained in:
commit
a5a0fe65df
4 changed files with 93 additions and 17 deletions
|
@ -7844,6 +7844,10 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
|
||||||
device_capabilities.subgroup_size = subgroup_capabilities.size;
|
device_capabilities.subgroup_size = subgroup_capabilities.size;
|
||||||
device_capabilities.subgroup_in_shaders = subgroup_capabilities.supported_stages_flags_rd();
|
device_capabilities.subgroup_in_shaders = subgroup_capabilities.supported_stages_flags_rd();
|
||||||
device_capabilities.subgroup_operations = subgroup_capabilities.supported_operations_flags_rd();
|
device_capabilities.subgroup_operations = subgroup_capabilities.supported_operations_flags_rd();
|
||||||
|
|
||||||
|
// get info about further features
|
||||||
|
VulkanContext::MultiviewCapabilities multiview_capabilies = p_context->get_multiview_capabilities();
|
||||||
|
device_capabilities.supports_multiview = multiview_capabilies.is_supported && multiview_capabilies.max_view_count > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = p_context;
|
context = p_context;
|
||||||
|
|
|
@ -352,8 +352,6 @@ Error VulkanContext::_initialize_extensions() {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void(VKAPI_PTR *_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice, VkPhysicalDeviceProperties2 *);
|
|
||||||
|
|
||||||
uint32_t VulkanContext::SubgroupCapabilities::supported_stages_flags_rd() const {
|
uint32_t VulkanContext::SubgroupCapabilities::supported_stages_flags_rd() const {
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
@ -496,20 +494,70 @@ String VulkanContext::SubgroupCapabilities::supported_operations_desc() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Error VulkanContext::_check_capabilities() {
|
Error VulkanContext::_check_capabilities() {
|
||||||
// check subgroups
|
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
|
||||||
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
|
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
|
||||||
|
|
||||||
// for Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
|
// for Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
|
||||||
_vkGetPhysicalDeviceProperties2 func = (_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2");
|
|
||||||
if (func != nullptr) {
|
// so we check if the functions are accessible by getting their function pointers and skipping if not
|
||||||
|
// (note that the desktop loader does a better job here but the android loader doesn't)
|
||||||
|
|
||||||
|
// assume not supported until proven otherwise
|
||||||
|
multiview_capabilities.is_supported = false;
|
||||||
|
multiview_capabilities.max_view_count = 0;
|
||||||
|
multiview_capabilities.max_instance_count = 0;
|
||||||
|
subgroup_capabilities.size = 0;
|
||||||
|
subgroup_capabilities.supportedStages = 0;
|
||||||
|
subgroup_capabilities.supportedOperations = 0;
|
||||||
|
subgroup_capabilities.quadOperationsInAllStages = false;
|
||||||
|
|
||||||
|
// check for extended features
|
||||||
|
PFN_vkGetPhysicalDeviceFeatures2 device_features_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2");
|
||||||
|
if (device_features_func == nullptr) {
|
||||||
|
// In Vulkan 1.0 might be accessible under its original extension name
|
||||||
|
device_features_func = (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceFeatures2KHR");
|
||||||
|
}
|
||||||
|
if (device_features_func != nullptr) {
|
||||||
|
// check our extended features
|
||||||
|
VkPhysicalDeviceMultiviewFeatures multiview_features;
|
||||||
|
multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
|
||||||
|
multiview_features.pNext = NULL;
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures2 device_features;
|
||||||
|
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||||
|
device_features.pNext = &multiview_features;
|
||||||
|
|
||||||
|
device_features_func(gpu, &device_features);
|
||||||
|
multiview_capabilities.is_supported = multiview_features.multiview;
|
||||||
|
// For now we ignore if multiview is available in geometry and tesselation as we do not currently support those
|
||||||
|
}
|
||||||
|
|
||||||
|
// check extended properties
|
||||||
|
PFN_vkGetPhysicalDeviceProperties2 device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2");
|
||||||
|
if (device_properties_func == nullptr) {
|
||||||
|
// In Vulkan 1.0 might be accessible under its original extension name
|
||||||
|
device_properties_func = (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2KHR");
|
||||||
|
}
|
||||||
|
if (device_properties_func != nullptr) {
|
||||||
|
VkPhysicalDeviceMultiviewProperties multiviewProperties;
|
||||||
VkPhysicalDeviceSubgroupProperties subgroupProperties;
|
VkPhysicalDeviceSubgroupProperties subgroupProperties;
|
||||||
|
VkPhysicalDeviceProperties2 physicalDeviceProperties;
|
||||||
|
|
||||||
subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
|
subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
|
||||||
subgroupProperties.pNext = nullptr;
|
subgroupProperties.pNext = nullptr;
|
||||||
|
|
||||||
VkPhysicalDeviceProperties2 physicalDeviceProperties;
|
|
||||||
physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||||
physicalDeviceProperties.pNext = &subgroupProperties;
|
|
||||||
|
|
||||||
func(gpu, &physicalDeviceProperties);
|
if (multiview_capabilities.is_supported) {
|
||||||
|
multiviewProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
|
||||||
|
multiviewProperties.pNext = &subgroupProperties;
|
||||||
|
|
||||||
|
physicalDeviceProperties.pNext = &multiviewProperties;
|
||||||
|
} else {
|
||||||
|
physicalDeviceProperties.pNext = &subgroupProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_properties_func(gpu, &physicalDeviceProperties);
|
||||||
|
|
||||||
subgroup_capabilities.size = subgroupProperties.subgroupSize;
|
subgroup_capabilities.size = subgroupProperties.subgroupSize;
|
||||||
subgroup_capabilities.supportedStages = subgroupProperties.supportedStages;
|
subgroup_capabilities.supportedStages = subgroupProperties.supportedStages;
|
||||||
|
@ -519,18 +567,30 @@ Error VulkanContext::_check_capabilities() {
|
||||||
// - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT
|
// - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT
|
||||||
subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
|
subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
|
||||||
|
|
||||||
// only output this when debugging?
|
if (multiview_capabilities.is_supported) {
|
||||||
print_line("- Vulkan subgroup size " + itos(subgroup_capabilities.size));
|
multiview_capabilities.max_view_count = multiviewProperties.maxMultiviewViewCount;
|
||||||
print_line("- Vulkan subgroup stages " + subgroup_capabilities.supported_stages_desc());
|
multiview_capabilities.max_instance_count = multiviewProperties.maxMultiviewInstanceIndex;
|
||||||
print_line("- Vulkan subgroup supported ops " + subgroup_capabilities.supported_operations_desc());
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
print_line("- Vulkan multiview supported:");
|
||||||
|
print_line(" max views: " + itos(multiview_capabilities.max_view_count));
|
||||||
|
print_line(" max instances: " + itos(multiview_capabilities.max_instance_count));
|
||||||
|
} else {
|
||||||
|
print_line("- Vulkan multiview not supported");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
print_line("- Vulkan subgroup:");
|
||||||
|
print_line(" size: " + itos(subgroup_capabilities.size));
|
||||||
|
print_line(" stages: " + subgroup_capabilities.supported_stages_desc());
|
||||||
|
print_line(" supported ops: " + subgroup_capabilities.supported_operations_desc());
|
||||||
if (subgroup_capabilities.quadOperationsInAllStages) {
|
if (subgroup_capabilities.quadOperationsInAllStages) {
|
||||||
print_line("- Vulkan subgroup quad operations in all stages");
|
print_line(" quad operations in all stages");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
subgroup_capabilities.size = 0;
|
print_line("- Couldn't call vkGetPhysicalDeviceProperties2");
|
||||||
subgroup_capabilities.supportedStages = 0;
|
#endif
|
||||||
subgroup_capabilities.supportedOperations = 0;
|
|
||||||
subgroup_capabilities.quadOperationsInAllStages = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
@ -54,6 +54,12 @@ public:
|
||||||
String supported_operations_desc() const;
|
String supported_operations_desc() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MultiviewCapabilities {
|
||||||
|
bool is_supported;
|
||||||
|
int32_t max_view_count;
|
||||||
|
int32_t max_instance_count;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
MAX_EXTENSIONS = 128,
|
MAX_EXTENSIONS = 128,
|
||||||
|
@ -75,6 +81,7 @@ private:
|
||||||
uint32_t vulkan_major = 1;
|
uint32_t vulkan_major = 1;
|
||||||
uint32_t vulkan_minor = 0;
|
uint32_t vulkan_minor = 0;
|
||||||
SubgroupCapabilities subgroup_capabilities;
|
SubgroupCapabilities subgroup_capabilities;
|
||||||
|
MultiviewCapabilities multiview_capabilities;
|
||||||
|
|
||||||
String device_vendor;
|
String device_vendor;
|
||||||
String device_name;
|
String device_name;
|
||||||
|
@ -227,6 +234,7 @@ public:
|
||||||
uint32_t get_vulkan_major() const { return vulkan_major; };
|
uint32_t get_vulkan_major() const { return vulkan_major; };
|
||||||
uint32_t get_vulkan_minor() const { return vulkan_minor; };
|
uint32_t get_vulkan_minor() const { return vulkan_minor; };
|
||||||
SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; };
|
SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; };
|
||||||
|
MultiviewCapabilities get_multiview_capabilities() const { return multiview_capabilities; };
|
||||||
|
|
||||||
VkDevice get_device();
|
VkDevice get_device();
|
||||||
VkPhysicalDevice get_physical_device();
|
VkPhysicalDevice get_physical_device();
|
||||||
|
|
|
@ -93,10 +93,14 @@ public:
|
||||||
DeviceFamily device_family = DEVICE_UNKNOWN;
|
DeviceFamily device_family = DEVICE_UNKNOWN;
|
||||||
uint32_t version_major = 1.0;
|
uint32_t version_major = 1.0;
|
||||||
uint32_t version_minor = 0.0;
|
uint32_t version_minor = 0.0;
|
||||||
|
|
||||||
// subgroup capabilities
|
// subgroup capabilities
|
||||||
uint32_t subgroup_size = 0;
|
uint32_t subgroup_size = 0;
|
||||||
uint32_t subgroup_in_shaders = 0; // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
|
uint32_t subgroup_in_shaders = 0; // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
|
||||||
uint32_t subgroup_operations = 0; // Set flags, using SubgroupOperations
|
uint32_t subgroup_operations = 0; // Set flags, using SubgroupOperations
|
||||||
|
|
||||||
|
// features
|
||||||
|
bool supports_multiview = false; // If true this device supports multiview options
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Vector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities);
|
typedef Vector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities);
|
||||||
|
|
Loading…
Reference in a new issue