forked from Mirrors/wine-wine
d3d12: Use VkPhysicalDevice corresponding to IDXGIAdapter.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>stable
parent
642ef33df0
commit
f42b983356
|
@ -1,6 +1,6 @@
|
|||
MODULE = d3d12.dll
|
||||
IMPORTLIB = d3d12
|
||||
IMPORTS = dxgi dxguid gdi32 user32
|
||||
IMPORTS = dxgi dxguid gdi32 user32 uuid
|
||||
EXTRALIBS = $(VKD3D_LIBS)
|
||||
EXTRAINCL = $(VKD3D_CFLAGS)
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
|
||||
#include <vkd3d.h>
|
||||
|
||||
#include "initguid.h"
|
||||
#include "wine/wined3d.h"
|
||||
#include "wine/winedxgi.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d12);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(winediag);
|
||||
|
||||
|
@ -118,14 +122,13 @@ static const struct vulkan_funcs *get_vk_funcs(void)
|
|||
return vk_funcs;
|
||||
}
|
||||
|
||||
static HRESULT d3d12_get_adapter(IUnknown **adapter, LUID *luid)
|
||||
static HRESULT d3d12_get_adapter(IWineDXGIAdapter **wine_adapter, IUnknown *adapter)
|
||||
{
|
||||
DXGI_ADAPTER_DESC adapter_desc;
|
||||
IDXGIAdapter *dxgi_adapter = NULL;
|
||||
IDXGIFactory4 *factory = NULL;
|
||||
IDXGIAdapter *dxgi_adapter;
|
||||
HRESULT hr;
|
||||
|
||||
if (!*adapter)
|
||||
if (!adapter)
|
||||
{
|
||||
if (FAILED(hr = CreateDXGIFactory2(0, &IID_IDXGIFactory4, (void **)&factory)))
|
||||
{
|
||||
|
@ -138,37 +141,153 @@ static HRESULT d3d12_get_adapter(IUnknown **adapter, LUID *luid)
|
|||
WARN("Failed to enumerate primary adapter, hr %#x.\n", hr);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (FAILED(hr = IUnknown_QueryInterface(*adapter, &IID_IDXGIAdapter, (void **)&dxgi_adapter)))
|
||||
{
|
||||
WARN("Invalid adapter %p, hr %#x.\n", adapter, hr);
|
||||
goto done;
|
||||
|
||||
adapter = (IUnknown *)dxgi_adapter;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr = IDXGIAdapter_GetDesc(dxgi_adapter, &adapter_desc)))
|
||||
{
|
||||
*adapter = (IUnknown *)dxgi_adapter;
|
||||
*luid = adapter_desc.AdapterLuid;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDXGIAdapter_Release(dxgi_adapter);
|
||||
}
|
||||
if (FAILED(hr = IUnknown_QueryInterface(adapter, &IID_IWineDXGIAdapter, (void **)wine_adapter)))
|
||||
WARN("Invalid adapter %p, hr %#x.\n", adapter, hr);
|
||||
|
||||
done:
|
||||
if (dxgi_adapter)
|
||||
IDXGIAdapter_Release(dxgi_adapter);
|
||||
if (factory)
|
||||
IDXGIFactory4_Release(factory);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static BOOL check_vk_instance_extension(const struct vulkan_funcs *vk_funcs, const char *name)
|
||||
{
|
||||
VkExtensionProperties *properties;
|
||||
BOOL ret = FALSE;
|
||||
unsigned int i;
|
||||
uint32_t count;
|
||||
|
||||
if (vk_funcs->p_vkEnumerateInstanceExtensionProperties(NULL, &count, NULL) < 0)
|
||||
return FALSE;
|
||||
|
||||
if (!(properties = heap_calloc(count, sizeof(*properties))))
|
||||
return FALSE;
|
||||
|
||||
if (vk_funcs->p_vkEnumerateInstanceExtensionProperties(NULL, &count, properties) >= 0)
|
||||
{
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
if (!strcmp(properties[i].extensionName, name))
|
||||
{
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
heap_free(properties);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static VkPhysicalDevice d3d12_get_vk_physical_device(struct vkd3d_instance *instance,
|
||||
const struct vulkan_funcs *vk_funcs, const struct wine_dxgi_adapter_info *adapter_info)
|
||||
{
|
||||
PFN_vkGetPhysicalDeviceProperties2 pfn_vkGetPhysicalDeviceProperties2 = NULL;
|
||||
PFN_vkGetPhysicalDeviceProperties pfn_vkGetPhysicalDeviceProperties;
|
||||
PFN_vkEnumeratePhysicalDevices pfn_vkEnumeratePhysicalDevices;
|
||||
VkPhysicalDevice vk_physical_device = VK_NULL_HANDLE;
|
||||
VkPhysicalDeviceIDProperties id_properties;
|
||||
VkPhysicalDeviceProperties2 properties2;
|
||||
VkPhysicalDeviceProperties properties;
|
||||
VkPhysicalDevice *vk_physical_devices;
|
||||
VkInstance vk_instance;
|
||||
unsigned int i;
|
||||
uint32_t count;
|
||||
VkResult vr;
|
||||
|
||||
vk_instance = vkd3d_instance_get_vk_instance(instance);
|
||||
|
||||
pfn_vkEnumeratePhysicalDevices = vk_funcs->p_vkGetInstanceProcAddr(vk_instance, "vkEnumeratePhysicalDevices");
|
||||
|
||||
pfn_vkGetPhysicalDeviceProperties = vk_funcs->p_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties");
|
||||
if (check_vk_instance_extension(vk_funcs, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
|
||||
pfn_vkGetPhysicalDeviceProperties2 = vk_funcs->p_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
|
||||
|
||||
if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, NULL)) < 0)
|
||||
{
|
||||
WARN("Failed to get device count, vr %d.\n", vr);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
if (!count)
|
||||
{
|
||||
WARN("No physical device available.\n");
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (!(vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices))))
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices)) < 0)
|
||||
goto done;
|
||||
|
||||
if (!IsEqualGUID(&adapter_info->driver_uuid, &GUID_NULL) && pfn_vkGetPhysicalDeviceProperties2)
|
||||
{
|
||||
TRACE("Matching adapters by UUIDs.\n");
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
memset(&id_properties, 0, sizeof(id_properties));
|
||||
id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
|
||||
|
||||
properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||
properties2.pNext = &id_properties;
|
||||
|
||||
pfn_vkGetPhysicalDeviceProperties2(vk_physical_devices[i], &properties2);
|
||||
|
||||
if (!memcmp(id_properties.driverUUID, &adapter_info->driver_uuid, VK_UUID_SIZE)
|
||||
&& !memcmp(id_properties.deviceUUID, &adapter_info->device_uuid, VK_UUID_SIZE))
|
||||
{
|
||||
vk_physical_device = vk_physical_devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vk_physical_device)
|
||||
{
|
||||
WARN("Matching adapters by PCI IDs.\n");
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
pfn_vkGetPhysicalDeviceProperties(vk_physical_devices[i], &properties);
|
||||
|
||||
if (properties.vendorID == adapter_info->vendor_id && properties.deviceID == adapter_info->device_id)
|
||||
{
|
||||
vk_physical_device = vk_physical_devices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vk_physical_device)
|
||||
{
|
||||
FIXME("Could not find Vulkan physical device for DXGI adapter.\n");
|
||||
vk_physical_device = vk_physical_devices[0];
|
||||
}
|
||||
|
||||
done:
|
||||
heap_free(vk_physical_devices);
|
||||
return vk_physical_device;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
|
||||
REFIID iid, void **device)
|
||||
{
|
||||
struct vkd3d_optional_instance_extensions_info optional_extensions_info;
|
||||
struct vkd3d_instance_create_info instance_create_info;
|
||||
struct vkd3d_device_create_info device_create_info;
|
||||
struct wine_dxgi_adapter_info adapter_info;
|
||||
VkPhysicalDevice vk_physical_device;
|
||||
const struct vulkan_funcs *vk_funcs;
|
||||
LUID adapter_luid;
|
||||
struct vkd3d_instance *instance;
|
||||
IWineDXGIAdapter *wine_adapter;
|
||||
HRESULT hr;
|
||||
|
||||
static const char * const instance_extensions[] =
|
||||
|
@ -176,6 +295,10 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe
|
|||
VK_KHR_SURFACE_EXTENSION_NAME,
|
||||
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
|
||||
};
|
||||
static const char * const optional_instance_extensions[] =
|
||||
{
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||
};
|
||||
static const char * const device_extensions[] =
|
||||
{
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
|
@ -190,12 +313,22 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* FIXME: Get VkPhysicalDevice for IDXGIAdapter. */
|
||||
if (FAILED(hr = d3d12_get_adapter(&adapter, &adapter_luid)))
|
||||
if (FAILED(hr = d3d12_get_adapter(&wine_adapter, adapter)))
|
||||
return hr;
|
||||
|
||||
memset(&instance_create_info, 0, sizeof(instance_create_info));
|
||||
if (FAILED(hr = IWineDXGIAdapter_get_adapter_info(wine_adapter, &adapter_info)))
|
||||
{
|
||||
WARN("Failed to get adapter info, hr %#x.\n", hr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
optional_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO;
|
||||
optional_extensions_info.next = NULL;
|
||||
optional_extensions_info.extensions = optional_instance_extensions;
|
||||
optional_extensions_info.extension_count = ARRAY_SIZE(optional_instance_extensions);
|
||||
|
||||
instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
instance_create_info.next = &optional_extensions_info;
|
||||
instance_create_info.pfn_signal_event = d3d12_signal_event;
|
||||
instance_create_info.pfn_create_thread = d3d12_create_thread;
|
||||
instance_create_info.pfn_join_thread = d3d12_join_thread;
|
||||
|
@ -205,17 +338,33 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe
|
|||
instance_create_info.instance_extensions = instance_extensions;
|
||||
instance_create_info.instance_extension_count = ARRAY_SIZE(instance_extensions);
|
||||
|
||||
memset(&device_create_info, 0, sizeof(device_create_info));
|
||||
if (FAILED(hr = vkd3d_create_instance(&instance_create_info, &instance)))
|
||||
{
|
||||
WARN("Failed to create vkd3d instance, hr %#x.\n", hr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(vk_physical_device = d3d12_get_vk_physical_device(instance, vk_funcs, &adapter_info)))
|
||||
goto done_instance;
|
||||
|
||||
device_create_info.type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
device_create_info.next = NULL;
|
||||
device_create_info.minimum_feature_level = minimum_feature_level;
|
||||
device_create_info.instance_create_info = &instance_create_info;
|
||||
device_create_info.instance = instance;
|
||||
device_create_info.instance_create_info = NULL;
|
||||
device_create_info.vk_physical_device = vk_physical_device;
|
||||
device_create_info.device_extensions = device_extensions;
|
||||
device_create_info.device_extension_count = ARRAY_SIZE(device_extensions);
|
||||
device_create_info.parent = adapter;
|
||||
device_create_info.adapter_luid = adapter_luid;
|
||||
device_create_info.parent = (IUnknown *)wine_adapter;
|
||||
device_create_info.adapter_luid = adapter_info.luid;
|
||||
|
||||
hr = vkd3d_create_device(&device_create_info, iid, device);
|
||||
IUnknown_Release(adapter);
|
||||
|
||||
done_instance:
|
||||
vkd3d_instance_decref(instance);
|
||||
|
||||
done:
|
||||
IWineDXGIAdapter_Release(wine_adapter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue