2017-10-11 15:32:24 +02:00
|
|
|
#include <array>
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
#include "../dxgi/dxgi_adapter.h"
|
2017-10-11 09:51:48 +02:00
|
|
|
|
2018-12-03 21:18:40 +01:00
|
|
|
#include "../dxvk/dxvk_instance.h"
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
#include "d3d11_device.h"
|
2017-12-02 16:47:06 +01:00
|
|
|
#include "d3d11_enums.h"
|
2018-04-20 00:19:03 +02:00
|
|
|
#include "d3d11_interop.h"
|
2017-10-11 09:51:48 +02:00
|
|
|
|
2017-12-06 23:36:11 +01:00
|
|
|
namespace dxvk {
|
|
|
|
Logger Logger::s_instance("d3d11.log");
|
|
|
|
}
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
extern "C" {
|
2017-10-11 15:32:24 +02:00
|
|
|
using namespace dxvk;
|
2017-10-11 09:51:48 +02:00
|
|
|
|
2018-05-07 14:06:52 +02:00
|
|
|
DLLEXPORT HRESULT __stdcall D3D11CoreCreateDevice(
|
|
|
|
IDXGIFactory* pFactory,
|
|
|
|
IDXGIAdapter* pAdapter,
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT Flags,
|
2018-05-07 14:06:52 +02:00
|
|
|
const D3D_FEATURE_LEVEL* pFeatureLevels,
|
2017-10-11 09:51:48 +02:00
|
|
|
UINT FeatureLevels,
|
2018-05-07 14:06:52 +02:00
|
|
|
ID3D11Device** ppDevice) {
|
2019-02-27 21:13:03 +00:00
|
|
|
InitReturnPtr(ppDevice);
|
|
|
|
|
2018-12-03 21:18:40 +01:00
|
|
|
Rc<DxvkAdapter> dxvkAdapter;
|
|
|
|
Rc<DxvkInstance> dxvkInstance;
|
|
|
|
|
2019-09-18 14:07:01 +02:00
|
|
|
Com<IDXGIDXVKAdapter> dxgiVkAdapter;
|
2017-10-11 15:32:24 +02:00
|
|
|
|
2018-12-03 21:18:40 +01:00
|
|
|
// Try to find the corresponding Vulkan device for the DXGI adapter
|
2019-09-18 14:07:01 +02:00
|
|
|
if (SUCCEEDED(pAdapter->QueryInterface(__uuidof(IDXGIDXVKAdapter), reinterpret_cast<void**>(&dxgiVkAdapter)))) {
|
2018-12-03 21:18:40 +01:00
|
|
|
dxvkAdapter = dxgiVkAdapter->GetDXVKAdapter();
|
2019-11-08 11:25:58 +01:00
|
|
|
dxvkInstance = dxgiVkAdapter->GetDXVKInstance();
|
2018-12-03 21:18:40 +01:00
|
|
|
} 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;
|
2017-10-11 15:32:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
};
|
|
|
|
|
2022-09-03 15:24:40 +02:00
|
|
|
if (!pFeatureLevels || !FeatureLevels) {
|
2017-10-11 15:32:24 +02:00
|
|
|
pFeatureLevels = defaultFeatureLevels.data();
|
|
|
|
FeatureLevels = defaultFeatureLevels.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the highest feature level supported by the device.
|
|
|
|
// This works because the feature level array is ordered.
|
2022-09-03 15:24:40 +02:00
|
|
|
D3D_FEATURE_LEVEL maxFeatureLevel = D3D11Device::GetMaxFeatureLevel(dxvkInstance, dxvkAdapter);
|
|
|
|
D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL();
|
|
|
|
D3D_FEATURE_LEVEL devFeatureLevel = D3D_FEATURE_LEVEL();
|
2018-12-03 21:18:40 +01:00
|
|
|
|
2022-09-03 15:24:40 +02:00
|
|
|
Logger::info(str::format("D3D11CoreCreateDevice: Maximum supported feature level: ", maxFeatureLevel));
|
|
|
|
|
|
|
|
for (uint32_t flId = 0 ; flId < FeatureLevels; flId++) {
|
|
|
|
minFeatureLevel = pFeatureLevels[flId];
|
|
|
|
|
|
|
|
if (minFeatureLevel <= maxFeatureLevel) {
|
|
|
|
devFeatureLevel = minFeatureLevel;
|
2017-10-11 15:32:24 +02:00
|
|
|
break;
|
2022-09-03 15:24:40 +02:00
|
|
|
}
|
2017-10-11 15:32:24 +02:00
|
|
|
}
|
2022-09-03 15:24:40 +02:00
|
|
|
|
|
|
|
if (!devFeatureLevel) {
|
|
|
|
Logger::err(str::format("D3D11CoreCreateDevice: Minimum required feature level ", minFeatureLevel, " not supported"));
|
2017-12-09 13:43:14 +01:00
|
|
|
return E_INVALIDARG;
|
2017-10-11 15:32:24 +02:00
|
|
|
}
|
2022-09-03 15:24:40 +02:00
|
|
|
|
2017-10-11 15:32:24 +02:00
|
|
|
try {
|
2022-09-03 15:24:40 +02:00
|
|
|
Logger::info(str::format("D3D11CoreCreateDevice: Using feature level ", devFeatureLevel));
|
|
|
|
|
2023-03-16 01:34:49 +01:00
|
|
|
DxvkDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(dxvkAdapter);
|
|
|
|
Rc<DxvkDevice> dxvkDevice = dxvkAdapter->createDevice(dxvkInstance, deviceFeatures);
|
|
|
|
|
2018-12-03 19:26:29 +01:00
|
|
|
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
|
2023-03-16 01:34:49 +01:00
|
|
|
pAdapter, nullptr, nullptr,
|
|
|
|
dxvkInstance, dxvkAdapter, dxvkDevice,
|
|
|
|
devFeatureLevel, Flags);
|
2022-09-03 15:24:40 +02:00
|
|
|
|
2018-12-03 19:26:29 +01:00
|
|
|
return device->QueryInterface(
|
|
|
|
__uuidof(ID3D11Device),
|
|
|
|
reinterpret_cast<void**>(ppDevice));
|
2017-10-11 15:32:24 +02:00
|
|
|
} catch (const DxvkError& e) {
|
2018-05-07 14:06:52 +02:00
|
|
|
Logger::err("D3D11CoreCreateDevice: Failed to create D3D11 device");
|
2017-10-11 15:32:24 +02:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
static HRESULT D3D11InternalCreateDeviceAndSwapChain(
|
2018-05-07 14:06:52 +02:00
|
|
|
IDXGIAdapter* pAdapter,
|
|
|
|
D3D_DRIVER_TYPE DriverType,
|
|
|
|
HMODULE Software,
|
|
|
|
UINT Flags,
|
|
|
|
const D3D_FEATURE_LEVEL* pFeatureLevels,
|
|
|
|
UINT FeatureLevels,
|
|
|
|
UINT SDKVersion,
|
2019-05-15 16:45:37 +02:00
|
|
|
const DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
|
|
|
|
IDXGISwapChain** ppSwapChain,
|
2018-05-07 14:06:52 +02:00
|
|
|
ID3D11Device** ppDevice,
|
|
|
|
D3D_FEATURE_LEVEL* pFeatureLevel,
|
|
|
|
ID3D11DeviceContext** ppImmediateContext) {
|
2019-02-27 21:13:03 +00:00
|
|
|
InitReturnPtr(ppDevice);
|
2019-05-15 16:45:37 +02:00
|
|
|
InitReturnPtr(ppSwapChain);
|
2019-02-27 21:13:03 +00:00
|
|
|
InitReturnPtr(ppImmediateContext);
|
|
|
|
|
2019-10-11 17:01:23 +02:00
|
|
|
if (pFeatureLevel)
|
|
|
|
*pFeatureLevel = D3D_FEATURE_LEVEL(0);
|
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
HRESULT hr;
|
|
|
|
|
2018-05-07 14:06:52 +02:00
|
|
|
Com<IDXGIFactory> dxgiFactory = nullptr;
|
|
|
|
Com<IDXGIAdapter> dxgiAdapter = pAdapter;
|
2019-05-15 16:45:37 +02:00
|
|
|
Com<ID3D11Device> device = nullptr;
|
2018-05-07 14:06:52 +02:00
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
if (ppSwapChain && !pSwapChainDesc)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
if (!pAdapter) {
|
2018-05-07 14:06:52 +02:00
|
|
|
// 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
|
2019-05-15 16:45:37 +02:00
|
|
|
hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory));
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
2018-05-07 14:06:52 +02:00
|
|
|
Logger::err("D3D11CreateDevice: Failed to create a DXGI factory");
|
2019-05-15 16:45:37 +02:00
|
|
|
return hr;
|
2018-05-07 14:06:52 +02:00
|
|
|
}
|
2019-05-15 16:45:37 +02:00
|
|
|
|
|
|
|
hr = dxgiFactory->EnumAdapters(0, &dxgiAdapter);
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
2018-05-07 14:06:52 +02:00
|
|
|
Logger::err("D3D11CreateDevice: No default adapter available");
|
2019-05-15 16:45:37 +02:00
|
|
|
return hr;
|
2018-05-07 14:06:52 +02:00
|
|
|
}
|
|
|
|
} 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");
|
2019-05-15 16:45:37 +02:00
|
|
|
return E_INVALIDARG;
|
2018-05-07 14:06:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2019-05-15 16:45:37 +02:00
|
|
|
if (DriverType != D3D_DRIVER_TYPE_UNKNOWN || Software)
|
2018-05-07 14:06:52 +02:00
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the actual device
|
2019-05-15 16:45:37 +02:00
|
|
|
hr = D3D11CoreCreateDevice(
|
2018-05-07 14:06:52 +02:00
|
|
|
dxgiFactory.ptr(), dxgiAdapter.ptr(),
|
|
|
|
Flags, pFeatureLevels, FeatureLevels,
|
|
|
|
&device);
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
return hr;
|
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-07 14:06:52 +02:00
|
|
|
// Write back whatever info the application requested
|
2019-05-15 16:45:37 +02:00
|
|
|
if (pFeatureLevel)
|
2018-05-07 14:06:52 +02:00
|
|
|
*pFeatureLevel = device->GetFeatureLevel();
|
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
if (ppDevice)
|
2018-05-07 14:06:52 +02:00
|
|
|
*ppDevice = device.ref();
|
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
if (ppImmediateContext)
|
2018-05-07 14:06:52 +02:00
|
|
|
device->GetImmediateContext(ppImmediateContext);
|
2019-05-15 16:45:37 +02:00
|
|
|
|
2018-05-07 14:06:52 +02:00
|
|
|
// 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.
|
2019-05-15 16:45:37 +02:00
|
|
|
if (!ppDevice && !ppImmediateContext && !ppSwapChain)
|
2018-05-07 14:06:52 +02:00
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 16:45:37 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-05-07 14:06:52 +02:00
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
DLLEXPORT HRESULT __stdcall D3D11CreateDeviceAndSwapChain(
|
2018-05-07 14:06:52 +02:00
|
|
|
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) {
|
2019-05-15 16:45:37 +02:00
|
|
|
return D3D11InternalCreateDeviceAndSwapChain(
|
|
|
|
pAdapter, DriverType, Software, Flags,
|
|
|
|
pFeatureLevels, FeatureLevels, SDKVersion,
|
|
|
|
pSwapChainDesc, ppSwapChain,
|
|
|
|
ppDevice, pFeatureLevel, ppImmediateContext);
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|
2017-10-11 15:32:24 +02:00
|
|
|
|
2022-02-06 20:50:26 +01:00
|
|
|
|
|
|
|
DLLEXPORT HRESULT __stdcall D3D11On12CreateDevice(
|
|
|
|
IUnknown* pDevice,
|
|
|
|
UINT Flags,
|
|
|
|
const D3D_FEATURE_LEVEL* pFeatureLevels,
|
|
|
|
UINT FeatureLevels,
|
|
|
|
IUnknown* const* ppCommandQueues,
|
|
|
|
UINT NumQueues,
|
|
|
|
UINT NodeMask,
|
|
|
|
ID3D11Device** ppDevice,
|
|
|
|
ID3D11DeviceContext** ppImmediateContext,
|
|
|
|
D3D_FEATURE_LEVEL* pChosenFeatureLevel) {
|
2023-03-16 01:34:49 +01:00
|
|
|
InitReturnPtr(ppDevice);
|
|
|
|
InitReturnPtr(ppImmediateContext);
|
|
|
|
|
|
|
|
if (pChosenFeatureLevel)
|
|
|
|
*pChosenFeatureLevel = D3D_FEATURE_LEVEL(0);
|
|
|
|
|
|
|
|
if (!pDevice)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
// Figure out D3D12 objects
|
|
|
|
Com<ID3D12Device> d3d12Device;
|
|
|
|
Com<ID3D12CommandQueue> d3d12Queue;
|
|
|
|
|
|
|
|
if (FAILED(pDevice->QueryInterface(__uuidof(ID3D12Device), reinterpret_cast<void**>(&d3d12Device)))) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: Device is not a valid D3D12 device");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NodeMask & (NodeMask - 1)) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: Invalid node mask");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!NumQueues || !ppCommandQueues || !ppCommandQueues[0]) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: No command queue specified");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NumQueues > 1) {
|
|
|
|
// Not sure what to do with more than one graphics queue
|
|
|
|
Logger::warn("D3D11On12CreateDevice: Only one queue supported");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FAILED(ppCommandQueues[0]->QueryInterface(__uuidof(ID3D12CommandQueue), reinterpret_cast<void**>(&d3d12Queue)))) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: Queue is not a valid D3D12 command queue");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine feature level for the D3D11 device
|
|
|
|
std::array<D3D_FEATURE_LEVEL, 4> defaultFeatureLevels = {{
|
|
|
|
D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1,
|
|
|
|
D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_1,
|
|
|
|
}};
|
|
|
|
|
|
|
|
D3D12_FEATURE_DATA_FEATURE_LEVELS featureLevel = { };
|
|
|
|
|
|
|
|
if (!FeatureLevels || !pFeatureLevels) {
|
|
|
|
featureLevel.NumFeatureLevels = defaultFeatureLevels.size();
|
|
|
|
featureLevel.pFeatureLevelsRequested = defaultFeatureLevels.data();
|
|
|
|
} else {
|
|
|
|
featureLevel.NumFeatureLevels = FeatureLevels;
|
|
|
|
featureLevel.pFeatureLevelsRequested = pFeatureLevels;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT hr = d3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featureLevel, sizeof(featureLevel));
|
|
|
|
|
|
|
|
if (FAILED(hr) || !featureLevel.MaxSupportedFeatureLevel) {
|
|
|
|
Logger::err(str::format("D3D11On12CreateDevice: Minimum required feature level not supported"));
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger::info(str::format("D3D11On12CreateDevice: Chosen feature level: ", featureLevel.MaxSupportedFeatureLevel));
|
|
|
|
|
|
|
|
Com<ID3D12DXVKInteropDevice> interopDevice;
|
|
|
|
|
|
|
|
if (FAILED(d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice)))) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: Device not a vkd3d-proton device.");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
2022-02-06 20:50:26 +01:00
|
|
|
|
2023-03-16 01:34:49 +01:00
|
|
|
Com<IDXGIAdapter> dxgiAdapter;
|
2022-02-06 20:50:26 +01:00
|
|
|
|
2023-03-16 01:34:49 +01:00
|
|
|
if (FAILED(interopDevice->GetDXGIAdapter(IID_PPV_ARGS(&dxgiAdapter)))) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: Failed to query DXGI adapter.");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Initialize DXVK instance
|
|
|
|
DxvkInstanceImportInfo instanceInfo = { };
|
|
|
|
DxvkDeviceImportInfo deviceInfo = { };
|
|
|
|
VkPhysicalDevice vulkanAdapter = VK_NULL_HANDLE;
|
|
|
|
|
|
|
|
interopDevice->GetVulkanHandles(&instanceInfo.instance, &vulkanAdapter, &deviceInfo.device);
|
|
|
|
|
|
|
|
uint32_t instanceExtensionCount = 0;
|
|
|
|
interopDevice->GetInstanceExtensions(&instanceExtensionCount, nullptr);
|
|
|
|
|
|
|
|
std::vector<const char*> instanceExtensions(instanceExtensionCount);
|
|
|
|
interopDevice->GetInstanceExtensions(&instanceExtensionCount, instanceExtensions.data());
|
|
|
|
|
|
|
|
instanceInfo.extensionCount = instanceExtensions.size();
|
|
|
|
instanceInfo.extensionNames = instanceExtensions.data();
|
|
|
|
|
|
|
|
Rc<DxvkInstance> dxvkInstance = new DxvkInstance(instanceInfo);
|
|
|
|
|
|
|
|
// Find adapter by physical device handle
|
|
|
|
Rc<DxvkAdapter> dxvkAdapter;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < dxvkInstance->adapterCount(); i++) {
|
|
|
|
Rc<DxvkAdapter> curr = dxvkInstance->enumAdapters(i);
|
|
|
|
|
|
|
|
if (curr->handle() == vulkanAdapter)
|
|
|
|
dxvkAdapter = std::move(curr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dxvkAdapter == nullptr) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: No matching adapter found");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
interopDevice->GetVulkanQueueInfo(d3d12Queue.ptr(), &deviceInfo.queue, &deviceInfo.queueFamily);
|
|
|
|
interopDevice->GetDeviceFeatures(&deviceInfo.features);
|
|
|
|
|
|
|
|
uint32_t deviceExtensionCount = 0;
|
|
|
|
interopDevice->GetDeviceExtensions(&deviceExtensionCount, nullptr);
|
|
|
|
|
|
|
|
std::vector<const char*> deviceExtensions(deviceExtensionCount);
|
|
|
|
interopDevice->GetDeviceExtensions(&deviceExtensionCount, deviceExtensions.data());
|
|
|
|
|
|
|
|
deviceInfo.extensionCount = deviceExtensions.size();
|
|
|
|
deviceInfo.extensionNames = deviceExtensions.data();
|
|
|
|
|
|
|
|
deviceInfo.queueCallback = [
|
|
|
|
cDevice = interopDevice,
|
|
|
|
cQueue = d3d12Queue
|
|
|
|
] (bool doLock) {
|
|
|
|
HRESULT hr = doLock
|
|
|
|
? cDevice->LockCommandQueue(cQueue.ptr())
|
|
|
|
: cDevice->UnlockCommandQueue(cQueue.ptr());
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
Logger::err(str::format("Failed to lock vkd3d-proton device queue: ", hr));
|
|
|
|
};
|
|
|
|
|
|
|
|
Rc<DxvkDevice> dxvkDevice = dxvkAdapter->importDevice(dxvkInstance, deviceInfo);
|
|
|
|
|
|
|
|
// Create and return the actual D3D11 device
|
|
|
|
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
|
|
|
|
dxgiAdapter.ptr(), d3d12Device.ptr(), d3d12Queue.ptr(),
|
|
|
|
dxvkInstance, dxvkAdapter, dxvkDevice,
|
|
|
|
featureLevel.MaxSupportedFeatureLevel, Flags);
|
|
|
|
|
|
|
|
Com<ID3D11Device> d3d11Device;
|
|
|
|
device->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void**>(&d3d11Device));
|
|
|
|
|
|
|
|
if (ppDevice)
|
|
|
|
*ppDevice = d3d11Device.ref();
|
|
|
|
|
|
|
|
if (ppImmediateContext)
|
|
|
|
d3d11Device->GetImmediateContext(ppImmediateContext);
|
|
|
|
|
|
|
|
if (pChosenFeatureLevel)
|
|
|
|
*pChosenFeatureLevel = d3d11Device->GetFeatureLevel();
|
|
|
|
|
|
|
|
if (!ppDevice && !ppImmediateContext)
|
|
|
|
return S_FALSE;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
} catch (const DxvkError& e) {
|
|
|
|
Logger::err("D3D11On12CreateDevice: Failed to create D3D11 device");
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
2022-02-06 20:50:26 +01:00
|
|
|
}
|
|
|
|
|
2017-10-11 09:51:48 +02:00
|
|
|
}
|