This commit is contained in:
Joshua Ashton 2021-03-16 16:30:46 +00:00
parent 0336929c60
commit cd92558295
No known key found for this signature in database
GPG Key ID: C85A08669126BE8D
7 changed files with 162 additions and 72 deletions

View File

@ -10,6 +10,7 @@ vkd3d_idl = [
'vkd3d_dxgiformat.idl',
'vkd3d_dxgitype.idl',
'vkd3d_swapchain_factory.idl',
'vkd3d_dxvk_interop.idl',
]
vkd3d_header_files = idl_generator.process(vkd3d_idl)

View File

@ -94,6 +94,9 @@ struct vkd3d_instance_create_info
const char * const *instance_extensions;
uint32_t instance_extension_count;
/* If set to NULL, libvkd3d will create an instance */
VkInstance vk_instance;
};
/* Extends vkd3d_instance_create_info. Available since 1.1. */

View File

@ -0,0 +1,44 @@
/*
* Copyright 2020 Joshua Ashton for Valve Software
*
* 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
*/
import "vkd3d_windows.h";
#include "vkd3d_unknown.idl"
cpp_quote("#ifndef VKD3D_NO_VULKAN_H")
cpp_quote("# ifdef _WIN32")
cpp_quote("# define VK_USE_PLATFORM_WIN32_KHR")
cpp_quote("# endif")
cpp_quote("# include <vulkan/vulkan.h>")
cpp_quote("#endif /* VKD3D_NO_VULKAN_H */")
/* For IDL only. */
cpp_quote("#if 0")
typedef struct VkInstance_T* VkInstance;
typedef struct VkPhysicalDevice_T* VkPhysicalDevice;
cpp_quote("#endif")
[
local,
object,
uuid(3a6d8f2c-b0e8-4ab4-b4dc-4fd24891bfa5),
pointer_default(unique)
]
interface IDXGIVkInteropAdapter : IUnknown
{
void GetVulkanHandles(VkInstance *instance, VkPhysicalDevice *physical_device);
}

View File

@ -59,6 +59,7 @@
#include <vkd3d_swapchain_factory.h>
#include <vkd3d_d3d12.h>
#include <vkd3d_d3d12sdklayers.h>
#include <vkd3d_dxvk_interop.h>
/* End of MinGW hack. All Windows headers have been included */
#ifdef __MINGW32__

View File

@ -253,8 +253,11 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
struct vkd3d_device_create_info device_create_info;
struct DXGI_ADAPTER_DESC adapter_desc;
VkPhysicalDevice vk_physical_device = VK_NULL_HANDLE;
IDXGIVkInteropAdapter *dxvk_adapter;
struct vkd3d_instance *instance;
IDXGIAdapter *dxgi_adapter;
VkInstance vk_instance = VK_NULL_HANDLE;
HRESULT hr;
static const char * const instance_extensions[] =
@ -285,6 +288,13 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
goto done;
}
if (SUCCEEDED(hr = IDXGIAdapter_QueryInterface(dxgi_adapter, &IID_IDXGIVkInteropAdapter, (void**)&dxvk_adapter)))
{
/* Get the instance and physical device from from the DXVK adapter */
IDXGIVkInteropAdapter_GetVulkanHandles(dxvk_adapter, &vk_instance, &vk_physical_device);
IDXGIVkInteropAdapter_Release(dxvk_adapter);
}
instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instance_create_info.next = NULL;
instance_create_info.pfn_signal_event = d3d12_signal_event;
@ -293,6 +303,7 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
instance_create_info.pfn_vkGetInstanceProcAddr = pfn_vkGetInstanceProcAddr;
instance_create_info.instance_extensions = instance_extensions;
instance_create_info.instance_extension_count = ARRAYSIZE(instance_extensions);
instance_create_info.vk_instance = vk_instance;
if (FAILED(hr = vkd3d_create_instance(&instance_create_info, &instance)))
{
@ -300,12 +311,15 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
goto done;
}
if (!vk_physical_device)
vk_physical_device = d3d12_find_physical_device(instance, pfn_vkGetInstanceProcAddr, &adapter_desc);
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 = instance;
device_create_info.instance_create_info = NULL;
device_create_info.vk_physical_device = d3d12_find_physical_device(instance, pfn_vkGetInstanceProcAddr, &adapter_desc);
device_create_info.vk_physical_device = vk_physical_device;
device_create_info.device_extensions = device_extensions;
device_create_info.device_extension_count = ARRAYSIZE(device_extensions);
device_create_info.parent = (IUnknown *)dxgi_adapter;

