Skip to content

Commit

Permalink
Fixed resolution getting stuck after playing games
Browse files Browse the repository at this point in the history
  • Loading branch information
acceleration3 committed May 8, 2021
1 parent 6ad2f80 commit 41066bd
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 11 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.vscode
ResFix_src/nvapi/*
!ResFix_src/nvapi/nvapi_info.txt
ResFix_src/build
1 change: 1 addition & 0 deletions Bin/ResFix/AtLogon.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ResFix.exe set-edid 0 0 edid.txt > log.txt
Binary file added Bin/ResFix/ResFix.exe
Binary file not shown.
1 change: 1 addition & 0 deletions Bin/ResFix/edid.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
00 FF FF FF FF FF FF 00 3A C4 00 00 00 00 00 00 0F 19 01 04 A5 3E 22 64 06 92 B1 A3 54 4C 99 26 0F 50 54 00 00 00 95 00 81 00 D1 00 D1 C0 81 C0 B3 00 6C 40 00 00 4D D0 00 A0 F0 70 3E 80 30 20 35 00 6D 55 21 00 00 1A 39 1C 58 A0 50 00 16 30 30 20 3A 00 6D 55 21 00 00 1A 00 00 00 FD 00 1E 46 1E 8C 36 01 0A 20 20 20 20 20 20 00 00 00 FC 00 4E 56 49 44 49 41 20 56 47 58 20 0A 20 00 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Binary file removed Bin/ResolutionFix.exe
Binary file not shown.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ A Powershell one-click solution to enable NVIDIA GeForce Experience GameStream o
## Installation
Copy and paste these commands in the machine's powershell prompt:
```
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls";Set-ExecutionPolicy Unrestricted;Invoke-WebRequest -Uri https://github.com/acceleration3/cloudgamestream/archive/master.zip -OutFile arch.zip;Add-Type -Assembly "System.IO.Compression.Filesystem";$dir = [string](Get-Location);rmdir -r cloudgamestream-master -ErrorAction Ignore;[System.IO.Compression.ZipFile]::ExtractToDirectory($dir + "\arch.zip", $dir);cd cloudgamestream-master;./Setup.ps1
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls";Set-ExecutionPolicy Unrestricted;Invoke-WebRequest -Uri https://github.com/acceleration3/cloudgamestream/releases/download/resolution-fix/cloudgamestream.zip -OutFile arch.zip;Add-Type -Assembly "System.IO.Compression.Filesystem";$dir = [string](Get-Location);rmdir -r cloudgamestream-master -ErrorAction Ignore;[System.IO.Compression.ZipFile]::ExtractToDirectory($dir + "\arch.zip", $dir);cd cloudgamestream;./Setup.ps1
```
Or you can download the script and binaries from [here](https://github.com/acceleration3/cloudgamestream/archive/master.zip).
Or you can download the script and binaries from [here](https://github.com/acceleration3/cloudgamestream/releases/download/resolution-fix/cloudgamestream.zip).
 
 

## Compatibility
Tested and working on the following:

* OS:
* Windows 10 Pro build 2004 (**Windows 10 will only be compatible with some GPUs. Out of all the ones I've tested only the M60 works.**)
* Windows 10 Pro (**Windows 10 works, albeit only with some older NVIDIA driver versions. I will try to figure out if something can be done for newer drivers.**)
* Windows Server 2019
* Windows Server 2016

Expand All @@ -29,7 +29,7 @@ Tested and working on the following:
* Google Cloud Platform Tesla P4

 
**WARNING: Machines provided by Shadow.tech supposedly have incompatibility with GeForce Experience and may brick your VM. Use at your own risk.**
**WARNING: Machines provided by Shadow.tech supposedly have incompatibility with GeForce Experience and may brick your VM.**
 
 
 
Expand All @@ -48,6 +48,9 @@ I am building a list of platforms it currently supports, so if you've tested it

### This GeForce Experience version doesn't support my game. What do I do?
You can stream your entire desktop with GeForce Experience. Just add `C:\windows\system32\mstsc.exe` to the applications list and launch that with Moonlight.

### Can I load custom EDID data?
Yes, but the EDID files **need to be compatible with NVIDIA's EDID format**. You can try changing the EDID data by editing the `C:\ResFix\edid.txt` file. Create a backup of the original file in case it isn't compatible.
 
 
 
Expand Down
18 changes: 18 additions & 0 deletions ResFix_src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.15)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

project(ResFix)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

find_package(NVAPI)

if (NOT NVAPI_FOUND)
message(FATAL_ERROR "NVAPI was not found. Read the file nvapi_info.txt inside the nvapi folder for more information.")
endif()

add_executable(ResFix main.cpp)
target_include_directories(ResFix PRIVATE ${NVAPI_INCLUDE_DIR})
target_link_libraries(ResFix ${NVAPI_LIBRARY})
4 changes: 4 additions & 0 deletions ResFix_src/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@echo off
cmake --build build --config Release --target ResFix
mv build/Release/ResFix.exe ../Bin/ResFix/ResFix.exe
pause
6 changes: 6 additions & 0 deletions ResFix_src/clean_reconfigure.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@echo off
rmdir /q /s build
mkdir build
cd build
cmake -G "Visual Studio 16 2019" -A win32 ..
pause
35 changes: 35 additions & 0 deletions ResFix_src/cmake/FindNVAPI.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
set(NVAPI_FOUND 0)

if(WIN32)
find_path(NVAPI_INCLUDE_DIR
NAMES nvapi.h
PATHS ${CMAKE_SOURCE_DIR}/nvapi
)

if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
message("Trying to find AMD64 NVAPI library...")
set(NVAPI_ARCH_DIR amd64)
set(NVAPI_LIBRARY_NAME nvapi64)
else()
message("Trying to find x86 NVAPI library...")
set(NVAPI_ARCH_DIR x86)
set(NVAPI_LIBRARY_NAME nvapi)
endif()

set(NVAPI_POSSIBLE_LIBRARY_PATHS
${NVAPI_INCLUDE_DIR}/${NVAPI_ARCH_DIR}
)

find_library(NVAPI_LIBRARY
NAMES ${NVAPI_LIBRARY_NAME}
HINTS ${NVAPI_POSSIBLE_LIBRARY_PATHS}
)

message("NVAPI_INCLUDE_DIR: ${NVAPI_INCLUDE_DIR}")
message("NVAPI_LIBRARY: ${NVAPI_LIBRARY}")

if(NVAPI_INCLUDE_DIR AND NVAPI_LIBRARY)
message("Found NVAPI.")
set(NVAPI_FOUND 1)
endif()
endif()
124 changes: 124 additions & 0 deletions ResFix_src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <windows.h>

#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <filesystem>

#include "nvapi.h"

#define NVAPI_EXIT_IF_ERROR(func, msg) \
{ \
NvAPI_Status status; \
NvAPI_ShortString string; \
if ((status = func) != NVAPI_OK) { \
NvAPI_GetErrorMessage(status, string); \
std::cout << msg << " Error: " << string << std::endl; \
NvAPI_Unload(); \
return false; \
} \
}

bool nv_set_edid(const std::uint32_t gpu_index, const std::uint32_t display_index, const std::string_view edid_file)
{
std::fstream edid_stream(edid_file);
if (!edid_stream.good()) {
std::cout << "ERROR: Failed to open EDID file." << std::endl;
return false;
}

std::vector<std::uint8_t> edid_data;
std::uint32_t byte;
while(!edid_stream.eof()) {
edid_stream >> std::hex >> byte;
edid_data.push_back(byte);
}
if (edid_data.size() != 256) {
std::cout << "ERROR: Invalid EDID data (size != 256 bytes). The data is either malformed or not in the NVIDIA format." << std::endl;
return false;
}

NVAPI_EXIT_IF_ERROR(NvAPI_Initialize(), "ERROR: Failed to initialize NVAPI.");

NvU32 gpu_count = 0;
NvPhysicalGpuHandle physical_gpus[NVAPI_MAX_PHYSICAL_GPUS];
NVAPI_EXIT_IF_ERROR(NvAPI_EnumPhysicalGPUs(physical_gpus, &gpu_count), "ERROR: NvAPI_EnumPhysicalGPUs failed to get GPU info.");
if (gpu_count <= 0) {
std::cout << "ERROR: Invalid GPU count: " << gpu_count << std::endl;
return false;
}

NvU32 display_count = 0;
NVAPI_EXIT_IF_ERROR(NvAPI_GPU_GetAllDisplayIds(physical_gpus[0], NULL, &display_count), "ERROR: NvAPI_GPU_GetAllDisplayIds failed to get available display count.");

NV_GPU_DISPLAYIDS displays[NVAPI_MAX_DISPLAYS];
displays[0].version = NV_GPU_DISPLAYIDS_VER;
NVAPI_EXIT_IF_ERROR(NvAPI_GPU_GetAllDisplayIds(physical_gpus[0], displays, &display_count), "ERROR: NvAPI_GPU_GetAllDisplayIds failed to get display info.");

if (gpu_index >= gpu_count) {
std::cout << "ERROR: Invalid GPU index: count=" << gpu_count << ", index=" << gpu_index << std::endl;
return false;
}
if (display_index >= display_count) {
std::cout << "ERROR: Invalid display index: count=" << display_count << ", index=" << display_index << std::endl;
return false;
}

NV_EDID edid{};
edid.version = NV_EDID_VER;
std::copy(edid_data.begin(), edid_data.end(), edid.EDID_Data);
edid.sizeofEDID = edid_data.size();
NVAPI_EXIT_IF_ERROR(NvAPI_GPU_SetEDID(physical_gpus[gpu_index], displays[display_index].displayId, &edid), "ERROR: NvAPI_GPU_SetEDID failed to set EDID.");

NvAPI_Unload();
return true;
}

int main(int argc, char *argv[])
{
std::vector<std::string> args;
for (int i = 0; i < argc; i++) {
args.push_back(std::string(argv[i]));
}

for (auto arg = args.begin(); arg != args.end(); arg++) {
if (*arg == "set-edid") {
auto gpu_index_arg = std::next(arg);
if(gpu_index_arg == args.end()) {
std::cout << "ERROR: set-edid command missing GPU index argument." << std::endl;
return -1;
}

auto display_index_arg = std::next(gpu_index_arg);
if(display_index_arg == args.end()) {
std::cout << "ERROR: set-edid command missing display index argument." << std::endl;
return -1;
}

auto edid_file_arg = std::next(display_index_arg);
if(edid_file_arg == args.end()) {
std::cout << "ERROR: set-edid command missing EDID file argument." << std::endl;
return -1;
}

std::string edid_file = *edid_file_arg;
if (!std::filesystem::exists(edid_file)) {
std::cout << "ERROR: EDID file \"" << edid_file << "\" does not exist." << std::endl;
return -1;
}

std::uint32_t gpu_index = std::atoi(gpu_index_arg->c_str());
std::uint32_t display_index = std::atoi(display_index_arg->c_str());
if (!nv_set_edid(gpu_index, display_index, edid_file)) {
return -1;
}
std::cout << "Success: Set EDID file sucessfully." << std::endl;
}
}

return 0;
}
1 change: 1 addition & 0 deletions ResFix_src/nvapi/nvapi_info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Due to the NVAPI SDK's license, distribution of copies of the source code is not allowed. To build this, you need to download the NVAPI SDK and extract it here.
21 changes: 14 additions & 7 deletions Steps/4_Apply_Fixes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ If (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdenti
Break
}

$WorkDir = "$PSScriptRoot\..\Bin\"
$WorkDir = "$PSScriptRoot\..\Bin"

$osType = Get-CimInstance -ClassName Win32_OperatingSystem

Expand All @@ -13,14 +13,21 @@ if($osType.ProductType -eq 3) {
Install-WindowsFeature -Name Wireless-Networking | Out-Null
}

Write-Host "Applying resolution fix..."
$Status = @("NvAPI failed to initialize", "Failed to query GPUs", "Failed to get display count", "Failed to query displays", "Failed to set EDID")
Write-Host "Applying resolution fix scheduled task..."
if (!(Test-Path -Path "C:\ResFix")) {
New-Item -Path C:\ResFix -ItemType Directory | Out-Null
Copy-Item "$WorkDir\ResFix\*" -Destination "C:\ResFix" -Recurse | Out-Null
New-Item "C:\ResFix\Folder used by cloudgamestream dont delete.txt" | Out-Null
}

$ExitCode = (Start-Process -FilePath "$WorkDir\ResolutionFix.exe" -WorkingDirectory "$WorkDir" -Argument "-a","-g 0","-d 0" -NoNewWindow -Wait -PassThru).ExitCode
if($ExitCode -ne 0) {
$Message = $Status[$($ExitCode - 1)]
throw "Adding EDID failed: $Message($ExitCode)"
if (!(Get-ScheduledTask -TaskName "SetEDID")) {
$action = New-ScheduledTaskAction -Execute "C:\ResFix\AtLogon.bat" -WorkingDirectory "C:\ResFix"
$trigger = New-ScheduledTaskTrigger -AtLogon -RandomDelay "00:00:30"
$principal = New-ScheduledTaskPrincipal -GroupId "BUILTIN\Administrators" -RunLevel Highest
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "SetEDID" -Principal $principal -Description "Sets an EDID at startup" | Out-Null
}

Start-ScheduledTask -TaskName "SetEDID" | Out-Null

Start-Sleep -Seconds 2
Write-Host "Resolution fix applied." -ForegroundColor Green

0 comments on commit 41066bd

Please sign in to comment.