From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Orbiter Space Flight Simulator and Train Simulator Classic. --- dlls/d3d9/d3d9.spec | 1 + dlls/d3d9/d3d9_main.c | 28 +++++++++++++++-- dlls/d3d9/d3d9_private.h | 5 ++- dlls/d3d9/device.c | 67 ++++++++++++++++++++++++++++++++++++++++ dlls/d3d9/directx.c | 3 +- 5 files changed, 100 insertions(+), 4 deletions(-)
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..b3fcfc272e4 100644 --- a/dlls/d3d9/d3d9_main.c +++ b/dlls/d3d9/d3d9_main.c @@ -41,7 +41,7 @@ IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT sdk_version) if (!(object = calloc(1, sizeof(*object)))) return NULL;
- if (!d3d9_init(object, FALSE)) + if (!d3d9_init(object, FALSE, FALSE)) { WARN("Failed to initialize d3d9.\n"); free(object); @@ -62,7 +62,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9E if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (!d3d9_init(object, TRUE)) + if (!d3d9_init(object, TRUE, FALSE)) { WARN("Failed to initialize d3d9.\n"); free(object); @@ -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 *d3d9on12_args, UINT d3d9on12_args_count) +{ + struct d3d9 *object; + BOOL d3d9on12 = TRUE; + + TRACE("sdk_version %#x, d3d9on12_args %p, d3d9on12_args_count %#x.\n", sdk_version, d3d9on12_args, d3d9on12_args_count); + + if (!(object = calloc(1, sizeof(*object)))) + return NULL; + + if (!d3d9on12_args || !d3d9on12_args->Enable9On12 || !d3d9on12_args_count) + d3d9on12 = FALSE; + + if (!d3d9_init(object, TRUE, d3d9on12)) + { + WARN("Failed to initialize d3d9.\n"); + free(object); + return NULL; + } + + TRACE("Created d3d9 object %p.\n", object); + 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..b1e7690cb93 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,12 @@ struct d3d9 struct wined3d_output **wined3d_outputs; unsigned int wined3d_output_count; BOOL extended; + BOOL d3d9on12; };
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); +BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended, BOOL d3d9on12);
struct fvf_declaration { @@ -87,6 +89,7 @@ enum d3d9_device_state struct d3d9_device { IDirect3DDevice9Ex IDirect3DDevice9Ex_iface; + IDirect3DDevice9On12 IDirect3DDevice9On12_iface; struct wined3d_device_parent device_parent; LONG refcount; struct wined3d_device *wined3d_device; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index e9499a3be9b..9d4d0eb6f99 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -593,6 +593,56 @@ static void device_reset_viewport_state(struct d3d9_device *device) wined3d_stateblock_set_scissor_rect(device->state, &rect); }
+static HRESULT WINAPI d3d9on12_QueryInterface(IDirect3DDevice9On12 *iface, REFIID iid, void **out) +{ + return IDirect3DDevice9Ex_QueryInterface(iface, iid, out); +} + +static ULONG WINAPI d3d9on12_AddRef(IDirect3DDevice9On12 *iface) +{ + return IDirect3DDevice9Ex_AddRef(iface); +} + +static ULONG WINAPI d3d9on12_Release(IDirect3DDevice9On12 *iface) +{ + return IDirect3DDevice9Ex_Release(iface); +} + +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 fence_count, UINT64 *signal_values, ID3D12Fence **fences) +{ + FIXME("iface %p, resource %p, fence_count %#x, signal_values %p, fences %p stub!\n", iface, resource, fence_count, 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 +}; + static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -623,6 +673,22 @@ 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; + } + + IDirect3DDevice9Ex_AddRef(iface); + *out = &device->IDirect3DDevice9On12_iface; + return S_OK; + } + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
*out = NULL; @@ -4668,6 +4734,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine FIXME("Ignoring display mode.\n");
device->IDirect3DDevice9Ex_iface.lpVtbl = &d3d9_device_vtbl; + device->IDirect3DDevice9On12_iface.lpVtbl = &d3d9on12_vtbl; device->device_parent.ops = &d3d9_wined3d_device_parent_ops; device->adapter_ordinal = adapter; device->refcount = 1; diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 13d32b00680..e20fc981d8a 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -683,7 +683,7 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl = d3d9_GetAdapterLUID, };
-BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) +BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended, BOOL d3d9on12) { DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR @@ -736,6 +736,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
wined3d_mutex_unlock(); d3d9->extended = extended; + d3d9->d3d9on12 = d3d9on12;
return TRUE; }