diff options
Diffstat (limited to 'src/libs/dxvk-native-1.9.2a/src/d3d11/d3d11_main.cpp')
-rw-r--r-- | src/libs/dxvk-native-1.9.2a/src/d3d11/d3d11_main.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/src/libs/dxvk-native-1.9.2a/src/d3d11/d3d11_main.cpp b/src/libs/dxvk-native-1.9.2a/src/d3d11/d3d11_main.cpp new file mode 100644 index 00000000..c0be5283 --- /dev/null +++ b/src/libs/dxvk-native-1.9.2a/src/d3d11/d3d11_main.cpp @@ -0,0 +1,247 @@ +#include <array> + +#include "../dxgi/dxgi_adapter.h" + +#include "../dxvk/dxvk_instance.h" + +#include "d3d11_device.h" +#include "d3d11_enums.h" +#include "d3d11_interop.h" + +namespace dxvk { +#ifndef VBOX + Logger Logger::s_instance("d3d11.log"); +#endif +} + +extern "C" { + using namespace dxvk; + + DLLEXPORT HRESULT __stdcall D3D11CoreCreateDevice( + IDXGIFactory* pFactory, + IDXGIAdapter* pAdapter, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + ID3D11Device** ppDevice) { + InitReturnPtr(ppDevice); + + Rc<DxvkAdapter> dxvkAdapter; + Rc<DxvkInstance> dxvkInstance; + + Com<IDXGIDXVKAdapter> dxgiVkAdapter; + + // Try to find the corresponding Vulkan device for the DXGI adapter + if (SUCCEEDED(pAdapter->QueryInterface(__uuidof(IDXGIDXVKAdapter), reinterpret_cast<void**>(&dxgiVkAdapter)))) { + dxvkAdapter = dxgiVkAdapter->GetDXVKAdapter(); + dxvkInstance = dxgiVkAdapter->GetDXVKInstance(); + } else { + Logger::warn("D3D11CoreCreateDevice: Adapter is not a DXVK adapter"); + DXGI_ADAPTER_DESC desc; + pAdapter->GetDesc(&desc); + + dxvkInstance = new DxvkInstance(); + dxvkAdapter = dxvkInstance->findAdapterByLuid(&desc.AdapterLuid); + + if (dxvkAdapter == nullptr) + dxvkAdapter = dxvkInstance->findAdapterByDeviceId(desc.VendorId, desc.DeviceId); + + if (dxvkAdapter == nullptr) + dxvkAdapter = dxvkInstance->enumAdapters(0); + + if (dxvkAdapter == nullptr) + return E_FAIL; + } + + // Feature levels to probe if the + // application does not specify any. + std::array<D3D_FEATURE_LEVEL, 6> defaultFeatureLevels = { + D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1, + }; + + if (pFeatureLevels == nullptr || FeatureLevels == 0) { + pFeatureLevels = defaultFeatureLevels.data(); + FeatureLevels = defaultFeatureLevels.size(); + } + + // Find the highest feature level supported by the device. + // This works because the feature level array is ordered. + UINT flId; + + for (flId = 0 ; flId < FeatureLevels; flId++) { + Logger::info(str::format("D3D11CoreCreateDevice: Probing ", pFeatureLevels[flId])); + + if (D3D11Device::CheckFeatureLevelSupport(dxvkInstance, dxvkAdapter, pFeatureLevels[flId])) + break; + } + + if (flId == FeatureLevels) { + Logger::err("D3D11CoreCreateDevice: Requested feature level not supported"); + return E_INVALIDARG; + } + + // Try to create the device with the given parameters. + const D3D_FEATURE_LEVEL fl = pFeatureLevels[flId]; + + try { + Logger::info(str::format("D3D11CoreCreateDevice: Using feature level ", fl)); + Com<D3D11DXGIDevice> device = new D3D11DXGIDevice( + pAdapter, dxvkInstance, dxvkAdapter, fl, Flags); + + return device->QueryInterface( + __uuidof(ID3D11Device), + reinterpret_cast<void**>(ppDevice)); + } catch (const DxvkError& e) { + Logger::err("D3D11CoreCreateDevice: Failed to create D3D11 device"); + return E_FAIL; + } + } + + + static HRESULT D3D11InternalCreateDeviceAndSwapChain( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IDXGISwapChain** ppSwapChain, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext) { + InitReturnPtr(ppDevice); + InitReturnPtr(ppSwapChain); + InitReturnPtr(ppImmediateContext); + + if (pFeatureLevel) + *pFeatureLevel = D3D_FEATURE_LEVEL(0); + + HRESULT hr; + + Com<IDXGIFactory> dxgiFactory = nullptr; + Com<IDXGIAdapter> dxgiAdapter = pAdapter; + Com<ID3D11Device> device = nullptr; + + if (ppSwapChain && !pSwapChainDesc) + return E_INVALIDARG; + + if (!pAdapter) { + // We'll treat everything as hardware, even if the + // Vulkan device is actually a software device. + if (DriverType != D3D_DRIVER_TYPE_HARDWARE) + Logger::warn("D3D11CreateDevice: Unsupported driver type"); + + // We'll use the first adapter returned by a DXGI factory + hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory)); + + if (FAILED(hr)) { + Logger::err("D3D11CreateDevice: Failed to create a DXGI factory"); + return hr; + } + + hr = dxgiFactory->EnumAdapters(0, &dxgiAdapter); + + if (FAILED(hr)) { + Logger::err("D3D11CreateDevice: No default adapter available"); + return hr; + } + } else { + // We should be able to query the DXGI factory from the adapter + if (FAILED(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory)))) { + Logger::err("D3D11CreateDevice: Failed to query DXGI factory from DXGI adapter"); + return E_INVALIDARG; + } + + // In theory we could ignore these, but the Microsoft docs explicitly + // state that we need to return E_INVALIDARG in case the arguments are + // invalid. Both the driver type and software parameter can only be + // set if the adapter itself is unspecified. + // See: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082(v=vs.85).aspx + if (DriverType != D3D_DRIVER_TYPE_UNKNOWN || Software) + return E_INVALIDARG; + } + + // Create the actual device + hr = D3D11CoreCreateDevice( + dxgiFactory.ptr(), dxgiAdapter.ptr(), + Flags, pFeatureLevels, FeatureLevels, + &device); + + if (FAILED(hr)) + return hr; + + // Create the swap chain, if requested + if (ppSwapChain) { + DXGI_SWAP_CHAIN_DESC desc = *pSwapChainDesc; + hr = dxgiFactory->CreateSwapChain(device.ptr(), &desc, ppSwapChain); + + if (FAILED(hr)) { + Logger::err("D3D11CreateDevice: Failed to create swap chain"); + return hr; + } + } + + // Write back whatever info the application requested + if (pFeatureLevel) + *pFeatureLevel = device->GetFeatureLevel(); + + if (ppDevice) + *ppDevice = device.ref(); + + if (ppImmediateContext) + device->GetImmediateContext(ppImmediateContext); + + // If we were unable to write back the device and the + // swap chain, the application has no way of working + // with the device so we should report S_FALSE here. + if (!ppDevice && !ppImmediateContext && !ppSwapChain) + return S_FALSE; + + return S_OK; + } + + + DLLEXPORT HRESULT __stdcall D3D11CreateDevice( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext) { + return D3D11InternalCreateDeviceAndSwapChain( + pAdapter, DriverType, Software, Flags, + pFeatureLevels, FeatureLevels, SDKVersion, + nullptr, nullptr, + ppDevice, pFeatureLevel, ppImmediateContext); + } + + + DLLEXPORT HRESULT __stdcall D3D11CreateDeviceAndSwapChain( + IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, + IDXGISwapChain** ppSwapChain, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext) { + return D3D11InternalCreateDeviceAndSwapChain( + pAdapter, DriverType, Software, Flags, + pFeatureLevels, FeatureLevels, SDKVersion, + pSwapChainDesc, ppSwapChain, + ppDevice, pFeatureLevel, ppImmediateContext); + } + +}
\ No newline at end of file |