mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[d3d9] Add device import interop API
This commit is contained in:
parent
afc24ddbe9
commit
91e5e18141
3 changed files with 164 additions and 0 deletions
|
@ -3,6 +3,27 @@
|
|||
#include "d3d9_include.h"
|
||||
#include "../vulkan/vulkan_loader.h"
|
||||
|
||||
using D3D9VkQueueLockCallback = void(bool);
|
||||
|
||||
/**
|
||||
* \brief Device import info
|
||||
*/
|
||||
struct D3D9VkDeviceImportInfo {
|
||||
VkDevice device;
|
||||
D3DDEVTYPE deviceType;
|
||||
VkQueue graphicsQueue;
|
||||
uint32_t graphicsQueueFamily;
|
||||
VkQueue transferQueue;
|
||||
uint32_t transferQueueFamily;
|
||||
VkQueue sparseQueue;
|
||||
uint32_t sparseQueueFamily;
|
||||
uint32_t extensionCount;
|
||||
const char** extensionNames;
|
||||
const VkPhysicalDeviceFeatures2* features;
|
||||
D3D9VkQueueLockCallback* queueLockCallback;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief D3D9 interface for Vulkan interop
|
||||
*
|
||||
|
@ -28,6 +49,39 @@ ID3D9VkInteropInterface : public IUnknown {
|
|||
virtual void STDMETHODCALLTYPE GetPhysicalDeviceHandle(
|
||||
UINT Adapter,
|
||||
VkPhysicalDevice* pPhysicalDevice) = 0;
|
||||
|
||||
/**
|
||||
* \brief Gets the VkDeviceCreateInfo for a D3D9 adapter
|
||||
*
|
||||
* \param [in] Adapter Adapter ordinal
|
||||
* \param [out] pCreateInfo The Vulkan device create info
|
||||
*/
|
||||
virtual HRESULT STDMETHODCALLTYPE GetDeviceCreateInfo(
|
||||
UINT Adapter,
|
||||
VkDeviceCreateInfo* pCreateInfo) = 0;
|
||||
|
||||
/**
|
||||
* \brief Create a D3D9 device for an existing Vulkan device
|
||||
*
|
||||
* It is suggested to create the device with the
|
||||
* VkDeviceCreateInfo returned by GetDeviceCreateInfo,
|
||||
* which will specify everything the device needs for
|
||||
* DXVK to function.
|
||||
*
|
||||
* \param [in] Adapter Adapter ordinal
|
||||
* \param [in] ... Arguments to IDirect3D9Ex::CreateDeviceEx
|
||||
* \param [in] pInfo Info about the created device
|
||||
* \param [out] ppReturnedDevice The D3D9 device
|
||||
*/
|
||||
virtual HRESULT STDMETHODCALLTYPE ImportDevice(
|
||||
UINT Adapter,
|
||||
D3DDEVTYPE DeviceType,
|
||||
HWND hFocusWindow,
|
||||
DWORD BehaviorFlags,
|
||||
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||
D3DDISPLAYMODEEX* pFullscreenDisplayMode,
|
||||
D3D9VkDeviceImportInfo* pInfo,
|
||||
IDirect3DDevice9Ex** ppReturnedDevice) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,6 +51,102 @@ namespace dxvk {
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::GetDeviceCreateInfo(
|
||||
UINT Adapter,
|
||||
VkDeviceCreateInfo* pCreateInfo) {
|
||||
if (unlikely(pCreateInfo == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
auto* adapter = m_interface->GetAdapter(Adapter);
|
||||
|
||||
if (adapter == nullptr)
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
auto dxvkAdapter = adapter->GetDXVKAdapter();
|
||||
|
||||
DxvkDeviceCreateInfo createInfo;
|
||||
if (!dxvkAdapter->getDeviceCreateInfo(m_interface->GetInstance(), D3D9DeviceEx::GetDeviceFeatures(dxvkAdapter), false, createInfo))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
*pCreateInfo = createInfo.info;
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::ImportDevice(
|
||||
UINT Adapter,
|
||||
D3DDEVTYPE DeviceType,
|
||||
HWND hFocusWindow,
|
||||
DWORD BehaviorFlags,
|
||||
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||
D3DDISPLAYMODEEX* pFullscreenDisplayMode,
|
||||
D3D9VkDeviceImportInfo* pInfo,
|
||||
IDirect3DDevice9Ex** ppReturnedDevice) {
|
||||
InitReturnPtr(ppReturnedDevice);
|
||||
|
||||
if (unlikely(ppReturnedDevice == nullptr
|
||||
|| pPresentationParameters == nullptr))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
// Creating a device with D3DCREATE_PUREDEVICE only works in conjunction
|
||||
// with D3DCREATE_HARDWARE_VERTEXPROCESSING on native drivers.
|
||||
if (unlikely(BehaviorFlags & D3DCREATE_PUREDEVICE &&
|
||||
!(BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
HRESULT hr;
|
||||
// Black Desert creates a D3DDEVTYPE_NULLREF device and
|
||||
// expects it be created despite passing invalid parameters.
|
||||
if (likely(DeviceType != D3DDEVTYPE_NULLREF)) {
|
||||
hr = m_interface->ValidatePresentationParameters(pPresentationParameters);
|
||||
|
||||
if (unlikely(FAILED(hr)))
|
||||
return hr;
|
||||
}
|
||||
|
||||
auto* adapter = m_interface->GetAdapter(Adapter);
|
||||
|
||||
if (adapter == nullptr)
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
auto dxvkAdapter = adapter->GetDXVKAdapter();
|
||||
|
||||
DxvkDeviceImportInfo info;
|
||||
info.device = pInfo->device;
|
||||
info.queue = pInfo->graphicsQueue;
|
||||
info.queueFamily = pInfo->graphicsQueueFamily;
|
||||
info.extensionCount = pInfo->extensionCount;
|
||||
info.extensionNames = pInfo->extensionNames;
|
||||
info.features = pInfo->features;
|
||||
info.queueCallback = pInfo->queueLockCallback;
|
||||
|
||||
try {
|
||||
auto dxvkDevice = dxvkAdapter->importDevice(m_interface->GetInstance(), info);
|
||||
|
||||
auto* device = new D3D9DeviceEx(
|
||||
m_interface,
|
||||
adapter,
|
||||
DeviceType,
|
||||
hFocusWindow,
|
||||
BehaviorFlags,
|
||||
dxvkDevice);
|
||||
|
||||
hr = device->InitialReset(pPresentationParameters, pFullscreenDisplayMode);
|
||||
|
||||
if (unlikely(FAILED(hr)))
|
||||
return hr;
|
||||
|
||||
*ppReturnedDevice = ref(device);
|
||||
}
|
||||
catch (const DxvkError& e) {
|
||||
Logger::err(e.message());
|
||||
return D3DERR_NOTAVAILABLE;
|
||||
}
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Texture Interop
|
||||
///////////////////////////////
|
||||
|
|
|
@ -34,6 +34,20 @@ namespace dxvk {
|
|||
UINT Adapter,
|
||||
VkPhysicalDevice* pPhysicalDevice);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetDeviceCreateInfo(
|
||||
UINT Adapter,
|
||||
VkDeviceCreateInfo* pCreateInfo);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE ImportDevice(
|
||||
UINT Adapter,
|
||||
D3DDEVTYPE DeviceType,
|
||||
HWND hFocusWindow,
|
||||
DWORD BehaviorFlags,
|
||||
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||
D3DDISPLAYMODEEX* pFullscreenDisplayMode,
|
||||
D3D9VkDeviceImportInfo* pInfo,
|
||||
IDirect3DDevice9Ex** ppReturnedDevice);
|
||||
|
||||
private:
|
||||
|
||||
D3D9InterfaceEx* m_interface;
|
||||
|
|
Loading…
Add table
Reference in a new issue