From 634a52e29654751c294b85d1ec54f893796d79d9 Mon Sep 17 00:00:00 2001 From: Mikhail Gorobets Date: Wed, 10 Jan 2024 06:37:11 +0600 Subject: [PATCH] OpenGL: Add option to control desired adapter type in OpenGL (close #450) --- .../GraphicsEngine/interface/GraphicsTypes.h | 6 ++++ .../src/EngineFactoryOpenGL.cpp | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 605ec6199b..1a386ddbae 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -3485,6 +3485,12 @@ struct EngineGLCreateInfo DILIGENT_DERIVE(EngineCreateInfo) /// Use IRenderDevice::GetDeviceInfo().NDC to get current NDC. Bool ZeroToOneNDZ DEFAULT_INITIALIZER(false); + /// The GPU preference allows you to request either the integrated or dedicated GPU + /// on systems having both onboard and dedicated GPUs. Currently this works only on Windows and Linux + /// - On Windows this is done by setting the `NvOptimusEnablement` and `AmdPowerXpressRequestHighPerformance` + /// - On Linux this affects the `DRI_PRIME` environment variable that's used by Mesa drivers that support PRIME. + ADAPTER_TYPE PreferredAdapterType DEFAULT_INITIALIZER(ADAPTER_TYPE_UNKNOWN); + #if PLATFORM_EMSCRIPTEN /// WebGL context attributes. WebGLContextAttribs WebGLAttribs; diff --git a/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp index 06d1e5575b..7bb8c482f7 100644 --- a/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp @@ -58,6 +58,24 @@ # include "RenderDeviceGLESImpl.hpp" #endif +#if PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS +# define DILIGENT_INTERFACE_EXPORT +#elif PLATFORM_LINUX +# define DILIGENT_INTERFACE_EXPORT __attribute__((visibility("default"))) +#else +# define DILIGENT_INTERFACE_EXPORT +#endif + +/// Let the NVIDIA and AMD know we want to use their graphics card on a dual graphics card system. +extern "C" +{ + /// https://community.amd.com/thread/169965 + DILIGENT_INTERFACE_EXPORT uint64_t AmdPowerXpressRequestHighPerformance = 0x0; + + /// http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf + DILIGENT_INTERFACE_EXPORT uint64_t NvOptimusEnablement = 0x0; +} + namespace Diligent { @@ -137,6 +155,20 @@ static void SetDefaultGraphicsAdapterInfo(GraphicsAdapterInfo& AdapterInfo) AdapterInfo.Queues[0].TextureCopyGranularity[2] = 1; } +static void SetPreferredAdapter(const EngineGLCreateInfo& EngineCI) +{ + bool IsEnableDedicatedGPU = EngineCI.PreferredAdapterType == ADAPTER_TYPE_DISCRETE; +#if PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS + AmdPowerXpressRequestHighPerformance = IsEnableDedicatedGPU; + NvOptimusEnablement = IsEnableDedicatedGPU; +#elif PLAtTFORM_LINUX + setenv("DRI_PRIME", IsEnableDedicatedGPU ? "1" : "0", 1); +#else + if (EngineCI.PreferredAdapterType != ADAPTER_TYPE_UNKNOWN) + LOG_WARNING_MESSAGE("Setting prefered adapter type isn't supported on this platform") +#endif +} + void EngineFactoryOpenGLImpl::EnumerateAdapters(Version MinVersion, Uint32& NumAdapters, GraphicsAdapterInfo* Adapters) const @@ -303,6 +335,7 @@ void EngineFactoryOpenGLImpl::AttachToActiveGLContext(const EngineGLCreateInfo& SetRawAllocator(EngineCI.pRawMemAllocator); auto& RawMemAllocator = GetRawAllocator(); + SetPreferredAdapter(EngineCI); RenderDeviceGLImpl* pRenderDeviceOpenGL{ NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)( RawMemAllocator, this, EngineCI //