├── README.md ├── d3d11.cpp ├── d3d11.def └── d3d11.vcxproj /README.md: -------------------------------------------------------------------------------- 1 | # Elf auf Zwölf 2 | 3 | Translates D3D11 games to D3D12 using Microsoft's own 4 | [D3D11On12](https://docs.microsoft.com/en-us/windows/desktop/direct3d12/direct3d-11-on-12) 5 | wrapper library. 6 | 7 | ### Requirements 8 | 9 | Windows 10 build 1809 is required for this to work properly. Might work with 1803, but that 10 | was not tested. 11 | 12 | ### How to use 13 | 14 | Just download the latest [release](https://github.com/doitsujin/elf-auf-zwoelf/releases), 15 | copy the `d3d11.dll` next to the executable of the game you want to run, and start the game. 16 | Make sure to use the `x64` one for 64-bit games, and the `x86` one for 32-bit games. 17 | 18 | If everything works correctly, you will most likely experience reduced performance compared 19 | to native D3D11, and in some cases rendering issues and/or driver crashes. Some games may 20 | refuse to run entirely. 21 | 22 | **Note:** Tools like MSI Afterburner will still show D3D11 in their overlay. This is because 23 | they see a DXGI swap chain created for a D3D11 device, not the underlying D3D12 device. 24 | 25 | ### Why? 26 | 27 | Why not? Just don't expect any sort of support when running into issues. 28 | -------------------------------------------------------------------------------- /d3d11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | static PFN_D3D11ON12_CREATE_DEVICE getPfnD3D11On12CreateDevice() { 8 | static PFN_D3D11ON12_CREATE_DEVICE fptr = nullptr; 9 | 10 | if (fptr) 11 | return fptr; 12 | 13 | HMODULE d3d11module = LoadLibraryA("C:\\Windows\\System32\\d3d11.dll"); 14 | 15 | if (!d3d11module) 16 | return nullptr; 17 | 18 | fptr = reinterpret_cast( 19 | GetProcAddress(d3d11module, "D3D11On12CreateDevice")); 20 | return fptr; 21 | } 22 | 23 | 24 | 25 | HRESULT __stdcall D3D11CreateDevice( 26 | IDXGIAdapter *pAdapter, 27 | D3D_DRIVER_TYPE DriverType, 28 | HMODULE Software, 29 | UINT Flags, 30 | const D3D_FEATURE_LEVEL *pFeatureLevels, 31 | UINT FeatureLevels, 32 | UINT SDKVersion, 33 | ID3D11Device **ppDevice, 34 | D3D_FEATURE_LEVEL *pFeatureLevel, 35 | ID3D11DeviceContext **ppImmediateContext) { 36 | ID3D12Device* d3d12device; 37 | 38 | HRESULT hr = D3D12CreateDevice(pAdapter, 39 | D3D_FEATURE_LEVEL_11_0, 40 | IID_PPV_ARGS(&d3d12device)); 41 | 42 | if (FAILED(hr)) 43 | return hr; 44 | 45 | D3D12_COMMAND_QUEUE_DESC desc; 46 | desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; 47 | desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; 48 | desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; 49 | desc.NodeMask = 0; 50 | 51 | ID3D12CommandQueue* d3d12queue; 52 | 53 | hr = d3d12device->CreateCommandQueue(&desc, 54 | IID_PPV_ARGS(&d3d12queue)); 55 | 56 | if (FAILED(hr)) 57 | return hr; 58 | 59 | auto pfnD3D11on12CreateDevice = getPfnD3D11On12CreateDevice(); 60 | 61 | if (!pfnD3D11on12CreateDevice) 62 | return E_FAIL; 63 | 64 | hr = (*pfnD3D11on12CreateDevice)(d3d12device, 65 | Flags, pFeatureLevels, FeatureLevels, 66 | reinterpret_cast(&d3d12queue), 67 | 1, 0, ppDevice, ppImmediateContext, pFeatureLevel); 68 | 69 | d3d12device->Release(); 70 | return hr; 71 | } 72 | 73 | 74 | HRESULT __stdcall D3D11CreateDeviceAndSwapChain( 75 | IDXGIAdapter* pAdapter, 76 | D3D_DRIVER_TYPE DriverType, 77 | HMODULE Software, 78 | UINT Flags, 79 | const D3D_FEATURE_LEVEL* pFeatureLevels, 80 | UINT FeatureLevels, 81 | UINT SDKVersion, 82 | const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, 83 | IDXGISwapChain** ppSwapChain, 84 | ID3D11Device** ppDevice, 85 | D3D_FEATURE_LEVEL* pFeatureLevel, 86 | ID3D11DeviceContext** ppImmediateContext) { 87 | if (ppSwapChain && !pSwapChainDesc) 88 | return E_INVALIDARG; 89 | 90 | ID3D11Device* d3d11Device; 91 | ID3D11DeviceContext* d3d11Context; 92 | 93 | HRESULT status = D3D11CreateDevice(pAdapter, DriverType, 94 | Software, Flags, pFeatureLevels, FeatureLevels, 95 | SDKVersion, &d3d11Device, pFeatureLevel, &d3d11Context); 96 | 97 | if (FAILED(status)) 98 | return status; 99 | 100 | if (ppSwapChain) { 101 | IDXGIDevice* dxgiDevice = nullptr; 102 | IDXGIAdapter* dxgiAdapter = nullptr; 103 | IDXGIFactory* dxgiFactory = nullptr; 104 | 105 | HRESULT hr = d3d11Device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); 106 | 107 | if (FAILED(hr)) 108 | return E_INVALIDARG; 109 | 110 | hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter)); 111 | dxgiDevice->Release(); 112 | 113 | if (FAILED(hr)) 114 | return E_INVALIDARG; 115 | 116 | hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)); 117 | dxgiAdapter->Release(); 118 | 119 | if (FAILED(hr)) 120 | return E_INVALIDARG; 121 | 122 | DXGI_SWAP_CHAIN_DESC desc = *pSwapChainDesc; 123 | hr = dxgiFactory->CreateSwapChain(d3d11Device, &desc, ppSwapChain); 124 | dxgiFactory->Release(); 125 | 126 | if (FAILED(hr)) 127 | return hr; 128 | } 129 | 130 | if (ppDevice != nullptr) 131 | *ppDevice = d3d11Device; 132 | else 133 | d3d11Device->Release(); 134 | 135 | if (ppImmediateContext != nullptr) 136 | *ppImmediateContext = d3d11Context; 137 | else 138 | d3d11Context->Release(); 139 | 140 | return S_OK; 141 | } -------------------------------------------------------------------------------- /d3d11.def: -------------------------------------------------------------------------------- 1 | LIBRARY D3D11.DLL 2 | EXPORTS 3 | D3D11CreateDevice 4 | D3D11CreateDeviceAndSwapChain 5 | -------------------------------------------------------------------------------- /d3d11.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {94D26100-50F9-472B-82DF-6ED9BB6DCD62} 24 | Win32Proj 25 | Dll1 26 | 10.0.17763.0 27 | d3d11 28 | 29 | 30 | 31 | DynamicLibrary 32 | true 33 | v141 34 | Unicode 35 | 36 | 37 | DynamicLibrary 38 | false 39 | v141 40 | true 41 | Unicode 42 | 43 | 44 | DynamicLibrary 45 | true 46 | v141 47 | Unicode 48 | 49 | 50 | DynamicLibrary 51 | false 52 | v141 53 | true 54 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | 77 | 78 | true 79 | 80 | 81 | false 82 | 83 | 84 | false 85 | 86 | 87 | 88 | NotUsing 89 | Level3 90 | Disabled 91 | true 92 | WIN32;_DEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 93 | true 94 | 95 | 96 | Windows 97 | true 98 | d3d12.lib;%(AdditionalDependencies) 99 | d3d11.def 100 | 101 | 102 | 103 | 104 | NotUsing 105 | Level3 106 | Disabled 107 | true 108 | _DEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 109 | true 110 | 111 | 112 | Windows 113 | true 114 | d3d11.def 115 | d3d12.lib;%(AdditionalDependencies) 116 | 117 | 118 | 119 | 120 | NotUsing 121 | Level3 122 | MaxSpeed 123 | true 124 | true 125 | true 126 | WIN32;NDEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 127 | true 128 | 129 | 130 | Windows 131 | true 132 | true 133 | true 134 | d3d11.def 135 | d3d12.lib;%(AdditionalDependencies) 136 | 137 | 138 | 139 | 140 | NotUsing 141 | Level3 142 | MaxSpeed 143 | true 144 | true 145 | true 146 | NDEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 147 | true 148 | 149 | 150 | Windows 151 | true 152 | true 153 | true 154 | d3d11.def 155 | d3d12.lib;%(AdditionalDependencies) 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | --------------------------------------------------------------------------------