Skip to content

Commit

Permalink
OpenGL: Added option to control desired adapter type in OpenGL (close #…
Browse files Browse the repository at this point in the history
  • Loading branch information
MikhailGorobets committed Jan 10, 2024
1 parent 1210c85 commit c7425fd
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Graphics/GraphicsEngine/interface/GraphicsTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions Graphics/GraphicsEngineOpenGL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,11 @@ set_source_files_properties(
readme.md PROPERTIES HEADER_FILE_ONLY TRUE
)

add_library(Diligent-GLAdapterSelector OBJECT "src/GLAdapterSelector.cpp")
set_target_properties(Diligent-GLAdapterSelector PROPERTIES FOLDER DiligentCore/Graphics)

if(DILIGENT_INSTALL_CORE)
install_core_lib(Diligent-GraphicsEngineOpenGL-shared)
install_core_lib(Diligent-GraphicsEngineOpenGL-static)
install_core_lib(Diligent-GLAdapterSelector)
endif()
24 changes: 24 additions & 0 deletions Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,28 @@ 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
const HMODULE ModuleHandle = GetModuleHandle(nullptr);
Uint64* const NvOptimusEnablement = reinterpret_cast<Uint64*>(GetProcAddress(ModuleHandle, "NvOptimusEnablement"));
Uint64* const AmdPowerXpressRequestHighPerformance = reinterpret_cast<Uint64*>(GetProcAddress(ModuleHandle, "AmdPowerXpressRequestHighPerformance"));
if (!NvOptimusEnablement && !AmdPowerXpressRequestHighPerformance)
LOG_WARNING_MESSAGE("Nither NvOptimusEnablement nor AmdPowerXpressRequestHighPerformance symbols found");
if (AmdPowerXpressRequestHighPerformance)
*AmdPowerXpressRequestHighPerformance = IsEnableDedicatedGPU;
if (NvOptimusEnablement)
*NvOptimusEnablement = IsEnableDedicatedGPU;
#elif PLAtTFORM_LINUX
setenv("DRI_PRIME", IsEnableDedicatedGPU ? "1" : "0", 1);
#else
(void)IsEnableDedicatedGPU;
if (EngineCI.PreferredAdapterType != ADAPTER_TYPE_UNKNOWN)
LOG_WARNING_MESSAGE("Setting preferred adapter type isn't supported on this platform");
#endif
}

void EngineFactoryOpenGLImpl::EnumerateAdapters(Version MinVersion,
Uint32& NumAdapters,
GraphicsAdapterInfo* Adapters) const
Expand Down Expand Up @@ -205,6 +227,7 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInf
SetRawAllocator(EngineCI.pRawMemAllocator);
auto& RawMemAllocator = GetRawAllocator();

SetPreferredAdapter(EngineCI);
RenderDeviceGLImpl* pRenderDeviceOpenGL{
NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(
RawMemAllocator, this, EngineCI, &SCDesc //
Expand Down Expand Up @@ -303,6 +326,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 //
Expand Down
19 changes: 19 additions & 0 deletions Graphics/GraphicsEngineOpenGL/src/GLAdapterSelector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <cinttypes>

#if PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS
# define DILIGENT_INTERFACE_EXPORT __declspec(dllexport)
#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
__declspec(dllexport) uint64_t AmdPowerXpressRequestHighPerformance = 0x0;

/// http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf
__declspec(dllexport) uint64_t NvOptimusEnablement = 0x0;
}

0 comments on commit c7425fd

Please sign in to comment.