Skip to content

Commit

Permalink
Remove OpenGL, use DirectX instead
Browse files Browse the repository at this point in the history
  • Loading branch information
thompsonnoahe committed Aug 4, 2024
1 parent ab171b7 commit cd21d7e
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 51 deletions.
8 changes: 2 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ project(com.nthompson.gpu VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 20)

find_package(CUDAToolkit)
find_package(GLEW CONFIG REQUIRED)
find_package(glfw3 CONFIG REQUIRED)
find_package(OpenGL)

include("Src/ThirdParty/StreamDeckSDK.cmake")

Expand All @@ -31,7 +28,6 @@ target_include_directories(gpu PUBLIC Src/ThirdParty/Amd)

add_library(adlx STATIC ${THIRD_PARTY_AMD_INCLUDE} ${THIRD_PARTY_AMD_SRC} ${THIRD_PARTY_AMD_SRC_WIN})

target_link_libraries(gpu PRIVATE StreamDeckSDK CUDA::nvml adlx OpenGL::GL glfw GLEW::GLEW)

install(FILES Src/com.nthompson.gpu.sdPlugin/manifest.json DESTINATION Release)
target_link_libraries(gpu PRIVATE StreamDeckSDK CUDA::nvml adlx d3d12.lib dxgi.lib)

set_property(TARGET gpu PROPERTY LINK_FLAGS "/DELAYLOAD:nvml.dll")
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![GPU Utilization Icon](Src/com.nthompson.gpu.sdPlugin/defaultImage.png)


# Stream Deck GPU Utilization Plugin 📈
# Stream Deck GPU Utilization Plugin 📈

A plugin for monitoring the utilization of your GPU on the Elgato Stream Deck. Windows only.

