From 1486182f98b7ceb264c72ab2d3111d730dc5d8cc Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 1 Mar 2019 12:50:42 -0500 Subject: [PATCH 1/5] dxgi,include: Add and implement IWineDXGISwapChainHelper --- dlls/dxgi/adapter.c | 239 ++++++++++++++++++++++++++++++++++++++ dlls/dxgi/dxgi_private.h | 1 + include/wine/winedxgi.idl | 52 +++++++++ 3 files changed, 292 insertions(+) diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index 31baae6f49ff..27062bf776c2 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -31,6 +31,8 @@ static inline struct dxgi_adapter *impl_from_IWineDXGIAdapter(IWineDXGIAdapter * static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryInterface(IWineDXGIAdapter *iface, REFIID iid, void **out) { + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); if (IsEqualGUID(iid, &IID_IWineDXGIAdapter) @@ -47,6 +49,13 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryInterface(IWineDXGIAdapter *i return S_OK; } + if (IsEqualGUID(iid, &IID_IWineDXGISwapChainHelper)) + { + IUnknown_AddRef(iface); + *out = &adapter->IWineDXGISwapChainHelper_iface; + return S_OK; + } + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); *out = NULL; @@ -392,6 +401,235 @@ static const struct IWineDXGIAdapterVtbl dxgi_adapter_vtbl = dxgi_adapter_GetDesc3, }; +static inline struct dxgi_adapter *impl_from_IWineDXGISwapChainHelper(IWineDXGISwapChainHelper *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_adapter, IWineDXGISwapChainHelper_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_QueryInterface(IWineDXGISwapChainHelper *iface, + REFIID iid, void **out) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGISwapChainHelper(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + return dxgi_adapter_QueryInterface(&adapter->IWineDXGIAdapter_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE dxgi_swapchain_helper_AddRef(IWineDXGISwapChainHelper *iface) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGISwapChainHelper(iface); + + TRACE("iface %p.\n", iface); + + return dxgi_adapter_AddRef(&adapter->IWineDXGIAdapter_iface); +} + +static ULONG STDMETHODCALLTYPE dxgi_swapchain_helper_Release(IWineDXGISwapChainHelper *iface) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGISwapChainHelper(iface); + + TRACE("iface %p.\n", iface); + + return dxgi_adapter_Release(&adapter->IWineDXGIAdapter_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_get_monitor(IWineDXGISwapChainHelper *iface, + HWND window, HMONITOR *monitor) +{ + RECT window_rect = {0, 0, 0, 0}; + POINT window_middle; + + TRACE("iface %p, window %p, monitor %p.\n", iface, window, monitor); + + if (!IsWindow(window) || !monitor) + return DXGI_ERROR_INVALID_CALL; + + GetWindowRect(window, &window_rect); + + window_middle.x = (window_rect.left + window_rect.right) / 2; + window_middle.y = (window_rect.top + window_rect.bottom) / 2; + + *monitor = MonitorFromPoint(window_middle, MONITOR_DEFAULTTOPRIMARY); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_get_window_info(IWineDXGISwapChainHelper *iface, + HWND window, RECT *rect, RECT *client_rect, LONG *style, LONG *exstyle) +{ + TRACE("iface %p, window %p, rect %p, style %p, exstyle %p.\n", iface, window, rect, style, exstyle); + + if (!IsWindow(window)) + return DXGI_ERROR_INVALID_CALL; + + if (rect) + GetWindowRect(window, rect); + + if (client_rect) + GetClientRect(window, client_rect); + + if (style) + *style = GetWindowLongW(window, GWL_STYLE); + + if (exstyle) + *exstyle = GetWindowLongW(window, GWL_EXSTYLE); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_set_window_pos(IWineDXGISwapChainHelper *iface, + HWND window, HWND hwnd_insert_after, RECT position, UINT flags) +{ + TRACE("iface %p, window %p, hwnd_insert_after %p, position (%d,%d)-(%d,%d), flags %08x.\n", + iface, window, hwnd_insert_after, position.left, position.top, position.right, position.bottom, flags); + + if (!IsWindow(window)) + return DXGI_ERROR_INVALID_CALL; + + SetWindowPos(window, hwnd_insert_after, position.left, position.top, position.right - position.left, + position.bottom - position.top, flags); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_resize_window(IWineDXGISwapChainHelper *iface, + HWND window, UINT width, UINT height) +{ + RECT old_rect = {0, 0, 0, 0}; + RECT new_rect = {0, 0, 0, 0}; + + TRACE("iface %p, window %p, width %u, height %u.\n", iface, window, width, height); + + if (!IsWindow(window)) + return DXGI_ERROR_INVALID_CALL; + + GetWindowRect(window, &old_rect); + SetRect(&new_rect, 0, 0, width, height); + AdjustWindowRectEx( &new_rect, GetWindowLongW(window, GWL_STYLE), FALSE, GetWindowLongW(window, GWL_EXSTYLE) ); + SetRect(&new_rect, 0, 0, new_rect.right - new_rect.left, new_rect.bottom - new_rect.top); + OffsetRect(&new_rect, old_rect.left, old_rect.top); + MoveWindow(window, new_rect.left, new_rect.top, new_rect.right - new_rect.left, new_rect.bottom - new_rect.top, TRUE); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_set_window_styles(IWineDXGISwapChainHelper *iface, + HWND window, const LONG *style, const LONG *exstyle) +{ + TRACE("iface %p, window %p, style %p, exstyle %p.\n", iface, window, style, exstyle); + + if (!IsWindow(window)) + return DXGI_ERROR_INVALID_CALL; + + if (style) + SetWindowLongW(window, GWL_STYLE, *style); + + if (exstyle) + SetWindowLongW(window, GWL_EXSTYLE, *exstyle); + + return S_OK; +} + +static unsigned int GetMonitorFormatBpp(DXGI_FORMAT format) +{ + switch (format) { + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_R10G10B10A2_UNORM: + return 32; + + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return 64; + + default: + WARN("Unknown format: %s\n", debug_dxgi_format(format)); + return 32; + } +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_get_display_mode(IWineDXGISwapChainHelper *iface, + HMONITOR monitor, DWORD mode_num, DXGI_MODE_DESC *mode) +{ + MONITORINFOEXW mon_info; + DEVMODEW dev_mode = {}; + DXGI_RATIONAL rate; + + TRACE("iface %p, monitor %p, mode_num %u, mode %p.\n", iface, monitor, mode_num, mode); + + mon_info.cbSize = sizeof(mon_info); + if (!GetMonitorInfoW(monitor, (MONITORINFO*)&mon_info)) + { + ERR("Failed to query monitor info\n"); + return E_FAIL; + } + + dev_mode.dmSize = sizeof(dev_mode); + if (!EnumDisplaySettingsW(mon_info.szDevice, mode_num, &dev_mode)) + return DXGI_ERROR_NOT_FOUND; + + mode->Width = dev_mode.dmPelsWidth; + mode->Height = dev_mode.dmPelsHeight; + rate.Numerator = dev_mode.dmDisplayFrequency; + rate.Denominator = 1; + mode->RefreshRate = rate; + mode->Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; /* FIXME */ + mode->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; + mode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_set_display_mode(IWineDXGISwapChainHelper *iface, + HMONITOR monitor, const DXGI_MODE_DESC *mode) +{ + MONITORINFOEXW mon_info; + DEVMODEW dev_mode = {}; + LONG status; + + TRACE("iface %p, monitor %p, mode %p.\n", iface, monitor, mode); + + mon_info.cbSize = sizeof(mon_info); + if (!GetMonitorInfoW(monitor, (MONITORINFO*)&mon_info)) + { + ERR("Failed to query monitor info\n"); + return E_FAIL; + } + + dev_mode.dmSize = sizeof(dev_mode); + dev_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + dev_mode.dmPelsWidth = mode->Width; + dev_mode.dmPelsHeight = mode->Height; + dev_mode.dmBitsPerPel = GetMonitorFormatBpp(mode->Format); + + if (mode->RefreshRate.Numerator) + { + dev_mode.dmFields |= DM_DISPLAYFREQUENCY; + dev_mode.dmDisplayFrequency = mode->RefreshRate.Numerator / mode->RefreshRate.Denominator; + } + + TRACE("Setting Display Mode: %u x %u @ %u\n", dev_mode.dmPelsWidth, dev_mode.dmPelsHeight, dev_mode.dmDisplayFrequency); + + status = ChangeDisplaySettingsExW(mon_info.szDevice, &dev_mode, NULL, CDS_FULLSCREEN, NULL); + + return status == DISP_CHANGE_SUCCESSFUL ? S_OK : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; +} + +static const struct IWineDXGISwapChainHelperVtbl dxgi_swapchain_helper_vtbl = +{ + dxgi_swapchain_helper_QueryInterface, + dxgi_swapchain_helper_AddRef, + dxgi_swapchain_helper_Release, + dxgi_swapchain_helper_get_monitor, + dxgi_swapchain_helper_get_window_info, + dxgi_swapchain_helper_set_window_pos, + dxgi_swapchain_helper_resize_window, + dxgi_swapchain_helper_set_window_styles, + dxgi_swapchain_helper_get_display_mode, + dxgi_swapchain_helper_set_display_mode +}; + struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) { IWineDXGIAdapter *wine_adapter; @@ -414,6 +652,7 @@ struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) static void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *factory, UINT ordinal) { adapter->IWineDXGIAdapter_iface.lpVtbl = &dxgi_adapter_vtbl; + adapter->IWineDXGISwapChainHelper_iface.lpVtbl = &dxgi_swapchain_helper_vtbl; adapter->refcount = 1; wined3d_private_store_init(&adapter->private_store); adapter->ordinal = ordinal; diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index 320a347dde5e..4137746ceb08 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -149,6 +149,7 @@ HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **ou struct dxgi_adapter { IWineDXGIAdapter IWineDXGIAdapter_iface; + IWineDXGISwapChainHelper IWineDXGISwapChainHelper_iface; LONG refcount; struct wined3d_private_store private_store; UINT ordinal; diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index f300eb928b62..5aa2353c5985 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -85,3 +85,55 @@ interface IWineDXGIAdapter : IDXGIAdapter4 interface IWineDXGIFactory : IDXGIFactory5 { } + +[ + object, + local, + uuid(d922ca90-6152-41f9-8b44-47adaac22b40) +] +interface IWineDXGISwapChainHelper : IUnknown +{ + HRESULT get_monitor( + [in] HWND window, + [out] HMONITOR *monitor + ); + + HRESULT get_window_info( + [in] HWND window, + [out] RECT *rect, + [out] RECT *client_rect, + [out] LONG *style, + [out] LONG *exstyle + ); + + /* Clone of SetWindowPos */ + HRESULT set_window_pos( + [in] HWND window, + [in] HWND hwnd_insert_after, + [in] RECT position, + [in] UINT flags + ); + + HRESULT resize_window( + [in] HWND window, + [in] UINT width, + [in] UINT height + ); + + HRESULT set_window_styles( + [in] HWND window, + [in] const LONG *style, + [in] const LONG *exstyle + ); + + HRESULT get_display_mode( + [in] HMONITOR monitor, + [in] DWORD mode_num, + [out] DXGI_MODE_DESC *mode + ); + + HRESULT set_display_mode( + [in] HMONITOR monitor, + [in] const DXGI_MODE_DESC *mode + ); +} \ No newline at end of file From eba58ed67fe9a1c36b06160a4ccc84f665c57419 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 1 Mar 2019 12:51:18 -0500 Subject: [PATCH 2/5] d3d11,include: Add mechanism for using a native library as a d3d11 implementation --- dlls/d3d11/Makefile.in | 4 +- dlls/d3d11/d3d11_main.c | 3 + dlls/d3d11/d3d11_private.h | 7 ++ dlls/d3d11/external.c | 127 ++++++++++++++++++++++++++++++++++++ include/wine/external_d3d.h | 58 ++++++++++++++++ 5 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 dlls/d3d11/external.c create mode 100644 include/wine/external_d3d.h diff --git a/dlls/d3d11/Makefile.in b/dlls/d3d11/Makefile.in index 5a56faec523e..514cd1c40d40 100644 --- a/dlls/d3d11/Makefile.in +++ b/dlls/d3d11/Makefile.in @@ -1,12 +1,14 @@ MODULE = d3d11.dll IMPORTLIB = d3d11 -IMPORTS = dxguid uuid dxgi wined3d +IMPORTS = advapi32 user32 gdi32 dxguid uuid dxgi wined3d +EXTRAINCL = $(DXVK_CFLAGS) C_SRCS = \ async.c \ buffer.c \ d3d11_main.c \ device.c \ + external.c \ inputlayout.c \ shader.c \ state.c \ diff --git a/dlls/d3d11/d3d11_main.c b/dlls/d3d11/d3d11_main.c index b0a32aceda78..4059167dcd90 100644 --- a/dlls/d3d11/d3d11_main.c +++ b/dlls/d3d11/d3d11_main.c @@ -114,6 +114,9 @@ HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte HMODULE d3d11; HRESULT hr; + if (is_external_d3d11_available()) + return create_external_d3d11_device(factory, adapter, flags, feature_levels, levels, device); + TRACE("factory %p, adapter %p, flags %#x, feature_levels %p, levels %u, device %p.\n", factory, adapter, flags, feature_levels, levels, device); diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 44e774b8b4df..64d0c8cb14cf 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -579,4 +579,11 @@ HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, I unsigned int flags, const D3D_FEATURE_LEVEL *feature_levels, unsigned int level_count, void **device); HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count); +/* external d3d library support */ + +int is_external_d3d11_available(void); + +HRESULT create_external_d3d11_device(IDXGIFactory* factory, IDXGIAdapter *adapter, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device_out); + #endif /* __WINE_D3D11_PRIVATE_H */ diff --git a/dlls/d3d11/external.c b/dlls/d3d11/external.c new file mode 100644 index 000000000000..43acecde2c6a --- /dev/null +++ b/dlls/d3d11/external.c @@ -0,0 +1,127 @@ +#include "config.h" +#include "wine/port.h" + +#include "d3d11_private.h" + +#define EXTERNAL_D3D_NO_WINDOWS_H +#define EXTERNAL_D3D_NO_VULKAN_H +#include "wine/library.h" +#include "wine/vulkan.h" +#include "wine/vulkan_driver.h" +#include "wine/external_d3d.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +static void* external_d3d_lib; +static const struct vulkan_funcs *vulkan_funcs; +static PFN_native_core_create_d3d11_device pfn_native_core_create_d3d11_device; + +static char* get_desired_d3d_library(void) +{ + HKEY defkey; + HKEY appkey; + DWORD type, size; + char buffer[MAX_PATH+10]; + DWORD len; + LSTATUS status; + + static char* external_d3d_lib_name = NULL; + + if (external_d3d_lib_name) + return external_d3d_lib_name; + + external_d3d_lib_name = HeapAlloc(GetProcessHeap(), 0, MAX_PATH); + + /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */ + if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &defkey ) ) defkey = 0; + + len = GetModuleFileNameA( 0, buffer, MAX_PATH ); + if (len && len < MAX_PATH) + { + HKEY tmpkey; + /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */ + if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey )) + { + char *p, *appname = buffer; + if ((p = strrchr( appname, '/' ))) appname = p + 1; + if ((p = strrchr( appname, '\\' ))) appname = p + 1; + strcat( appname, "\\Direct3D" ); + TRACE("appname = [%s]\n", appname); + if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0; + RegCloseKey( tmpkey ); + } + } + + size = MAX_PATH; + + if (defkey) status = RegQueryValueExA(defkey, "external_d3d", 0, &type, (BYTE *)external_d3d_lib_name, &size); + if (type != REG_SZ && appkey) + status = RegQueryValueExA(appkey, "external_d3d", 0, &type, (BYTE *)external_d3d_lib_name, &size); + if (type != REG_SZ) + { + HeapFree(GetProcessHeap(), 0, external_d3d_lib_name); + external_d3d_lib_name = NULL; + } + + RegCloseKey(appkey); + RegCloseKey(defkey); + + return external_d3d_lib_name; +} + +int is_external_d3d11_available(void) +{ + char* lib_name = get_desired_d3d_library(); + + if (!lib_name) + return 0; + + if ( !(external_d3d_lib = wine_dlopen(lib_name, RTLD_LAZY | RTLD_NOLOAD, NULL, 0)) ) + { + if ( !(external_d3d_lib = wine_dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL, NULL, 0)) ) + { + ERR("External D3D Library %s could not be found\n", lib_name); + return 0; + } else { + HDC hdc; + + pfn_native_core_create_d3d11_device = wine_dlsym(external_d3d_lib, "native_core_create_d3d11_device", NULL, 0); + + hdc = GetDC(0); + vulkan_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); + ReleaseDC(0, hdc); + } + } + + return 1; +} + +static VkResult create_vulkan_surface(VkInstance instance, void *window, VkSurfaceKHR *surface) +{ + HINSTANCE window_instance = (HINSTANCE) GetWindowLongPtrA(window, GWLP_HINSTANCE); + + VkWin32SurfaceCreateInfoKHR info; + info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + info.pNext = NULL; + info.flags = 0; + info.hinstance = window_instance; + info.hwnd = window; + + return vulkan_funcs->p_vkCreateWin32SurfaceKHR(instance, &info, NULL, surface); +} + +static native_info info = +{ + NULL, + create_vulkan_surface +}; + +HRESULT create_external_d3d11_device(IDXGIFactory *factory, IDXGIAdapter *adapter, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device_out) +{ + info.pfn_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) vulkan_funcs->p_vkGetInstanceProcAddr; + + TRACE("Calling external D3D11 library's entry-point\n"); + return pfn_native_core_create_d3d11_device(info, factory, adapter, flags, feature_levels, + levels, device_out); +} \ No newline at end of file diff --git a/include/wine/external_d3d.h b/include/wine/external_d3d.h new file mode 100644 index 000000000000..e463b78b09c9 --- /dev/null +++ b/include/wine/external_d3d.h @@ -0,0 +1,58 @@ +#ifndef EXTERNAL_D3D_H +#define EXTERNAL_D3D_H + +#ifndef EXTERNAL_D3D_NO_WINDOWS_H + #ifdef __GNUC__ + #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" + #endif + #include + #include + #include + #include +#endif + +#ifndef EXTERNAL_D3D_NO_VULKAN_H + #include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + typedef VkResult (*PFN_create_vulkan_surface)(VkInstance instance, void* window, VkSurfaceKHR *surface); + typedef struct tag_native_info + { + PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr; + PFN_create_vulkan_surface pfn_create_vulkan_surface; + } native_info; + + HRESULT native_core_create_d3d11_device( + native_info native_info, + IDXGIFactory* pFactory, + IDXGIAdapter* pAdapter, + UINT Flags, + const D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + ID3D11Device** ppDevice + ); + + typedef HRESULT (*PFN_native_core_create_d3d11_device)(native_info,IDXGIFactory*,IDXGIAdapter*,UINT,const D3D_FEATURE_LEVEL*,UINT,ID3D11Device**); + + HRESULT native_core_create_d3d10_device( + native_info native_info, + IDXGIFactory* pFactory, + IDXGIAdapter* pAdapter, + UINT Flags, + D3D_FEATURE_LEVEL FeatureLevel, + ID3D10Device** ppDevice + ); + + typedef HRESULT (*PFN_native_core_create_d3d10_device)(native_info,IDXGIFactory*,IDXGIAdapter*,UINT,D3D_FEATURE_LEVEL,ID3D10Device**); + + extern native_info g_native_info; + +#ifdef __cplusplus +} +#endif + +#endif From dfb3463539d2253e2bd9fe38010cf7048cb15950 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 1 Mar 2019 20:45:07 -0500 Subject: [PATCH 3/5] Remove vestige of dxvk.h --- include/wine/external_d3d.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/wine/external_d3d.h b/include/wine/external_d3d.h index e463b78b09c9..9aaabb446cf8 100644 --- a/include/wine/external_d3d.h +++ b/include/wine/external_d3d.h @@ -49,8 +49,6 @@ extern "C" { typedef HRESULT (*PFN_native_core_create_d3d10_device)(native_info,IDXGIFactory*,IDXGIAdapter*,UINT,D3D_FEATURE_LEVEL,ID3D10Device**); - extern native_info g_native_info; - #ifdef __cplusplus } #endif From e72f8bffc583bdb797ff0b3120ac743eb60f05b2 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 8 Mar 2019 15:07:44 -0500 Subject: [PATCH 4/5] Extend interface to allow external library to get vulkan functions --- dlls/dxgi/adapter.c | 47 ++++++++++++++++++++++++++++++++++++++- include/wine/winedxgi.idl | 20 +++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index 27062bf776c2..2e1ecc49fcc2 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -616,6 +616,49 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_set_display_mode(IWineDXG return status == DISP_CHANGE_SUCCESSFUL ? S_OK : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; } +static const struct vulkan_funcs *vk_funcs = NULL; + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_helper_get_vulkan_func_finder(IWineDXGISwapChainHelper *iface, + PFN_vkGetInstanceProcAddr *func_finder) +{ + if (!vk_funcs) + { + HDC hdc = GetDC(0); + vk_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); + ReleaseDC(0, hdc); + } + + if (vk_funcs) + *func_finder = (PFN_vkGetInstanceProcAddr) vk_funcs->p_vkGetInstanceProcAddr; + + return S_OK; +} + +static VkResult STDMETHODCALLTYPE dxgi_swapchain_helper_create_surface(IWineDXGISwapChainHelper *iface, + HWND window, VkInstance instance, VkSurfaceKHR *surface) +{ + HINSTANCE hinstance; + VkWin32SurfaceCreateInfoKHR info; + + if (!vk_funcs) + { + HDC hdc = GetDC(0); + vk_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); + ReleaseDC(0, hdc); + } + + hinstance = (HINSTANCE) GetWindowLongPtrW(window, GWLP_HINSTANCE); + + info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + info.pNext = NULL; + info.flags = 0; + info.hinstance = hinstance; + info.hwnd = window; + + return vk_funcs->p_vkCreateWin32SurfaceKHR(instance, &info, NULL, surface); +} + + static const struct IWineDXGISwapChainHelperVtbl dxgi_swapchain_helper_vtbl = { dxgi_swapchain_helper_QueryInterface, @@ -627,7 +670,9 @@ static const struct IWineDXGISwapChainHelperVtbl dxgi_swapchain_helper_vtbl = dxgi_swapchain_helper_resize_window, dxgi_swapchain_helper_set_window_styles, dxgi_swapchain_helper_get_display_mode, - dxgi_swapchain_helper_set_display_mode + dxgi_swapchain_helper_set_display_mode, + dxgi_swapchain_helper_get_vulkan_func_finder, + dxgi_swapchain_helper_create_surface }; struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index 5aa2353c5985..6b5671f44a3c 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -20,6 +20,9 @@ import "dxgi1_6.idl"; +cpp_quote("#include \"wine/vulkan.h\"") +cpp_quote("#include \"wine/vulkan_driver.h\"") + [ object, local, @@ -86,6 +89,13 @@ interface IWineDXGIFactory : IDXGIFactory5 { } +cpp_quote("#if 0") +typedef LONGLONG VkSurfaceKHR; +typedef LONGLONG VkInstance; +typedef void* PFN_vkGetInstanceProcAddr; +typedef int VkResult; +cpp_quote("#endif") + [ object, local, @@ -136,4 +146,14 @@ interface IWineDXGISwapChainHelper : IUnknown [in] HMONITOR monitor, [in] const DXGI_MODE_DESC *mode ); + + HRESULT get_vulkan_func_finder( + [out] PFN_vkGetInstanceProcAddr *func_finder + ); + + VkResult create_surface( + [in] HWND window, + [in] VkInstance instance, + [out] VkSurfaceKHR *surface + ); } \ No newline at end of file From 5bc56c5a4f99cb45ea472544dcbbb51a1ab1df5a Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 8 Mar 2019 20:33:25 -0500 Subject: [PATCH 5/5] Remove Old Code --- dlls/d3d11/external.c | 47 ++++++------------------------- include/wine/external_d3d.h | 56 ------------------------------------- 2 files changed, 8 insertions(+), 95 deletions(-) delete mode 100644 include/wine/external_d3d.h diff --git a/dlls/d3d11/external.c b/dlls/d3d11/external.c index 43acecde2c6a..27b72c3d3cf9 100644 --- a/dlls/d3d11/external.c +++ b/dlls/d3d11/external.c @@ -3,18 +3,15 @@ #include "d3d11_private.h" -#define EXTERNAL_D3D_NO_WINDOWS_H -#define EXTERNAL_D3D_NO_VULKAN_H #include "wine/library.h" -#include "wine/vulkan.h" -#include "wine/vulkan_driver.h" -#include "wine/external_d3d.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d11); +typedef HRESULT (WINAPI* PFN_D3D11_CORE_CREATE_DEVICE)(IDXGIFactory*,IDXGIAdapter*,UINT,const D3D_FEATURE_LEVEL*, + UINT,ID3D11Device**); + static void* external_d3d_lib; -static const struct vulkan_funcs *vulkan_funcs; -static PFN_native_core_create_d3d11_device pfn_native_core_create_d3d11_device; +static PFN_D3D11_CORE_CREATE_DEVICE pfn_native_core_create_d3d11_device; static char* get_desired_d3d_library(void) { @@ -23,7 +20,6 @@ static char* get_desired_d3d_library(void) DWORD type, size; char buffer[MAX_PATH+10]; DWORD len; - LSTATUS status; static char* external_d3d_lib_name = NULL; @@ -54,9 +50,9 @@ static char* get_desired_d3d_library(void) size = MAX_PATH; - if (defkey) status = RegQueryValueExA(defkey, "external_d3d", 0, &type, (BYTE *)external_d3d_lib_name, &size); + if (defkey) RegQueryValueExA(defkey, "external_d3d", 0, &type, (BYTE *)external_d3d_lib_name, &size); if (type != REG_SZ && appkey) - status = RegQueryValueExA(appkey, "external_d3d", 0, &type, (BYTE *)external_d3d_lib_name, &size); + RegQueryValueExA(appkey, "external_d3d", 0, &type, (BYTE *)external_d3d_lib_name, &size); if (type != REG_SZ) { HeapFree(GetProcessHeap(), 0, external_d3d_lib_name); @@ -83,45 +79,18 @@ int is_external_d3d11_available(void) ERR("External D3D Library %s could not be found\n", lib_name); return 0; } else { - HDC hdc; - - pfn_native_core_create_d3d11_device = wine_dlsym(external_d3d_lib, "native_core_create_d3d11_device", NULL, 0); - - hdc = GetDC(0); - vulkan_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); - ReleaseDC(0, hdc); + pfn_native_core_create_d3d11_device = wine_dlsym(external_d3d_lib, "D3D11CoreCreateDevice", NULL, 0); } } return 1; } -static VkResult create_vulkan_surface(VkInstance instance, void *window, VkSurfaceKHR *surface) -{ - HINSTANCE window_instance = (HINSTANCE) GetWindowLongPtrA(window, GWLP_HINSTANCE); - - VkWin32SurfaceCreateInfoKHR info; - info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - info.pNext = NULL; - info.flags = 0; - info.hinstance = window_instance; - info.hwnd = window; - - return vulkan_funcs->p_vkCreateWin32SurfaceKHR(instance, &info, NULL, surface); -} - -static native_info info = -{ - NULL, - create_vulkan_surface -}; - HRESULT create_external_d3d11_device(IDXGIFactory *factory, IDXGIAdapter *adapter, UINT flags, const D3D_FEATURE_LEVEL *feature_levels, UINT levels, ID3D11Device **device_out) { - info.pfn_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) vulkan_funcs->p_vkGetInstanceProcAddr; TRACE("Calling external D3D11 library's entry-point\n"); - return pfn_native_core_create_d3d11_device(info, factory, adapter, flags, feature_levels, + return pfn_native_core_create_d3d11_device(factory, adapter, flags, feature_levels, levels, device_out); } \ No newline at end of file diff --git a/include/wine/external_d3d.h b/include/wine/external_d3d.h deleted file mode 100644 index 9aaabb446cf8..000000000000 --- a/include/wine/external_d3d.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef EXTERNAL_D3D_H -#define EXTERNAL_D3D_H - -#ifndef EXTERNAL_D3D_NO_WINDOWS_H - #ifdef __GNUC__ - #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - #endif - #include - #include - #include - #include -#endif - -#ifndef EXTERNAL_D3D_NO_VULKAN_H - #include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - typedef VkResult (*PFN_create_vulkan_surface)(VkInstance instance, void* window, VkSurfaceKHR *surface); - typedef struct tag_native_info - { - PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr; - PFN_create_vulkan_surface pfn_create_vulkan_surface; - } native_info; - - HRESULT native_core_create_d3d11_device( - native_info native_info, - IDXGIFactory* pFactory, - IDXGIAdapter* pAdapter, - UINT Flags, - const D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - ID3D11Device** ppDevice - ); - - typedef HRESULT (*PFN_native_core_create_d3d11_device)(native_info,IDXGIFactory*,IDXGIAdapter*,UINT,const D3D_FEATURE_LEVEL*,UINT,ID3D11Device**); - - HRESULT native_core_create_d3d10_device( - native_info native_info, - IDXGIFactory* pFactory, - IDXGIAdapter* pAdapter, - UINT Flags, - D3D_FEATURE_LEVEL FeatureLevel, - ID3D10Device** ppDevice - ); - - typedef HRESULT (*PFN_native_core_create_d3d10_device)(native_info,IDXGIFactory*,IDXGIAdapter*,UINT,D3D_FEATURE_LEVEL,ID3D10Device**); - -#ifdef __cplusplus -} -#endif - -#endif