View File

@ -577,85 +577,115 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
if (loader_version > VKD3D_MAX_API_VERSION)
loader_version = VKD3D_MAX_API_VERSION;
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
application_info.pNext = NULL;
application_info.pApplicationName = NULL;
application_info.applicationVersion = 0;
application_info.pEngineName = "vkd3d";
application_info.engineVersion = vkd3d_get_vk_version();
application_info.apiVersion = loader_version;
instance->external_vk_instance = create_info->vk_instance != VK_NULL_HANDLE;
INFO("vkd3d-proton - build: %"PRIx64".\n", vkd3d_build);
if (vkd3d_get_program_name(application_name))
application_info.pApplicationName = application_name;
TRACE("Application: %s.\n", debugstr_a(application_info.pApplicationName));
if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions))))
if (instance->external_vk_instance)
{
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);
vkd3d_free(user_extension_supported);
return E_OUTOFMEMORY;
}
vk_instance = create_info->vk_instance;
optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_INSTANCE_EXTENSIONS_INFO);
INFO("Using Vulkan Instance from DXVK Adapter.\n");
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instance_info.pNext = NULL;
instance_info.flags = 0;
instance_info.pApplicationInfo = &application_info;
instance_info.enabledLayerCount = 0;
instance_info.ppEnabledLayerNames = NULL;
instance_info.enabledExtensionCount = vkd3d_enable_extensions(extensions, NULL, 0,
optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions),
create_info->instance_extensions, create_info->instance_extension_count,
optional_extensions ? optional_extensions->extensions : NULL,
optional_extensions ? optional_extensions->extension_count : 0,
user_extension_supported, &instance->vk_info);
instance_info.ppEnabledExtensionNames = extensions;
vkd3d_free(user_extension_supported);
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_VULKAN_DEBUG)
{
layers = NULL;
if (vk_global_procs->vkEnumerateInstanceLayerProperties(&layer_count, NULL) == VK_SUCCESS &&
layer_count &&
(layers = vkd3d_malloc(layer_count * sizeof(*layers))) &&
vk_global_procs->vkEnumerateInstanceLayerProperties(&layer_count, layers) == VK_SUCCESS)
if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions))))
{
for (i = 0; i < layer_count; i++)
{
if (strcmp(layers[i].layerName, debug_layer_name) == 0)
{
instance_info.enabledLayerCount = 1;
instance_info.ppEnabledLayerNames = &debug_layer_name;
break;
}
}
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);
vkd3d_free(user_extension_supported);
return E_OUTOFMEMORY;
}
if (instance_info.enabledLayerCount == 0)
ERR("Failed to enumerate instance layers, will not use VK_LAYER_KHRONOS_validation!\n");
vkd3d_free(layers);
vkd3d_enable_extensions(extensions, NULL, 0,
optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions),
create_info->instance_extensions, create_info->instance_extension_count,
NULL, 0,
user_extension_supported, &instance->vk_info);
vkd3d_free(user_extension_supported);
}
vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance);
vkd3d_free((void *)extensions);
if (vr < 0)
else
{
ERR("Failed to create Vulkan instance, vr %d.\n", vr);
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);
return hresult_from_vk_result(vr);
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
application_info.pNext = NULL;
application_info.pApplicationName = NULL;
application_info.applicationVersion = 0;
application_info.pEngineName = "vkd3d";
application_info.engineVersion = vkd3d_get_vk_version();
application_info.apiVersion = loader_version;
INFO("vkd3d-proton - build: %"PRIx64".\n", vkd3d_build);
if (vkd3d_get_program_name(application_name))
application_info.pApplicationName = application_name;
TRACE("Application: %s.\n", debugstr_a(application_info.pApplicationName));
if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions))))
{
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);
vkd3d_free(user_extension_supported);
return E_OUTOFMEMORY;
}
optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_INSTANCE_EXTENSIONS_INFO);
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instance_info.pNext = NULL;
instance_info.flags = 0;
instance_info.pApplicationInfo = &application_info;
instance_info.enabledLayerCount = 0;
instance_info.ppEnabledLayerNames = NULL;
instance_info.enabledExtensionCount = vkd3d_enable_extensions(extensions, NULL, 0,
optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions),
create_info->instance_extensions, create_info->instance_extension_count,
optional_extensions ? optional_extensions->extensions : NULL,
optional_extensions ? optional_extensions->extension_count : 0,
user_extension_supported, &instance->vk_info);
instance_info.ppEnabledExtensionNames = extensions;
vkd3d_free(user_extension_supported);
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_VULKAN_DEBUG)
{
layers = NULL;
if (vk_global_procs->vkEnumerateInstanceLayerProperties(&layer_count, NULL) == VK_SUCCESS &&
layer_count &&
(layers = vkd3d_malloc(layer_count * sizeof(*layers))) &&
vk_global_procs->vkEnumerateInstanceLayerProperties(&layer_count, layers) == VK_SUCCESS)
{
for (i = 0; i < layer_count; i++)
{
if (strcmp(layers[i].layerName, debug_layer_name) == 0)
{
instance_info.enabledLayerCount = 1;
instance_info.ppEnabledLayerNames = &debug_layer_name;
break;
}
}
}
if (instance_info.enabledLayerCount == 0)
ERR("Failed to enumerate instance layers, will not use VK_LAYER_KHRONOS_validation!\n");
vkd3d_free(layers);
}
vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance);
vkd3d_free((void *)extensions);
if (vr < 0)
{
ERR("Failed to create Vulkan instance, vr %d.\n", vr);
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);
return hresult_from_vk_result(vr);
}
TRACE("Created Vulkan instance %p, version %u.%u.\n", vk_instance,
VK_VERSION_MAJOR(loader_version),
VK_VERSION_MINOR(loader_version));
}
if (FAILED(hr = vkd3d_load_vk_instance_procs(&instance->vk_procs, vk_global_procs, vk_instance)))
{
ERR("Failed to load instance procs, hr %#x.\n", hr);
if (instance->vk_procs.vkDestroyInstance)
if (instance->vk_procs.vkDestroyInstance && !instance->external_vk_instance)
instance->vk_procs.vkDestroyInstance(vk_instance, NULL);
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);
@ -665,17 +695,12 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
instance->vk_instance = vk_instance;
instance->instance_version = loader_version;
TRACE("Created Vulkan instance %p, version %u.%u.\n", vk_instance,
VK_VERSION_MAJOR(loader_version),
VK_VERSION_MINOR(loader_version));
instance->refcount = 1;
instance->vk_debug_callback = VK_NULL_HANDLE;
if (instance->vk_info.EXT_debug_utils && (vkd3d_config_flags & VKD3D_CONFIG_FLAG_VULKAN_DEBUG))
vkd3d_init_debug_messenger_callback(instance);
#ifdef VKD3D_ENABLE_RENDERDOC
/* Need to init this sometime after creating the instance so that the layer has loaded. */
vkd3d_renderdoc_init();
@ -730,7 +755,8 @@ static void vkd3d_destroy_instance(struct vkd3d_instance *instance)
if (instance->vk_debug_callback)
VK_CALL(vkDestroyDebugUtilsMessengerEXT(vk_instance, instance->vk_debug_callback, NULL));
VK_CALL(vkDestroyInstance(vk_instance, NULL));
if (!instance->external_vk_instance)
VK_CALL(vkDestroyInstance(vk_instance, NULL));
if (instance->libvulkan)
vkd3d_dlclose(instance->libvulkan);

View File

@ -189,6 +189,7 @@ struct vkd3d_instance
VkDebugUtilsMessengerEXT vk_debug_callback;
bool external_vk_instance;
LONG refcount;
};