diff --git a/src/d3d9/d3d9.def b/src/d3d9/d3d9.def index 3042268e2..96ae240f8 100644 --- a/src/d3d9/d3d9.def +++ b/src/d3d9/d3d9.def @@ -25,3 +25,6 @@ EXPORTS DXVK_UnRegisterAnnotation @28258 NONAME Direct3D9ForceHybridEnumeration @16 NONAME PRIVATE + + Direct3DCreate9On12 @20 + Direct3DCreate9On12Ex @21 diff --git a/src/d3d9/d3d9.sym b/src/d3d9/d3d9.sym index fd2e67c5f..bbfaee0a3 100644 --- a/src/d3d9/d3d9.sym +++ b/src/d3d9/d3d9.sym @@ -18,6 +18,8 @@ DXVK_RegisterAnnotation; DXVK_UnRegisterAnnotation; Direct3D9ForceHybridEnumeration; + Direct3DCreate9On12; + Direct3DCreate9On12Ex; local: *; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 6a5f5492b..2c4b5b1cf 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -55,7 +55,8 @@ namespace dxvk { , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? true : false ) , m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) ) , m_csChunk ( AllocCsChunk() ) - , m_d3d9Interop ( this ) { + , m_d3d9Interop ( this ) + , m_d3d9On12 ( this ) { // If we can SWVP, then we use an extended constant set // as SWVP has many more slots available than HWVP. bool canSWVP = CanSWVP(); @@ -205,6 +206,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(IDirect3DDevice9On12)) { + *ppvObject = ref(&m_d3d9On12); + return S_OK; + } + // We want to ignore this if the extended device is queried and we weren't made extended. if (riid == __uuidof(IDirect3DDevice9Ex)) return E_NOINTERFACE; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index c73fcb407..eba85c0b8 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -28,6 +28,7 @@ #include "d3d9_spec_constants.h" #include "d3d9_interop.h" +#include "d3d9_on_12.h" #include #include @@ -1375,6 +1376,7 @@ namespace dxvk { Direct3DState9 m_state; D3D9VkInteropDevice m_d3d9Interop; + D3D9On12 m_d3d9On12; }; } diff --git a/src/d3d9/d3d9_include.h b/src/d3d9/d3d9_include.h index 896e7df95..2492f3ae2 100644 --- a/src/d3d9/d3d9_include.h +++ b/src/d3d9/d3d9_include.h @@ -60,3 +60,50 @@ typedef struct _D3DDEVINFO_RESOURCEMANAGER #define D3DPOOL_MANAGED_EX D3DPOOL(6) using D3D9VertexElements = std::vector; + +///////////////////// +// D3D9On12 content +///////////////////// + +#include + +#define MAX_D3D9ON12_QUEUES 2 + +struct D3D9ON12_ARGS { + BOOL Enable9On12; + IUnknown* pD3D12Device; + IUnknown* ppD3D12Queues[MAX_D3D9ON12_QUEUES]; + UINT NumQueues; + UINT NodeMask; +}; + +extern "C" { + + // Ordinal 20 + typedef IDirect3D9* (WINAPI* PFN_Direct3DCreate9On12)(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count); + IDirect3D9* WINAPI Direct3DCreate9On12(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count); + + // Ordinal 21 + typedef HRESULT(WINAPI* PFN_Direct3DCreate9On12Ex)(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count, IDirect3D9Ex** output); + HRESULT WINAPI Direct3DCreate9On12Ex(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count, IDirect3D9Ex** output); + +} + +MIDL_INTERFACE("e7fda234-b589-4049-940d-8878977531c8") +IDirect3DDevice9On12 : public IUnknown { + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** object) = 0; + virtual ULONG STDMETHODCALLTYPE AddRef() = 0; + virtual ULONG STDMETHODCALLTYPE Release() = 0; + + virtual HRESULT STDMETHODCALLTYPE GetD3D12Device(REFIID riid, void** object) = 0; + virtual HRESULT STDMETHODCALLTYPE UnwrapUnderlyingResource(IDirect3DResource9* resource, ID3D12CommandQueue* command_queue, REFIID riid, void** object) = 0; + virtual HRESULT STDMETHODCALLTYPE ReturnUnderlyingResource(IDirect3DResource9* resource, UINT num_sync, UINT64* signal_values, ID3D12Fence** fences) = 0; +}; + +#ifdef _MSC_VER +struct __declspec(uuid("e7fda234-b589-4049-940d-8878977531c8")) IDirect3DDevice9On12; +#else +__CRT_UUID_DECL(IDirect3DDevice9On12, 0xe7fda234,0xb589,0x4049,0x94,0x0d,0x88,0x78,0x97,0x75,0x31,0xc8); +#endif + diff --git a/src/d3d9/d3d9_main.cpp b/src/d3d9/d3d9_main.cpp index e182b5fa3..9e7aaa24d 100644 --- a/src/d3d9/d3d9_main.cpp +++ b/src/d3d9/d3d9_main.cpp @@ -101,4 +101,14 @@ extern "C" { DLLEXPORT void __stdcall Direct3D9ForceHybridEnumeration(UINT uHybrid) { } + DLLEXPORT IDirect3D9* __stdcall Direct3DCreate9On12(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count) { + dxvk::Logger::warn("Direct3DCreate9On12: 9On12 functionality is unimplemented."); + return Direct3DCreate9(sdk_version); + } + + DLLEXPORT HRESULT __stdcall Direct3DCreate9On12Ex(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count, IDirect3D9Ex** output) { + dxvk::Logger::warn("Direct3DCreate9On12Ex: 9On12 functionality is unimplemented."); + return Direct3DCreate9Ex(sdk_version, output); + } + } diff --git a/src/d3d9/d3d9_on_12.cpp b/src/d3d9/d3d9_on_12.cpp new file mode 100644 index 000000000..38885894c --- /dev/null +++ b/src/d3d9/d3d9_on_12.cpp @@ -0,0 +1,37 @@ +#include "d3d9_on_12.h" + +#include "d3d9_device.h" + +namespace dxvk { + + D3D9On12::D3D9On12(D3D9DeviceEx* device) + : m_device(device) { + + } + + HRESULT STDMETHODCALLTYPE D3D9On12::QueryInterface(REFIID riid, void** object) { + return m_device->QueryInterface(riid, object); + } + ULONG STDMETHODCALLTYPE D3D9On12::AddRef() { + return m_device->AddRef(); + } + ULONG STDMETHODCALLTYPE D3D9On12::Release() { + return m_device->Release(); + } + + HRESULT STDMETHODCALLTYPE D3D9On12::GetD3D12Device(REFIID riid, void** object) { + InitReturnPtr(object); + + Logger::err("D3D9On12::GetD3D12Device: Stub"); + return E_NOINTERFACE; + } + HRESULT STDMETHODCALLTYPE D3D9On12::UnwrapUnderlyingResource(IDirect3DResource9* resource, ID3D12CommandQueue* command_queue, REFIID riid, void** object) { + Logger::err("D3D9On12::GetD3D12Device: UnwrapUnderlyingResource: Stub"); + return E_NOINTERFACE; + } + HRESULT STDMETHODCALLTYPE D3D9On12::ReturnUnderlyingResource(IDirect3DResource9* resource, UINT num_sync, UINT64* signal_values, ID3D12Fence** fences) { + Logger::err("D3D9On12::GetD3D12Device: ReturnUnderlyingResource: Stub"); + return E_NOINTERFACE; + } + +} diff --git a/src/d3d9/d3d9_on_12.h b/src/d3d9/d3d9_on_12.h new file mode 100644 index 000000000..7af5c987b --- /dev/null +++ b/src/d3d9/d3d9_on_12.h @@ -0,0 +1,29 @@ +#pragma once + +#include "d3d9_include.h" + +namespace dxvk { + + class D3D9DeviceEx; + + class D3D9On12 final : public IDirect3DDevice9On12 { + + public: + + D3D9On12(D3D9DeviceEx* device); + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** object); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE GetD3D12Device(REFIID riid, void** object); + HRESULT STDMETHODCALLTYPE UnwrapUnderlyingResource(IDirect3DResource9* resource, ID3D12CommandQueue* command_queue, REFIID riid, void** object); + HRESULT STDMETHODCALLTYPE ReturnUnderlyingResource(IDirect3DResource9* resource, UINT num_sync, UINT64* signal_values, ID3D12Fence** fences); + + private: + + D3D9DeviceEx* m_device; + + }; + +} diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 9e27c6e83..8a49a9db1 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -44,7 +44,8 @@ d3d9_src = [ 'd3d9_annotation.cpp', 'd3d9_mem.cpp', 'd3d9_window.cpp', - 'd3d9_interop.cpp' + 'd3d9_interop.cpp', + 'd3d9_on_12.cpp' ] d3d9_ld_args = []