浏览代码

Add `RenderingServer.get_video_adapter_type()` method

This can be used to distinguish between integrated, dedicated, virtual
and software-emulated GPUs. This in turn can be used to automatically
adjust graphics settings, or warn users about features that may run
slowly on their hardware.
Hugo Locurcio 3 年之前
父节点
当前提交
b3174e7af9

+ 18 - 0
doc/classes/RenderingDevice.xml

@@ -654,6 +654,24 @@
 		</constant>
 		</constant>
 		<constant name="BARRIER_MASK_NO_BARRIER" value="8">
 		<constant name="BARRIER_MASK_NO_BARRIER" value="8">
 		</constant>
 		</constant>
+		<constant name="DEVICE_TYPE_OTHER" value="0" enum="DeviceType">
+			Rendering device type does not match any of the other enum values or is unknown.
+		</constant>
+		<constant name="DEVICE_TYPE_INTEGRATED_GPU" value="1" enum="DeviceType">
+			Rendering device is an integrated GPU, which is typically [i](but not always)[/i] slower than dedicated GPUs ([constant DEVICE_TYPE_DISCRETE_GPU]). On Android and iOS, the rendering device type is always considered to be [constant DEVICE_TYPE_INTEGRATED_GPU].
+		</constant>
+		<constant name="DEVICE_TYPE_DISCRETE_GPU" value="2" enum="DeviceType">
+			Rendering device is a dedicated GPU, which is typically [i](but not always)[/i] faster than integrated GPUs ([constant DEVICE_TYPE_INTEGRATED_GPU]).
+		</constant>
+		<constant name="DEVICE_TYPE_VIRTUAL_GPU" value="3" enum="DeviceType">
+			Rendering device is an emulated GPU in a virtual environment. This is typically much slower than the host GPU, which means the expected performance level on a dedicated GPU will be roughly equivalent to [constant DEVICE_TYPE_INTEGRATED_GPU]. Virtual machine GPU passthrough (such as VFIO) will not report the device type as [constant DEVICE_TYPE_VIRTUAL_GPU]. Instead, the host GPU's device type will be reported as if the GPU was not emulated.
+		</constant>
+		<constant name="DEVICE_TYPE_CPU" value="4" enum="DeviceType">
+			Rendering device is provided by software emulation (such as Lavapipe or [url=https://github.com/google/swiftshader]SwiftShader[/url]). This is the slowest kind of rendering device available; it's typically much slower than [constant DEVICE_TYPE_INTEGRATED_GPU].
+		</constant>
+		<constant name="DEVICE_TYPE_MAX" value="5" enum="DeviceType">
+			Represents the size of the [enum DeviceType] enum.
+		</constant>
 		<constant name="DRIVER_RESOURCE_VULKAN_DEVICE" value="0" enum="DriverResource">
 		<constant name="DRIVER_RESOURCE_VULKAN_DEVICE" value="0" enum="DriverResource">
 		</constant>
 		</constant>
 		<constant name="DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE" value="1" enum="DriverResource">
 		<constant name="DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE" value="1" enum="DriverResource">

+ 7 - 0
doc/classes/RenderingServer.xml

@@ -1232,6 +1232,13 @@
 				[b]Note:[/b] When running a headless or server binary, this function returns an empty string.
 				[b]Note:[/b] When running a headless or server binary, this function returns an empty string.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="get_video_adapter_type" qualifiers="const">
+			<return type="int" enum="RenderingDevice.DeviceType" />
+			<description>
+				Returns the type of the video adapter. Since dedicated graphics cards from a given generation will [i]usually[/i] be significantly faster than integrated graphics made in the same generation, the device type can be used as a basis for automatic graphics settings adjustment. However, this is not always true, so make sure to provide users with a way to manually override graphics settings.
+				[b]Note:[/b] When using the OpenGL backend or when running in headless mode, this function always returns [constant RenderingDevice.DEVICE_TYPE_OTHER].
+			</description>
+		</method>
 		<method name="get_video_adapter_vendor" qualifiers="const">
 		<method name="get_video_adapter_vendor" qualifiers="const">
 			<return type="String" />
 			<return type="String" />
 			<description>
 			<description>

+ 4 - 0
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -4465,6 +4465,10 @@ String RasterizerStorageGLES3::get_video_adapter_vendor() const {
 	return (const char *)glGetString(GL_VENDOR);
 	return (const char *)glGetString(GL_VENDOR);
 }
 }
 
 
+RenderingDevice::DeviceType RasterizerStorageGLES3::get_video_adapter_type() const {
+	return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER;
+}
+
 void RasterizerStorageGLES3::initialize() {
 void RasterizerStorageGLES3::initialize() {
 	RasterizerStorageGLES3::system_fbo = 0;
 	RasterizerStorageGLES3::system_fbo = 0;
 
 

+ 1 - 0
drivers/gles3/rasterizer_storage_gles3.h

@@ -1361,6 +1361,7 @@ public:
 	//	int get_render_info(RS::RenderInfo p_info) override;
 	//	int get_render_info(RS::RenderInfo p_info) override;
 	String get_video_adapter_name() const override;
 	String get_video_adapter_name() const override;
 	String get_video_adapter_vendor() const override;
 	String get_video_adapter_vendor() const override;
+	RenderingDevice::DeviceType get_video_adapter_type() const override;
 
 
 	void capture_timestamps_begin() override {}
 	void capture_timestamps_begin() override {}
 	void capture_timestamp(const String &p_name) override {}
 	void capture_timestamp(const String &p_name) override {}

+ 5 - 0
drivers/vulkan/rendering_device_vulkan.cpp

@@ -8525,6 +8525,11 @@ String RenderingDeviceVulkan::get_device_vendor_name() const {
 String RenderingDeviceVulkan::get_device_name() const {
 String RenderingDeviceVulkan::get_device_name() const {
 	return context->get_device_name();
 	return context->get_device_name();
 }
 }
+
+RenderingDevice::DeviceType RenderingDeviceVulkan::get_device_type() const {
+	return context->get_device_type();
+}
+
 String RenderingDeviceVulkan::get_device_pipeline_cache_uuid() const {
 String RenderingDeviceVulkan::get_device_pipeline_cache_uuid() const {
 	return context->get_device_pipeline_cache_uuid();
 	return context->get_device_pipeline_cache_uuid();
 }
 }

+ 1 - 0
drivers/vulkan/rendering_device_vulkan.h

@@ -1225,6 +1225,7 @@ public:
 
 
 	virtual String get_device_vendor_name() const;
 	virtual String get_device_vendor_name() const;
 	virtual String get_device_name() const;
 	virtual String get_device_name() const;
+	virtual RenderingDevice::DeviceType get_device_type() const;
 	virtual String get_device_pipeline_cache_uuid() const;
 	virtual String get_device_pipeline_cache_uuid() const;
 
 
 	virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0);
 	virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0);

+ 6 - 0
drivers/vulkan/vulkan_context.cpp

@@ -762,6 +762,7 @@ Error VulkanContext::_create_physical_device() {
 		{ 0, nullptr },
 		{ 0, nullptr },
 	};
 	};
 	device_name = gpu_props.deviceName;
 	device_name = gpu_props.deviceName;
+	device_type = gpu_props.deviceType;
 	pipeline_cache_id = String::hex_encode_buffer(gpu_props.pipelineCacheUUID, VK_UUID_SIZE);
 	pipeline_cache_id = String::hex_encode_buffer(gpu_props.pipelineCacheUUID, VK_UUID_SIZE);
 	pipeline_cache_id += "-driver-" + itos(gpu_props.driverVersion);
 	pipeline_cache_id += "-driver-" + itos(gpu_props.driverVersion);
 	{
 	{
@@ -2210,6 +2211,11 @@ String VulkanContext::get_device_vendor_name() const {
 String VulkanContext::get_device_name() const {
 String VulkanContext::get_device_name() const {
 	return device_name;
 	return device_name;
 }
 }
+
+RenderingDevice::DeviceType VulkanContext::get_device_type() const {
+	return RenderingDevice::DeviceType(device_type);
+}
+
 String VulkanContext::get_device_pipeline_cache_uuid() const {
 String VulkanContext::get_device_pipeline_cache_uuid() const {
 	return pipeline_cache_id;
 	return pipeline_cache_id;
 }
 }

+ 3 - 0
drivers/vulkan/vulkan_context.h

@@ -37,6 +37,7 @@
 #include "core/templates/map.h"
 #include "core/templates/map.h"
 #include "core/templates/rid_owner.h"
 #include "core/templates/rid_owner.h"
 #include "servers/display_server.h"
 #include "servers/display_server.h"
+#include "servers/rendering/rendering_device.h"
 
 
 #ifdef USE_VOLK
 #ifdef USE_VOLK
 #include <volk.h>
 #include <volk.h>
@@ -101,6 +102,7 @@ private:
 
 
 	String device_vendor;
 	String device_vendor;
 	String device_name;
 	String device_name;
+	VkPhysicalDeviceType device_type;
 	String pipeline_cache_id;
 	String pipeline_cache_id;
 	uint32_t device_api_version = 0;
 	uint32_t device_api_version = 0;
 
 
@@ -290,6 +292,7 @@ public:
 
 
 	String get_device_vendor_name() const;
 	String get_device_vendor_name() const;
 	String get_device_name() const;
 	String get_device_name() const;
+	RenderingDevice::DeviceType get_device_type() const;
 	String get_device_pipeline_cache_uuid() const;
 	String get_device_pipeline_cache_uuid() const;
 
 
 	void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode);
 	void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode);

+ 1 - 0
servers/rendering/rasterizer_dummy.h

@@ -700,6 +700,7 @@ public:
 
 
 	String get_video_adapter_name() const override { return String(); }
 	String get_video_adapter_name() const override { return String(); }
 	String get_video_adapter_vendor() const override { return String(); }
 	String get_video_adapter_vendor() const override { return String(); }
+	RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
 
 
 	static RendererStorage *base_singleton;
 	static RendererStorage *base_singleton;
 
 

+ 5 - 0
servers/rendering/renderer_rd/renderer_storage_rd.cpp

@@ -9529,10 +9529,15 @@ uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) {
 String RendererStorageRD::get_video_adapter_name() const {
 String RendererStorageRD::get_video_adapter_name() const {
 	return RenderingDevice::get_singleton()->get_device_name();
 	return RenderingDevice::get_singleton()->get_device_name();
 }
 }
+
 String RendererStorageRD::get_video_adapter_vendor() const {
 String RendererStorageRD::get_video_adapter_vendor() const {
 	return RenderingDevice::get_singleton()->get_device_vendor_name();
 	return RenderingDevice::get_singleton()->get_device_vendor_name();
 }
 }
 
 
+RenderingDevice::DeviceType RendererStorageRD::get_video_adapter_type() const {
+	return RenderingDevice::get_singleton()->get_device_type();
+}
+
 RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
 RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
 
 
 RendererStorageRD::RendererStorageRD() {
 RendererStorageRD::RendererStorageRD() {

+ 1 - 0
servers/rendering/renderer_rd/renderer_storage_rd.h

@@ -2393,6 +2393,7 @@ public:
 
 
 	String get_video_adapter_name() const;
 	String get_video_adapter_name() const;
 	String get_video_adapter_vendor() const;
 	String get_video_adapter_vendor() const;
+	RenderingDevice::DeviceType get_video_adapter_type() const;
 
 
 	virtual void capture_timestamps_begin();
 	virtual void capture_timestamps_begin();
 	virtual void capture_timestamp(const String &p_name);
 	virtual void capture_timestamp(const String &p_name);

+ 1 - 0
servers/rendering/renderer_storage.h

@@ -620,6 +620,7 @@ public:
 	virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0;
 	virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0;
 	virtual String get_video_adapter_name() const = 0;
 	virtual String get_video_adapter_name() const = 0;
 	virtual String get_video_adapter_vendor() const = 0;
 	virtual String get_video_adapter_vendor() const = 0;
+	virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
 
 
 	static RendererStorage *base_singleton;
 	static RendererStorage *base_singleton;
 
 

+ 7 - 0
servers/rendering/rendering_device.cpp

@@ -490,6 +490,13 @@ void RenderingDevice::_bind_methods() {
 	BIND_CONSTANT(BARRIER_MASK_ALL);
 	BIND_CONSTANT(BARRIER_MASK_ALL);
 	BIND_CONSTANT(BARRIER_MASK_NO_BARRIER);
 	BIND_CONSTANT(BARRIER_MASK_NO_BARRIER);
 
 
+	BIND_ENUM_CONSTANT(DEVICE_TYPE_OTHER);
+	BIND_ENUM_CONSTANT(DEVICE_TYPE_INTEGRATED_GPU);
+	BIND_ENUM_CONSTANT(DEVICE_TYPE_DISCRETE_GPU);
+	BIND_ENUM_CONSTANT(DEVICE_TYPE_VIRTUAL_GPU);
+	BIND_ENUM_CONSTANT(DEVICE_TYPE_CPU);
+	BIND_ENUM_CONSTANT(DEVICE_TYPE_MAX);
+
 	BIND_ENUM_CONSTANT(DRIVER_RESOURCE_VULKAN_DEVICE);
 	BIND_ENUM_CONSTANT(DRIVER_RESOURCE_VULKAN_DEVICE);
 	BIND_ENUM_CONSTANT(DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE);
 	BIND_ENUM_CONSTANT(DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE);
 	BIND_ENUM_CONSTANT(DRIVER_RESOURCE_VULKAN_INSTANCE);
 	BIND_ENUM_CONSTANT(DRIVER_RESOURCE_VULKAN_INSTANCE);

+ 13 - 0
servers/rendering/rendering_device.h

@@ -60,6 +60,17 @@ public:
 		DEVICE_DIRECTX
 		DEVICE_DIRECTX
 	};
 	};
 
 
+	// This enum matches VkPhysicalDeviceType (except for `DEVICE_TYPE_MAX`).
+	// Unlike VkPhysicalDeviceType, DeviceType is exposed to the scripting API.
+	enum DeviceType {
+		DEVICE_TYPE_OTHER,
+		DEVICE_TYPE_INTEGRATED_GPU,
+		DEVICE_TYPE_DISCRETE_GPU,
+		DEVICE_TYPE_VIRTUAL_GPU,
+		DEVICE_TYPE_CPU,
+		DEVICE_TYPE_MAX,
+	};
+
 	enum DriverResource {
 	enum DriverResource {
 		DRIVER_RESOURCE_VULKAN_DEVICE = 0,
 		DRIVER_RESOURCE_VULKAN_DEVICE = 0,
 		DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE,
 		DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE,
@@ -1199,6 +1210,7 @@ public:
 
 
 	virtual String get_device_vendor_name() const = 0;
 	virtual String get_device_vendor_name() const = 0;
 	virtual String get_device_name() const = 0;
 	virtual String get_device_name() const = 0;
+	virtual RenderingDevice::DeviceType get_device_type() const = 0;
 	virtual String get_device_pipeline_cache_uuid() const = 0;
 	virtual String get_device_pipeline_cache_uuid() const = 0;
 
 
 	virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0) = 0;
 	virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0) = 0;
@@ -1237,6 +1249,7 @@ protected:
 	Vector<int64_t> _draw_list_switch_to_next_pass_split(uint32_t p_splits);
 	Vector<int64_t> _draw_list_switch_to_next_pass_split(uint32_t p_splits);
 };
 };
 
 
+VARIANT_ENUM_CAST(RenderingDevice::DeviceType)
 VARIANT_ENUM_CAST(RenderingDevice::DriverResource)
 VARIANT_ENUM_CAST(RenderingDevice::DriverResource)
 VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
 VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
 VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)
 VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)

