Skip to content

Commit

Permalink
Merge pull request #11 from thompsonnoahe/users/nthompson/amd-fix
Browse files Browse the repository at this point in the history
Fixes for AMD systems
  • Loading branch information
thompsonnoahe authored Jan 6, 2025
2 parents 5993c8e + 9467ddf commit 0773586
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Src/GpuAbstraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace nthompson {
GpuVendor vendor;
std::string name;
uint32_t index;
UINT deviceId;
std::string deviceId;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Gpu, vendor, name, index, deviceId);
Expand Down
39 changes: 25 additions & 14 deletions Src/GpuPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace nthompson {
if (running_) return;
running_ = true;
thread_ = std::thread([this, interval, func]() {
// Place the lock here (not in the loop, or high CPU usage will occur!)
std::scoped_lock<std::mutex> lock(mutex_);
while (running_) {
func();
Expand Down Expand Up @@ -60,13 +61,15 @@ namespace nthompson {

GpuPlugin::~GpuPlugin() {
timer_->Stop();
usage_->Shutdown();
}

void GpuPlugin::WillAppearForAction(const std::string &inAction, const std::string &inContext,
const nlohmann::json &inPayload, const std::string &inDeviceID) {
std::scoped_lock<std::mutex> lock(mutex_);
contexts_.insert(inContext);

// When the action appears, handle receiving settings
if (inPayload.contains("settings")) {
Gpu gpu = inPayload["settings"]["gpuInfo"];
HandleSelectedGpu(gpu);
Expand All @@ -86,6 +89,10 @@ namespace nthompson {
}

void GpuPlugin::FindAvailableGpus() {
// Use DirectX to find the GPUs
// This is so we don't load the nvml.dll on an AMD system (would cause a crash due to missing DLL)
// Or vice versa for AMD's ADLX library

IDXGIFactory1* factory = nullptr;
winrt::com_ptr<IDXCoreAdapterFactory> coreFactory;

Expand All @@ -106,7 +113,6 @@ namespace nthompson {
UINT index = 0;
IDXGIAdapter1* adapter = nullptr;
winrt::com_ptr<IDXCoreAdapter> coreAdapter = nullptr;

uint32_t nvidiaGpuCount = 0, amdGpuCount = 0;

while (factory->EnumAdapters1(index, &adapter) != DXGI_ERROR_NOT_FOUND) {
Expand All @@ -115,7 +121,6 @@ namespace nthompson {
std::wstring wDescription = desc.Description;

std::string description = ConvToString(wDescription);
std::string gpuName = description;

std::transform(description.begin(), description.end(), description.begin(),
[](char c) { return std::tolower(c); });
Expand Down Expand Up @@ -165,22 +170,10 @@ namespace nthompson {
continue;
}

std::pair<UINT, Gpu> item;

item.first = desc.DeviceId;

if (description.find(nvidia) != std::string::npos) {
item.second = {GpuVendor::Nvidia, gpuName, nvidiaGpuCount, item.first};
gpus_.insert(item);
std::string gpuLog = gpuName + " found";
ESDLog(gpuLog);
nvidiaGpuCount++;
}
else if (description.find(amd) != std::string::npos || description.find(advancedMicroDevices) != std::string::npos) {
item.second = {GpuVendor::Amd, gpuName, amdGpuCount, item.first};
gpus_.insert(item);
std::string gpuLog = gpuName + " found";
ESDLog(gpuLog);
amdGpuCount++;
} else {
ESDLog("Found unsupported display adapter");
Expand All @@ -191,22 +184,38 @@ namespace nthompson {
adapter->Release();
}
factory->Release();


// If we do find some NVIDIA gpus, it's safe to load NVML
if (nvidiaGpuCount > 0) {
std::vector<Gpu> nvidiaGpus = NvidiaGpuUsage::GetGpus();
gpus_.insert(gpus_.end(), nvidiaGpus.begin(), nvidiaGpus.end());
}

// Same goes for AMD
if (amdGpuCount > 0) {
std::vector<Gpu> amdGpus = AmdGpuUsage::GetGpus();
gpus_.insert(gpus_.end(), amdGpus.begin(), amdGpus.end());
}
}

void
GpuPlugin::SendToPlugin(const std::string &inAction, const std::string &inContext, const nlohmann::json &inPayload,
const std::string &inDeviceID) {
nlohmann::json payload;
// Once the property inspector is loaded, send the list of GPUs
if (inPayload.at("propertyInspectorLoaded").get<bool>()) {
payload["gpus"] = gpus_;
payload["selected"] = selectedGpu_;
mConnectionManager->SendToPropertyInspector(inAction, inContext, payload);
}

// If the user selects a GPU, handle it
if (inPayload.at("receiveSelection").get<bool>()) {
Gpu gpu = inPayload["gpuInfo"];
HandleSelectedGpu(gpu);
mConnectionManager->SendToPropertyInspector(inAction, inContext, payload);
// Save the selected device to the settings
mConnectionManager->SetSettings(inPayload, inContext);
}
}
Expand All @@ -223,13 +232,15 @@ namespace nthompson {
usage_ = nullptr;
break;
}
// Save the selection
selectedGpu_ = gpu;
}

void GpuPlugin::KeyDownForAction(const std::string &inAction, const std::string &inContext,
const nlohmann::json &inPayload, const std::string &inDeviceID) {
if (!usage_) return;

// Launch the associated GPU management app
usage_->LaunchAssociatedApp();
}
}
12 changes: 10 additions & 2 deletions Src/GpuPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@

namespace nthompson {

// Timer class to run a function at a specified interval
class Timer {
public:
// Start the timer
void Start(const int32_t& interval, const std::function<void()>& func);
// Stop the timer
void Stop();
private:
std::thread thread_;
Expand All @@ -37,8 +40,11 @@ namespace nthompson {
GpuPlugin();
~GpuPlugin() override;

// Called once a second to update the title of the action
void Update();

// For the below methods, please refer to Elgato's documentation.

void SetActionText(const std::string& text);

void WillAppearForAction(const std::string& inAction,
Expand All @@ -63,14 +69,16 @@ namespace nthompson {
const nlohmann::json& inPayload,
const std::string& inDeviceID) override;
private:
// Finds all available GPUs on the system
void FindAvailableGpus();
std::map<UINT, Gpu> gpus_;
// Handles the selected GPU from the property inspector
void HandleSelectedGpu(const Gpu &gpu);
std::vector<Gpu> gpus_;
std::unique_ptr<IGpuUsage> usage_ = nullptr;
std::unique_ptr<Timer> timer_;
std::mutex mutex_;
std::set<std::string> contexts_;
Gpu selectedGpu_{};
void HandleSelectedGpu(const Gpu &gpu);
};

} // nthompson
Loading

0 comments on commit 0773586

Please sign in to comment.