Skip to content

Commit

Permalink
feat: add adapter options for idd
Browse files Browse the repository at this point in the history
  • Loading branch information
qiin2333 committed Aug 10, 2024
1 parent c6134e7 commit 3a249ee
Show file tree
Hide file tree
Showing 19 changed files with 257 additions and 30 deletions.
3 changes: 3 additions & 0 deletions cmake/packaging/windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/gamepad/"
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/vdd/"
DESTINATION "scripts"
COMPONENT vdd)
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/misc/cmd/"
DESTINATION "tools"
COMPONENT superCmds)

# Sunshine assets
install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/"
Expand Down
9 changes: 9 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,14 @@ namespace config {
return opts;
}

void
sync_idd_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input) {
std::string idd_adapter_path = "c:\\IddSampleDriver\\adapter.txt"; // "C:\IddSampleDriver\adapter.txt"
if (fs::exists(idd_adapter_path) && !input.empty()) {
file_handler::write_file(idd_adapter_path.c_str(), input.c_str());
}
}

void
apply_config(std::unordered_map<std::string, std::string> &&vars) {
if (!fs::exists(stream.file_apps.c_str())) {
Expand Down Expand Up @@ -1059,6 +1067,7 @@ namespace config {
string_f(vars, "capture", video.capture);
string_f(vars, "encoder", video.encoder);
string_f(vars, "adapter_name", video.adapter_name);
sync_idd_f(vars, "adapter_name", video.adapter_name);

string_f(vars, "output_name", video.output_name);
int_f(vars, "display_device_prep", video.display_device_prep, display_device::parsed_config_t::device_prep_from_view);
Expand Down
10 changes: 9 additions & 1 deletion src/confighttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,6 @@ namespace confighttp {
});

auto devices { display_device::enum_available_devices() };

pt::ptree devices_nodes;
for (const auto &[device_id, data] : devices) {
pt::ptree devices_node;
Expand All @@ -559,7 +558,16 @@ namespace confighttp {
devices_nodes.push_back(std::make_pair(""s, devices_node));
}

auto adapters { platf::adapter_names() };
pt::ptree adapters_nodes;
for (const auto &adapter_name : adapters) {
pt::ptree adapters_node;
adapters_node.put("name"s, adapter_name);
adapters_nodes.push_back(std::make_pair(""s, adapters_node));
}

outputTree.add_child("display_devices", devices_nodes);
outputTree.add_child("adapters", adapters_nodes);
outputTree.put("status", "true");
outputTree.put("platform", SUNSHINE_PLATFORM);
outputTree.put("version", PROJECT_VER);
Expand Down
34 changes: 34 additions & 0 deletions src/display_device/session.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// standard includes
#include <thread>
#include <boost/process.hpp>

// local includes
#include "session.h"
#include "src/platform/common.h"
#include "src/platform/windows/display_device/windows_utils.h"
#include "to_string.h"

namespace display_device {
Expand Down Expand Up @@ -204,6 +206,21 @@ namespace display_device {
}
else {
if (settings.is_changing_settings_going_to_fail()) {
// display_device::w_utils::togglePnpDeviceByFriendlyName("Virtual Display with HDR", false);
// BOOST_LOG(info) << "Disable IDD...";
boost::process::environment _env = boost::this_process::environment();
auto working_dir = boost::filesystem::path();
std::error_code ec;
std::string cmd = "C:\\Program Files\\Sunshine\\tools\\device-toggler.exe 2 2 \"Virtual Display with HDR\"";

auto child = platf::run_command(true, true, cmd, working_dir, _env, nullptr, ec, nullptr);
if (ec) {
BOOST_LOG(warning) << "Couldn't run cmd ["sv << cmd << "]: System: "sv << ec.message();
}
else {
BOOST_LOG(info) << "Executing idd cmd ["sv << cmd << "]"sv;
child.detach();
}
BOOST_LOG(warning) << "Reverting display settings will fail - retrying later...";
}

Expand All @@ -213,6 +230,23 @@ namespace display_device {
return false;
}

boost::process::environment _env = boost::this_process::environment();
auto working_dir = boost::filesystem::path();
std::error_code ec;
std::string cmd = "C:\\Program Files\\Sunshine\\tools\\device-toggler.exe 1 2 \"Virtual Display with HDR\"";

auto child = platf::run_command(true, true, cmd, working_dir, _env, nullptr, ec, nullptr);
if (ec) {
BOOST_LOG(warning) << "Couldn't run cmd ["sv << cmd << "]: System: "sv << ec.message();
}
else {
BOOST_LOG(info) << "Executing idd cmd ["sv << cmd << "]"sv;
child.detach();
}

// display_device::w_utils::togglePnpDeviceByFriendlyName("Generic Monitor (IDD HDR)", true);
// BOOST_LOG(info) << "Enable IDD...";
Sleep(1000);
return settings.revert_settings();
});
}
Expand Down
24 changes: 24 additions & 0 deletions src/entry_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <iostream>
#include <thread>

#include <boost/process.hpp>

// local includes
#include "config.h"
#include "confighttp.h"
Expand All @@ -16,6 +18,8 @@
#include "logging.h"
#include "network.h"
#include "platform/common.h"
#include "src/display_device/display_device.h"
#include "src/platform/windows/display_device/windows_utils.h"
#include "version.h"

extern "C" {
Expand Down Expand Up @@ -84,6 +88,26 @@ namespace lifetime {
int zero = 0;
desired_exit_code.compare_exchange_strong(zero, exit_code);

#ifdef _WIN32
if (async) {
// boost::process::environment _env = boost::this_process::environment();
// auto working_dir = boost::filesystem::path();
// std::error_code ec;
// std::string cmd = "C:\\Program Files\\Sunshine\\tools\\device-toggler.exe 2 \"Virtual Display with HDR\"";

// auto child = platf::run_command(true, true, cmd, working_dir, _env, nullptr, ec, nullptr);
// if (ec) {
// BOOST_LOG(warning) << "Couldn't run cmd ["sv << cmd << "]: System: "sv << ec.message();
// }
// else {
// BOOST_LOG(info) << "Executing sleep cmd ["sv << cmd << "]"sv;
// child.detach();
// }
// display_device::w_utils::togglePnpDeviceByFriendlyName("Generic Monitor (IDD HDR)", false);
// BOOST_LOG(info) << "Disable Generic Monitor (IDD HDR)...";
}
#endif

// Raise SIGINT to start termination
std::raise(SIGINT);

Expand Down
3 changes: 3 additions & 0 deletions src/platform/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,9 @@ namespace platf {
std::vector<std::string>
display_names(mem_type_e hwdevice_type);

std::vector<std::string>
adapter_names();

/**
* @brief Check if GPUs/drivers have changed since the last call to this function.
* @return `true` if a change has occurred or if it is unknown whether a change occurred.
Expand Down
27 changes: 27 additions & 0 deletions src/platform/windows/display_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,33 @@ namespace platf {
return display_names;
}


std::vector<std::string>
adapter_names() {
std::vector<std::string> adapter_names;

HRESULT status;

dxgi::factory1_t factory;
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void **) &factory);
if (FAILED(status)) {
BOOST_LOG(error) << "Failed to create DXGIFactory1 [0x"sv << util::hex(status).to_string_view() << ']';
return {};
}

dxgi::adapter_t adapter;
for (int x = 0; factory->EnumAdapters1(x, &adapter) != DXGI_ERROR_NOT_FOUND; ++x) {
DXGI_ADAPTER_DESC1 adapter_desc;
adapter->GetDesc1(&adapter_desc);

auto adapter_name = to_utf8(adapter_desc.Description);
adapter_names.emplace_back(std::move(adapter_name));
}

return adapter_names;
}


/**
* @brief Returns if GPUs/drivers have changed since the last call to this function.
* @return `true` if a change has occurred or if it is unknown whether a change occurred.
Expand Down
46 changes: 46 additions & 0 deletions src/platform/windows/display_device/windows_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,4 +651,50 @@ namespace display_device::w_utils {
return result == ERROR_ACCESS_DENIED;
}

bool
togglePnpDeviceByFriendlyName(const std::string &friendlyName, const bool &stat) {
HDEVINFO deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (deviceInfoSet == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to get device information set." << std::endl;
return false;
}

SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

bool deviceFound = false;
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); ++i) {
TCHAR deviceFriendlyName[256];
if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE) deviceFriendlyName, sizeof(deviceFriendlyName), NULL)) {
if (friendlyName == deviceFriendlyName) {
deviceFound = true;
break;
}
}
}

if (!deviceFound) {
std::cerr << "Device not found." << std::endl;
SetupDiDestroyDeviceInfoList(deviceInfoSet);
return false;
}

SP_PROPCHANGE_PARAMS propChangeParams;
propChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
propChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
propChangeParams.StateChange = stat ? DICS_ENABLE : DICS_DISABLE;
propChangeParams.Scope = DICS_FLAG_GLOBAL;
propChangeParams.HwProfile = 0;

if (!SetupDiSetClassInstallParams(deviceInfoSet, &deviceInfoData, &propChangeParams.ClassInstallHeader, sizeof(propChangeParams)) ||
!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, deviceInfoSet, &deviceInfoData)) {
std::cerr << "Failed to toggle device." << std::endl;
SetupDiDestroyDeviceInfoList(deviceInfoSet);
return false;
}

SetupDiDestroyDeviceInfoList(deviceInfoSet);
return true;
}

} // namespace display_device::w_utils
2 changes: 2 additions & 0 deletions src/platform/windows/display_device/windows_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,6 @@ namespace display_device::w_utils {
bool
test_no_access_to_ccd_api();

bool
togglePnpDeviceByFriendlyName(const std::string &friendlyName, const bool &stat);
} // namespace display_device::w_utils
2 changes: 1 addition & 1 deletion src/system_tray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace system_tray {
int msgboxID = MessageBoxW(
NULL,
L"你不能退出!\n那么想退吗? 真拿你没办法呢, 继续点一下吧~",
L"退你妹",
L"真的要退出吗",
MB_ICONWARNING | MB_OKCANCEL);

if (msgboxID == IDOK) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,26 @@ const config = ref(props.config)
<template>
<div class="mb-3" v-if="platform !== 'macos'">
<label for="adapter_name" class="form-label">{{ $t('config.adapter_name') }}</label>
<input type="text" class="form-control" id="adapter_name"
<PlatformLayout :platform="platform">
<template #windows>
<select id="adapter_name" class="form-select" v-model="config.adapter_name">
<option value="">{{ $t("_common.autodetect") }}</option>
<option v-for="(adapter, index) in config.adapters" :value="adapter.name" :key="index">
{{ adapter.name }}
</option>
</select>
</template>
<template #linux>
<input type="text" class="form-control" id="adapter_name"
:placeholder="$tp('config.adapter_name_placeholder', '/dev/dri/renderD128')"
v-model="config.adapter_name" />
</template>
</PlatformLayout>
<div class="form-text">
<PlatformLayout :platform="platform">
<template #windows>
{{ $t('config.adapter_name_desc_win') }}<br>
<pre>tools\dxgi-info.exe</pre>
{{ $t('config.adapter_name_desc_windows') }}<br>
<pre>如有安装最新版IDD虚拟显示器,可自动关联IDD的GPU指定</pre>
</template>
<template #linux>
{{ $t('config.adapter_name_desc_linux_1') }}<br>
Expand Down
2 changes: 1 addition & 1 deletion src_assets/common/assets/web/public/assets/locale/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"adapter_name_desc_linux_1": "手动指定用于捕获的 GPU。",
"adapter_name_desc_linux_2": "找到所有能够使用 VAAPI 的设备",
"adapter_name_desc_linux_3": "用上面的设备替换``renderD129``,列出设备的名称和功能。要获得 Sunshine 的支持,设备至少需要具备以下功能:",
"adapter_name_desc_windows": "手动指定用于捕获的 GPU 。如果未设置,GPU 将被自动选择。 我们强烈建议将此字段留空以使用自动的 GPU 选择!注意:此GPU 必须连接并开启显示器。 可以使用以下命令找到适当的值:",
"adapter_name_desc_windows": "手动指定用于捕获的 GPU 。如果未设置,GPU 将被自动选择。 我们强烈建议将此字段留空以使用自动的 GPU 选择!注意:此GPU 必须连接并开启显示器。",
"adapter_name_placeholder_windows": "Radeon RX 580系列",
"add": "添加",
"address_family": "IP 地址族",
Expand Down
2 changes: 1 addition & 1 deletion src_assets/common/sunshine-control-panel
36 changes: 35 additions & 1 deletion src_assets/windows/assets/apps.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,48 @@
"apps": [
{
"name": "Desktop",
"image-path": "desktop.png"
"image-path": "desktop.png",
"exclude-global-prep-cmd": "false",
"elevated": "",
"auto-detach": "true",
"wait-all": "true",
"exit-timeout": "5",
"menu-cmd": [
{
"id": "kcENAT5r9P",
"name": "打开触摸键盘",
"cmd": "C:\\Program Files\\Sunshine\\tools\\qiin-tabtip.exe",
"elevated": "false"
},
{
"id": "rjeOKHmcdL",
"name": "DPI 250",
"cmd": "C:\\Program Files\\Sunshine\\tools\\SetDpi.exe 250",
"elevated": "false"
},
{
"id": "C_vunhdQwA",
"name": "DPI 100",
"cmd": "C:\\Program Files\\Sunshine\\tools\\SetDpi.exe 100",
"elevated": "false"
}
]
},
{
"name": "Steam Big Picture",
"cmd": "steam://open/bigpicture",
"auto-detach": "true",
"wait-all": "true",
"image-path": "steam.png"
},
{
"name": "禁用虚拟显示器",
"cmd": "C:\\Program Files\\Sunshine\\tools\\device-toggler.exe 2 \"Virtual Display with HDR\"",
"elevated": "true"
},
{
"name": "安全模式重启Sunshine",
"cmd": "C:\\Program Files\\Sunshine\\Sunshine.exe -1"
}
]
}
Binary file modified src_assets/windows/misc/vdd/driver/IddSampleDriver.dll
Binary file not shown.
Binary file modified src_assets/windows/misc/vdd/driver/IddSampleDriver.inf
Binary file not shown.
1 change: 1 addition & 0 deletions src_assets/windows/misc/vdd/driver/adapter.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Microsoft Basic Render Driver
Binary file modified src_assets/windows/misc/vdd/driver/iddsampledriver.cat
Binary file not shown.
Loading

0 comments on commit 3a249ee

Please sign in to comment.