Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: NvFBC support #208

Merged
merged 5 commits into from
Dec 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

![GitHub last commit](https://img.shields.io/github/last-commit/keylase/nvidia-patch.svg) ![Latest version](https://img.shields.io/badge/latest%20linux%20driver%20version-440.36-brightgreen.svg)

This patch removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs. Also there is experimental NvFBC patch available which allows to use NvFBC on consumer-grade GPUs. It should be applied same way as NVENC `patch.sh`, except you have to use `patch-fbc.sh` instead.
This patch removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs.

Also there is available experimental NvFBC patch which allows to use NvFBC on consumer-grade GPUs. It should be applied same way as NVENC `patch.sh`, except you have to use `patch-fbc.sh` instead.

Main target operating system is **GNU/Linux**, but for **Windows** support see [**win**](win).

Expand Down
4 changes: 3 additions & 1 deletion tools/readme-autogen/templates/linux_readme_master.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

![GitHub last commit](https://img.shields.io/github/last-commit/keylase/nvidia-patch.svg) ![Latest version](https://img.shields.io/badge/latest%20linux%20driver%20version-${latest_version}-brightgreen.svg)

This patch removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs. Also there is experimental NvFBC patch available which allows to use NvFBC on consumer-grade GPUs. It should be applied same way as NVENC `patch.sh`, except you have to use `patch-fbc.sh` instead.
This patch removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs.

Also there is available experimental NvFBC patch which allows to use NvFBC on consumer-grade GPUs. It should be applied same way as NVENC `patch.sh`, except you have to use `patch-fbc.sh` instead.

Main target operating system is **GNU/Linux**, but for **Windows** support see [**win**](win).

Expand Down
2 changes: 2 additions & 0 deletions tools/readme-autogen/templates/windows_readme_master.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Nvidia drivers patch for Windows

This patch removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs.

Also there is available NvFBC wrapper which allows to use NvFBC on consumer-grade GPUs. See [**nvfbcwrp**](nvfbcwrp) directory for details.

Requirements:

- Any of following 64bit operating systems:
Expand Down
2 changes: 2 additions & 0 deletions win/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Nvidia drivers patch for Windows

This patch removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs.

Also there is available NvFBC wrapper which allows to use NvFBC on consumer-grade GPUs. See [**nvfbcwrp**](nvfbcwrp) directory for details.

Requirements:

- Any of following 64bit operating systems:
Expand Down
32 changes: 32 additions & 0 deletions win/nvfbcwrp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
12 changes: 12 additions & 0 deletions win/nvfbcwrp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
nvfbcwrp
========

Wrapper for `NvFBC64.dll` library which injects private keys into `NvFBC_CreateEx` calls in order to enable NvFBC on customer-grade hardware (like GeForce cards) for all NvFBC-targeted applications. It should work at least with applications built with Nvidia Capture SDK versions 5.0 to 7.1.

## Usage

1. Obtain `nvfbcwrp.dll` file. You may build it yourself with MSVS 2019 or download latest release [here](https://gist.github.com/Snawoot/1edfbda9b0e91c46b6cc3d5a0e1e55a4/raw/ee2e4647753a731ac7b333a0c9681dc07d3ee0a1/nvfbcwrp.dll).
2. Backup your `%WINDIR\system32\NvFBC64.dll` file.
3. Rename file `%WINDIR\system32\NvFBC64.dll` to `%WINDIR\system32\NvFBC64_.dll`
4. Put `nvfbcwrp.dll` to `%WINDIR\system32\NvFBC64.dll` (on the original place of renamed `NvFBC64.dll` library).
5. Restart any applications using this library. That's it.
5 changes: 5 additions & 0 deletions win/nvfbcwrp/framework.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#define WIN32_LEAN_AND_MEAN // Исключите редко используемые компоненты из заголовков Windows
// Файлы заголовков Windows
#include <windows.h>
37 changes: 37 additions & 0 deletions win/nvfbcwrp/nvfbcbody.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.data

extern ORIG_NvFBC_Create : qword, ORIG_NvFBC_Enable : qword,
ORIG_NvFBC_GetSDKVersion : qword, ORIG_NvFBC_GetStatus : qword,
ORIG_NvFBC_GetStatusEx : qword, ORIG_NvFBC_SetGlobalFlags : qword,
ORIG_NvOptimusEnablement : qword

.code
PROXY_NvFBC_Create proc
jmp qword ptr [ORIG_NvFBC_Create]
PROXY_NvFBC_Create endp

PROXY_NvFBC_Enable proc
jmp qword ptr [ORIG_NvFBC_Enable]
PROXY_NvFBC_Enable endp

PROXY_NvFBC_GetSDKVersion proc
jmp qword ptr [ORIG_NvFBC_GetSDKVersion]
PROXY_NvFBC_GetSDKVersion endp

PROXY_NvFBC_GetStatus proc
jmp qword ptr [ORIG_NvFBC_GetStatus]
PROXY_NvFBC_GetStatus endp

PROXY_NvFBC_GetStatusEx proc
jmp qword ptr [ORIG_NvFBC_GetStatusEx]
PROXY_NvFBC_GetStatusEx endp

PROXY_NvFBC_SetGlobalFlags proc
jmp qword ptr [ORIG_NvFBC_SetGlobalFlags]
PROXY_NvFBC_SetGlobalFlags endp

PROXY_NvOptimusEnablement proc
jmp qword ptr [ORIG_NvOptimusEnablement]
PROXY_NvOptimusEnablement endp

end
79 changes: 79 additions & 0 deletions win/nvfbcwrp/nvfbcdefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

// Magic code which is passed as pPrivateData and enables NvFBC to work on GeForce
int magic[] = { 0x0D7BC620, 0x4C17E142, 0x5E6B5997, 0x4B5A855B };

typedef unsigned long NvU32; /* 0 to 4294967295 */

/**
* \ingroup NVFBC
* Macro to define the NVFBC API version corresponding to this distribution.
*/
#define NVFBC_DLL_VERSION 0x70

/**
* \ingroup NVFBC
* Calling Convention
*/
#define NVFBCAPI __stdcall

/**
* \ingroup NVFBC
* Macro to construct version numbers for parameter structs.
*/
#define NVFBC_STRUCT_VERSION(typeName, ver) (NvU32)(sizeof(typeName) | ((ver)<<16) | (NVFBC_DLL_VERSION << 24))

typedef enum _NVFBCRESULT
{
NVFBC_SUCCESS = 0,
NVFBC_ERROR_GENERIC = -1, /**< Unexpected failure in NVFBC. */
NVFBC_ERROR_INVALID_PARAM = -2, /**< One or more of the paramteres passed to NvFBC are invalid [This include NULL pointers]. */
NVFBC_ERROR_INVALIDATED_SESSION = -3, /**< NvFBC session is invalid. Client needs to recreate session. */
NVFBC_ERROR_PROTECTED_CONTENT = -4, /**< Protected content detected. Capture failed. */
NVFBC_ERROR_DRIVER_FAILURE = -5, /**< GPU driver returned failure to process NvFBC command. */
NVFBC_ERROR_CUDA_FAILURE = -6, /**< CUDA driver returned failure to process NvFBC command. */
NVFBC_ERROR_UNSUPPORTED = -7, /**< API Unsupported on this version of NvFBC. */
NVFBC_ERROR_HW_ENC_FAILURE = -8, /**< HW Encoder returned failure to process NVFBC command. */
NVFBC_ERROR_INCOMPATIBLE_DRIVER = -9, /**< NVFBC is not compatible with this version of the GPU driver. */
NVFBC_ERROR_UNSUPPORTED_PLATFORM = -10, /**< NVFBC is not supported on this platform. */
NVFBC_ERROR_OUT_OF_MEMORY = -11, /**< Failed to allocate memory. */
NVFBC_ERROR_INVALID_PTR = -12, /**< A NULL pointer was passed. */
NVFBC_ERROR_INCOMPATIBLE_VERSION = -13, /**< An API was called with a parameter struct that has an incompatible version. Check dwVersion field of paramter struct. */
NVFBC_ERROR_OPT_CAPTURE_FAILURE = -14, /**< Desktop Capture failed. */
NVFBC_ERROR_INSUFFICIENT_PRIVILEGES = -15, /**< User doesn't have appropriate previlages. */
NVFBC_ERROR_INVALID_CALL = -16, /**< NVFBC APIs called in wrong sequence. */
NVFBC_ERROR_SYSTEM_ERROR = -17, /**< Win32 error. */
NVFBC_ERROR_INVALID_TARGET = -18, /**< The target adapter idx can not be used for NVFBC capture. It may not correspond to an NVIDIA GPU, or may not be attached to desktop. */
NVFBC_ERROR_NVAPI_FAILURE = -19, /**< NvAPI Error */
NVFBC_ERROR_DYNAMIC_DISABLE = -20, /**< NvFBC is dynamically disabled. Cannot continue to capture */
NVFBC_ERROR_IPC_FAILURE = -21, /**< NVFBC encountered an error in state management */
NVFBC_ERROR_CURSOR_CAPTURE_FAILURE = -22, /**< Hardware cursor capture failed */
} NVFBCRESULT;


typedef struct _NvFBCCreateParams
{
NvU32 dwVersion; /**< [in] Struct version. Set to NVFBC_CREATE_PARAMS_VER. */
NvU32 dwInterfaceType; /**< [in] ID of the NVFBC interface Type being requested. */
NvU32 dwMaxDisplayWidth; /**< [out] Max. display width allowed. */
NvU32 dwMaxDisplayHeight; /**< [out] Max. display height allowed. */
void* pDevice; /**< [in] Device pointer. */
void* pPrivateData; /**< [in] Private data [optional]. */
NvU32 dwPrivateDataSize; /**< [in] Size of private data. */
NvU32 dwInterfaceVersion; /**< [in] Version of the capture interface. */
void* pNvFBC; /**< [out] A pointer to the requested NVFBC object. */
NvU32 dwAdapterIdx; /**< [in] Adapter Ordinal corresponding to the display to be grabbed. If pDevice is set, this parameter is ignored. */
NvU32 dwNvFBCVersion; /**< [out] Indicates the highest NvFBC interface version supported by the loaded NVFBC library. */
void* cudaCtx; /**< [in] CUDA context created using cuD3D9CtxCreate with the D3D9 device passed as pDevice. Only used for NvFBCCuda interface.
It is mandatory to pass a valid D3D9 device if cudaCtx is passed. The call will fail otherwise.
Client must release NvFBCCuda object before destroying the cudaCtx. */
void* pPrivateData2; /**< [in] Private data [optional]. */
NvU32 dwPrivateData2Size; /**< [in] Size of private data. */
NvU32 dwReserved[55]; /**< [in] Reserved. Should be set to 0. */
void* pReserved[27]; /**< [in] Reserved. Should be set to NULL. */
}NvFBCCreateParams;
#define NVFBC_CREATE_PARAMS_VER_1 NVFBC_STRUCT_VERSION(NvFBCCreateParams, 1)
#define NVFBC_CREATE_PARAMS_VER_2 NVFBC_STRUCT_VERSION(NvFBCCreateParams, 2)
#define NVFBC_CREATE_PARAMS_VER NVFBC_CREATE_PARAMS_VER_2

typedef NVFBCRESULT(NVFBCAPI* NvFBC_CreateFunctionExType) (void* pCreateParams);
10 changes: 10 additions & 0 deletions win/nvfbcwrp/nvfbcwrp.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
LIBRARY nvfbcwrp
EXPORTS
NvFBC_Create=PROXY_NvFBC_Create @1
NvFBC_CreateEx=PROXY_NvFBC_CreateEx @2
NvFBC_Enable=PROXY_NvFBC_Enable @3
NvFBC_GetSDKVersion=PROXY_NvFBC_GetSDKVersion @4
NvFBC_GetStatus=PROXY_NvFBC_GetStatus @5
NvFBC_GetStatusEx=PROXY_NvFBC_GetStatusEx @6
NvFBC_SetGlobalFlags=PROXY_NvFBC_SetGlobalFlags @7
NvOptimusEnablement=PROXY_NvOptimusEnablement @8
31 changes: 31 additions & 0 deletions win/nvfbcwrp/nvfbcwrp.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29519.87
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nvfbcwrp", "nvfbcwrp.vcxproj", "{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x64.ActiveCfg = Debug|x64
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x64.Build.0 = Debug|x64
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x86.ActiveCfg = Debug|Win32
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Debug|x86.Build.0 = Debug|Win32
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x64.ActiveCfg = Release|x64
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x64.Build.0 = Release|x64
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x86.ActiveCfg = Release|Win32
{F2E7530B-BA35-4592-A0A9-CBE9CAD9A3CB}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8A014521-63BA-4C47-A9A0-D97C80423FA4}
EndGlobalSection
EndGlobal
Loading