From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Orbiter Space Flight Simulator and Train Simulator Classic. --- dlls/d3d9/Makefile.in | 1 + dlls/d3d9/d3d9.spec | 1 + dlls/d3d9/d3d9_main.c | 24 ++++++++ dlls/d3d9/d3d9_private.h | 6 ++ dlls/d3d9/d3d9on12.c | 125 +++++++++++++++++++++++++++++++++++++++ dlls/d3d9/device.c | 17 ++++++ 6 files changed, 174 insertions(+) create mode 100644 dlls/d3d9/d3d9on12.c
diff --git a/dlls/d3d9/Makefile.in b/dlls/d3d9/Makefile.in index 5a717b11863..84380258c32 100644 --- a/dlls/d3d9/Makefile.in +++ b/dlls/d3d9/Makefile.in @@ -5,6 +5,7 @@ IMPORTS = dxguid uuid wined3d SOURCES = \ buffer.c \ d3d9_main.c \ + d3d9on12.c \ device.c \ directx.c \ query.c \ diff --git a/dlls/d3d9/d3d9.spec b/dlls/d3d9/d3d9.spec index a33cba51e77..11ad26b64c6 100644 --- a/dlls/d3d9/d3d9.spec +++ b/dlls/d3d9/d3d9.spec @@ -12,3 +12,4 @@ @ stdcall DebugSetMute() @ stdcall Direct3DCreate9(long) @ stdcall Direct3DCreate9Ex(long ptr) +@ stdcall Direct3DCreate9On12(long ptr long) diff --git a/dlls/d3d9/d3d9_main.c b/dlls/d3d9/d3d9_main.c index 5bdf05409aa..48944ae75d4 100644 --- a/dlls/d3d9/d3d9_main.c +++ b/dlls/d3d9/d3d9_main.c @@ -75,6 +75,30 @@ HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9E return D3D_OK; }
+IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9On12(UINT sdk_version, D3D9ON12_ARGS *override_list, UINT override_entries) +{ + struct d3d9 *object; + + TRACE("sdk_version %#x, override_list %p, override_entries %#x.\n", sdk_version, override_list, override_entries); + + if (!(object = calloc(1, sizeof(*object)))) + return NULL; + + if (!d3d9_init(object, TRUE)) + { + WARN("Failed to initialize d3d9.\n"); + free(object); + return NULL; + } + d3d9on12_init(object, override_list, override_entries); + SetLastError(ERROR_SUCCESS); + + TRACE("Created d3d9 object %p.\n", object); + if (object->d3d9on12) TRACE("Created IDirect3DDevice9On12Vtbl %p.\n", object->IDirect3DDevice9On12_iface.lpVtbl); + + return (IDirect3D9 *)&object->IDirect3D9Ex_iface; +} + /* The callback is called on any error encountered during validation, including * improper IDirect3DShaderValidator9 method calls. * - "file" and "line" are passed through directly from Instruction(). "line" diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index a5f059c5aef..15d2925f29e 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -34,6 +34,7 @@ #include "wine/debug.h"
#include "d3d9.h" +#include "d3d9on12.h" #include "wine/wined3d.h"
#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 @@ -65,11 +66,16 @@ struct d3d9 struct wined3d_output **wined3d_outputs; unsigned int wined3d_output_count; BOOL extended; + BOOL d3d9on12; + IDirect3DDevice9On12 IDirect3DDevice9On12_iface; + struct D3D9ON12_ARGS *override_list; + UINT override_entries; };
void d3d9_caps_from_wined3dcaps(const struct d3d9 *d3d9, unsigned int adapter_ordinal, D3DCAPS9 *caps, const struct wined3d_caps *wined3d_caps); BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended); +void d3d9on12_init(struct d3d9 *d3d9, D3D9ON12_ARGS *override_list, UINT override_entries);
struct fvf_declaration { diff --git a/dlls/d3d9/d3d9on12.c b/dlls/d3d9/d3d9on12.c new file mode 100644 index 00000000000..fce7ad3f60c --- /dev/null +++ b/dlls/d3d9/d3d9on12.c @@ -0,0 +1,125 @@ +/* + * IDirect3DDevice9On12 implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "d3d9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d9); + +static inline struct d3d9 *impl_from_IDirect3DDevice9On12( IDirect3DDevice9On12 *iface ) +{ + return CONTAINING_RECORD( iface, struct d3d9, IDirect3DDevice9On12_iface ); +} + +static HRESULT WINAPI d3d9on12_QueryInterface( IDirect3DDevice9On12 *iface, REFIID iid, void **out ) +{ + struct d3d9 *d3d9 = impl_from_IDirect3DDevice9On12(iface); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IDirect3DDevice9On12 )) + { + IDirect3DDevice9On12_AddRef( &d3d9->IDirect3DDevice9On12_iface ); + *out = &d3d9->IDirect3DDevice9On12_iface; + return S_OK; + } + + WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid) ); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI d3d9on12_AddRef( IDirect3DDevice9On12 *iface ) +{ + struct d3d9 *d3d9 = impl_from_IDirect3DDevice9On12(iface); + ULONG refcount = InterlockedIncrement(&d3d9->refcount); + TRACE( "%p increasing refcount to %lu.\n", iface, refcount ); + return refcount; +} + +static ULONG WINAPI d3d9on12_Release( IDirect3DDevice9On12 *iface ) +{ + struct d3d9 *d3d9 = impl_from_IDirect3DDevice9On12(iface); + ULONG refcount = InterlockedDecrement(&d3d9->refcount); + + TRACE( "%p decreasing refcount to %lu.\n", iface, refcount ); + + if (!refcount) + { + ID3D12Device_Release( (ID3D12Device *)d3d9->override_list->pD3D12Device ); + for ( int i = 0; i < d3d9->override_list->NumQueues; i++ ) + IUnknown_Release( d3d9->override_list->ppD3D12Queues[i] ); + free( d3d9->override_list ); + } + + return refcount; +} + +static HRESULT WINAPI d3d9on12_GetD3D12Device( IDirect3DDevice9On12 *iface, REFIID iid, void **out ) +{ + FIXME( "iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out ); + + if (!out) return E_INVALIDARG; + + *out = NULL; + return E_NOINTERFACE; +} + +static HRESULT WINAPI d3d9on12_UnwrapUnderlyingResource( IDirect3DDevice9On12 *iface, IDirect3DResource9 *resource, ID3D12CommandQueue *queue, REFIID iid, void **out ) +{ + FIXME( "iface %p, resource %p, queue %p, iid %s, out %p stub!\n", iface, resource, queue, debugstr_guid(iid), out ); + return E_NOTIMPL; +} + +static HRESULT WINAPI d3d9on12_ReturnUnderlyingResource( IDirect3DDevice9On12 *iface, IDirect3DResource9 *resource, UINT num_sync, UINT64 *signal_values, ID3D12Fence **fences ) +{ + FIXME( "iface %p, resource %p, num_sync %#x, signal_values %p, fences %p stub!\n", iface, resource, num_sync, signal_values, fences ); + return E_NOTIMPL; +} + +static const struct IDirect3DDevice9On12Vtbl d3d9on12_vtbl = +{ + /* IUnknown */ + d3d9on12_QueryInterface, + d3d9on12_AddRef, + d3d9on12_Release, + /* IDirect3DDevice9On12 */ + d3d9on12_GetD3D12Device, + d3d9on12_UnwrapUnderlyingResource, + d3d9on12_ReturnUnderlyingResource, +}; + +void d3d9on12_init( struct d3d9 *d3d9, D3D9ON12_ARGS *override_list, UINT override_entries ) +{ + if (!override_entries || !override_list || !override_list->Enable9On12) + { + d3d9->d3d9on12 = FALSE; + return; + } + + FIXME( "ignoring override_list %p\n", override_list ); + + d3d9->d3d9on12 = TRUE; + d3d9->IDirect3DDevice9On12_iface.lpVtbl = &d3d9on12_vtbl; + d3d9->refcount += 1; + d3d9->override_list = NULL; + d3d9->override_entries = override_entries; +} diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 1267dc8fca1..0ddcffc6f22 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -623,6 +623,23 @@ static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFI return S_OK; }
+ if (IsEqualGUID(riid, &IID_IDirect3DDevice9On12)) + { + struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface); + + if (!device->d3d_parent->d3d9on12) + { + WARN("IDirect3D9 instance wasn't created with D3D9On12 enabled, returning E_NOINTERFACE.\n"); + *out = NULL; + return E_NOINTERFACE; + } + + FIXME("pD3D12Device value is not being checked if it matches the d3d9 device\n"); + + IDirect3DDevice9On12_QueryInterface(&device->d3d_parent->IDirect3DDevice9On12_iface, riid, out); + return S_OK; + } + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
*out = NULL;