diff options
| author | Bastiaan Olij <mux213@gmail.com> | 2021-05-04 15:30:21 +1000 | 
|---|---|---|
| committer | Bastiaan Olij <mux213@gmail.com> | 2021-05-06 12:06:07 +1000 | 
| commit | 90ef5d73c495e82fde390308194cf622a45039e4 (patch) | |
| tree | 0815088881673181b73e586db3814605ed128657 | |
| parent | 758bccf364729474f8ffbcf15a0bb6e9bad02d9c (diff) | |
Cleanup vulkan capabilities check and add multiview check
| -rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 4 | ||||
| -rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 94 | ||||
| -rw-r--r-- | drivers/vulkan/vulkan_context.h | 8 | ||||
| -rw-r--r-- | servers/rendering/rendering_device.h | 4 | 
4 files changed, 93 insertions, 17 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 30cc01fd10..43b2a24172 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -7844,6 +7844,10 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de  		device_capabilities.subgroup_size = subgroup_capabilities.size;  		device_capabilities.subgroup_in_shaders = subgroup_capabilities.supported_stages_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; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 0a8a5c746f..12a67c0e07 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -352,8 +352,6 @@ Error VulkanContext::_initialize_extensions() {  	return OK;  } -typedef void(VKAPI_PTR *_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice, VkPhysicalDeviceProperties2 *); -  uint32_t VulkanContext::SubgroupCapabilities::supported_stages_flags_rd() const {  	uint32_t flags = 0; @@ -496,20 +494,70 @@ String VulkanContext::SubgroupCapabilities::supported_operations_desc() const {  }  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 +  	// 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; +		VkPhysicalDeviceProperties2 physicalDeviceProperties; +  		subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;  		subgroupProperties.pNext = nullptr; -		VkPhysicalDeviceProperties2 physicalDeviceProperties;  		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.supportedStages = subgroupProperties.supportedStages; @@ -519,18 +567,30 @@ Error VulkanContext::_check_capabilities() {  		// - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT  		subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages; -		// only output this when debugging? -		print_line("- Vulkan subgroup size " + itos(subgroup_capabilities.size)); -		print_line("- Vulkan subgroup stages " + subgroup_capabilities.supported_stages_desc()); -		print_line("- Vulkan subgroup supported ops " + subgroup_capabilities.supported_operations_desc()); +		if (multiview_capabilities.is_supported) { +			multiview_capabilities.max_view_count = multiviewProperties.maxMultiviewViewCount; +			multiview_capabilities.max_instance_count = multiviewProperties.maxMultiviewInstanceIndex; + +#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) { -			print_line("- Vulkan subgroup quad operations in all stages"); +			print_line("  quad operations in all stages");  		}  	} else { -		subgroup_capabilities.size = 0; -		subgroup_capabilities.supportedStages = 0; -		subgroup_capabilities.supportedOperations = 0; -		subgroup_capabilities.quadOperationsInAllStages = false; +		print_line("- Couldn't call vkGetPhysicalDeviceProperties2"); +#endif  	}  	return OK; diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 88e4f26bb1..3d9b295c5a 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -54,6 +54,12 @@ public:  		String supported_operations_desc() const;  	}; +	struct MultiviewCapabilities { +		bool is_supported; +		int32_t max_view_count; +		int32_t max_instance_count; +	}; +  private:  	enum {  		MAX_EXTENSIONS = 128, @@ -75,6 +81,7 @@ private:  	uint32_t vulkan_major = 1;  	uint32_t vulkan_minor = 0;  	SubgroupCapabilities subgroup_capabilities; +	MultiviewCapabilities multiview_capabilities;  	String device_vendor;  	String device_name; @@ -227,6 +234,7 @@ public:  	uint32_t get_vulkan_major() const { return vulkan_major; };  	uint32_t get_vulkan_minor() const { return vulkan_minor; };  	SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; }; +	MultiviewCapabilities get_multiview_capabilities() const { return multiview_capabilities; };  	VkDevice get_device();  	VkPhysicalDevice get_physical_device(); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 2de0549e8d..d86c44a206 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -93,10 +93,14 @@ public:  		DeviceFamily device_family = DEVICE_UNKNOWN;  		uint32_t version_major = 1.0;  		uint32_t version_minor = 0.0; +  		// subgroup capabilities  		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_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);  |