Skip to content

Commit

Permalink
Merge pull request #208 from Snawoot/win_fbc
Browse files Browse the repository at this point in the history
Windows: NvFBC support
  • Loading branch information
Snawoot authored Dec 2, 2019
2 parents 80b3f26 + d106857 commit 9a30795
Show file tree
Hide file tree
Showing 17 changed files with 536 additions and 2 deletions.
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

0 comments on commit 9a30795

Please sign in to comment.