summaryrefslogtreecommitdiffstats
path: root/src/libs/dxvk-native-1.9.2a/src/d3d11/d3d11_main.cpp
diff options
context:
space:
mode:
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.cpp247
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