+ 4 - 0
servers/rendering/rendering_server_default.cpp

@@ -255,6 +255,10 @@ String RenderingServerDefault::get_video_adapter_vendor() const {
 	return RSG::storage->get_video_adapter_vendor();
 	return RSG::storage->get_video_adapter_vendor();
 }
 }
 
 
+RenderingDevice::DeviceType RenderingServerDefault::get_video_adapter_type() const {
+	return RSG::storage->get_video_adapter_type();
+}
+
 void RenderingServerDefault::set_frame_profiling_enabled(bool p_enable) {
 void RenderingServerDefault::set_frame_profiling_enabled(bool p_enable) {
 	RSG::storage->capturing_timestamps = p_enable;
 	RSG::storage->capturing_timestamps = p_enable;
 }
 }

+ 1 - 0
servers/rendering/rendering_server_default.h

@@ -891,6 +891,7 @@ public:
 	virtual uint64_t get_rendering_info(RenderingInfo p_info) override;
 	virtual uint64_t get_rendering_info(RenderingInfo p_info) override;
 	virtual String get_video_adapter_name() const override;
 	virtual String get_video_adapter_name() const override;
 	virtual String get_video_adapter_vendor() const override;
 	virtual String get_video_adapter_vendor() const override;
+	virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
 
 
 	virtual void set_frame_profiling_enabled(bool p_enable) override;
 	virtual void set_frame_profiling_enabled(bool p_enable) override;
 	virtual Vector<FrameProfileArea> get_frame_profile() override;
 	virtual Vector<FrameProfileArea> get_frame_profile() override;