Expand Down Expand Up @@ -39,4 +39,6 @@ Finally, repeat the steps you performed for GLEW to install [GLFW](https://www.g
And presto! You should be good to go.


![GPU Utilization Icon](Src/com.nthompson.gpu.sdPlugin/previews/Preview2.png)
![GPU Utilization Icon](Src/com.nthompson.gpu.sdPlugin/previews/Preview2.png)

<a href="https://buymeacoffee.com/thompsonnoahe" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
86 changes: 59 additions & 27 deletions Src/GpuPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
#include "GpuPlugin.h"

namespace nthompson {
// Convert a wide Unicode string to an UTF8 string
std::string ConvToString(const std::wstring &wStr)
{
if(wStr.empty()) return {};
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wStr[0], (int)wStr.size(), nullptr, 0, nullptr, nullptr);
std::string strTo(sizeNeeded, 0);
WideCharToMultiByte(CP_UTF8, 0, &wStr[0], (int)wStr.size(), &strTo[0], sizeNeeded, nullptr, nullptr);
return strTo;
}

void Timer::Start(int32_t interval, const std::function<void()>& func) {
if (running_) return;
running_ = true;
Expand All @@ -25,41 +35,48 @@ namespace nthompson {
}

GpuPlugin::GpuPlugin() {
if (!glfwInit()) {
ESDLog("Failed to init GLFW3");
IDXGIFactory* factory = nullptr;

HRESULT result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);

if (FAILED(result)) {
ESDLog("Failed to create factory object.");
return;
}

glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
std::string amd = "amd", advancedMicroDevices = "advanced micro devices", nvidia = "nvidia";

GLFWwindow* context = glfwCreateWindow(1, 1, "", nullptr, nullptr);
UINT index = 0;
IDXGIAdapter* adapter = nullptr;

glfwMakeContextCurrent(context);
nlohmann::json payload;

GLenum status = glewInit();
while (factory->EnumAdapters(index, &adapter) != DXGI_ERROR_NOT_FOUND) {
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
std::wstring wDescription = desc.Description;

if (status != GLEW_OK) {
ESDLog("Failed to init GLEW");
}
std::string description = ConvToString(wDescription);

std::string amd = "amd", advancedMicroDevices = "advanced micro devices", nvidia = "nvidia";
std::string gpuVendor = reinterpret_cast<const char* const>(glGetString(GL_VENDOR));
std::transform(description.begin(), description.end(), description.begin(),
[](char c) { return std::tolower(c); });

// Transform to lowercase
std::transform(gpuVendor.begin(), gpuVendor.end(), gpuVendor.begin(), [](unsigned char c) {
return std::tolower(c);
});
if (description.find(nvidia) != std::string::npos) {
usage_ = std::make_unique<NvidiaGpuUsage>();
break;
}
else if (description.find(amd) != std::string::npos || description.find(advancedMicroDevices) != std::string::npos) {
usage_ = std::make_unique<AmdGpuUsage>();
break;
} else {
ESDLog("Found unsupported display adapter");
usage_ = nullptr;
}

if (gpuVendor.find(amd) != std::string::npos || gpuVendor.find(advancedMicroDevices) != std::string::npos) {
usage_ = std::make_unique<AmdGpuUsage>();
}
else if (gpuVendor.find(nvidia) != std::string::npos) {
usage_ = std::make_unique<NvidiaGpuUsage>();
}
else {
ESDLog("Unsupported GPU.");
return;
++index;
}


timer_ = std::make_unique<Timer>();

timer_->Start(1000, [this]() {
Expand All @@ -71,10 +88,19 @@ namespace nthompson {
void GpuPlugin::Update() {
if (mConnectionManager == nullptr) return;
std::scoped_lock<std::mutex> lock(mutex_);
uint32_t utilization = usage_->GetGpuUsage();
for (const std::string& context : contexts_) {
mConnectionManager->SetTitle(std::to_string(utilization) + "%", context, kESDSDKTarget_HardwareAndSoftware);

if (usage_ == nullptr) {
SetActionText("?");
return;
}

uint32_t utilization = usage_->GetGpuUsage();

std::stringstream stream;
stream << std::to_string(utilization) << "%";

SetActionText(stream.str());

}

GpuPlugin::~GpuPlugin() {
Expand All @@ -93,4 +119,10 @@ namespace nthompson {
contexts_.erase(inContext);
}

void GpuPlugin::SetActionText(std::string text) {
for (const std::string& context : contexts_) {
mConnectionManager->SetTitle(text, context, kESDSDKTarget_HardwareAndSoftware);
}
}

}
8 changes: 4 additions & 4 deletions Src/GpuPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
#include <thread>
#include <mutex>
#include <set>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <GL/gl.h>
#include <dxgi.h>
#include <algorithm>
#include <functional>
#include "Windows/Nvidia/NvidiaGpuUsage.h"
Expand All @@ -37,6 +35,8 @@ namespace nthompson {

void Update();

void SetActionText(std::string text);

void WillAppearForAction(const std::string& inAction,
const std::string& inContext,
const nlohmann::json& inPayload,
Expand All @@ -48,7 +48,7 @@ namespace nthompson {
const nlohmann::json& inPayload,
const std::string& inDeviceID) override;
private:
std::unique_ptr<IGpuUsage> usage_;
std::unique_ptr<IGpuUsage> usage_ = nullptr;
std::unique_ptr<Timer> timer_;
std::mutex mutex_;
std::set<std::string> contexts_;
Expand Down
24 changes: 12 additions & 12 deletions Src/com.nthompson.gpu.sdPlugin/manifest.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"Actions": [
{
"Icon": "icon",
"Icon": "icon",
"Name": "GPU",
"States": [
{
"Image": "defaultImage",
"TitleAlignment": "middle",
"TitleAlignment": "middle",
"FontSize": "12"
}
],
],
"SupportedInMultiActions": false,
"Tooltip": "This action displays the GPU usage",
"UUID": "com.nthompson.gpu.gpu"
}
],
],
"SDKVersion": 2,
"Author": "Noah Thompson",
"CodePathWin": "gpu.exe",
Expand All @@ -23,16 +23,16 @@
"Description": "Displays the current GPU usage.",
"Name": "GPU",
"Icon": "pluginIcon",
"Version": "1.1.0",
"Version": "1.1.1",
"URL": "https://github.com/thompsonnoahe/StreamDeckGpu",
"OS": [
{
"Platform": "windows",
"MinimumVersion" : "10"
"Platform": "windows",
"MinimumVersion" : "10"
}
],
"Software":
{
"MinimumVersion" : "4.1"
}
}
"Software":
{
"MinimumVersion" : "4.1"
}
}

0 comments on commit cd21d7e

Please sign in to comment.