+ 1 - 0
servers/rendering_server.cpp

@@ -2711,6 +2711,7 @@ void RenderingServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_rendering_info", "info"), &RenderingServer::get_rendering_info);
 	ClassDB::bind_method(D_METHOD("get_rendering_info", "info"), &RenderingServer::get_rendering_info);
 	ClassDB::bind_method(D_METHOD("get_video_adapter_name"), &RenderingServer::get_video_adapter_name);
 	ClassDB::bind_method(D_METHOD("get_video_adapter_name"), &RenderingServer::get_video_adapter_name);
 	ClassDB::bind_method(D_METHOD("get_video_adapter_vendor"), &RenderingServer::get_video_adapter_vendor);
 	ClassDB::bind_method(D_METHOD("get_video_adapter_vendor"), &RenderingServer::get_video_adapter_vendor);
+	ClassDB::bind_method(D_METHOD("get_video_adapter_type"), &RenderingServer::get_video_adapter_type);
 
 
 	ClassDB::bind_method(D_METHOD("make_sphere_mesh", "latitudes", "longitudes", "radius"), &RenderingServer::make_sphere_mesh);
 	ClassDB::bind_method(D_METHOD("make_sphere_mesh", "latitudes", "longitudes", "radius"), &RenderingServer::make_sphere_mesh);
 	ClassDB::bind_method(D_METHOD("get_test_cube"), &RenderingServer::get_test_cube);
 	ClassDB::bind_method(D_METHOD("get_test_cube"), &RenderingServer::get_test_cube);

+ 1 - 0
servers/rendering_server.h

@@ -1473,6 +1473,7 @@ public:
 	virtual uint64_t get_rendering_info(RenderingInfo p_info) = 0;
 	virtual uint64_t get_rendering_info(RenderingInfo p_info) = 0;
 	virtual String get_video_adapter_name() const = 0;
 	virtual String get_video_adapter_name() const = 0;
 	virtual String get_video_adapter_vendor() const = 0;
 	virtual String get_video_adapter_vendor() const = 0;
+	virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
 
 
 	struct FrameProfileArea {
 	struct FrameProfileArea {
 		String name;
 		String name;