mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-07-14 17:26:18 +03:00
vrclient: Read Vulkan instance extensions from registry in load_vrclient().
CW-Bug-Id: #24553 CW-Bug-Id: #24891
This commit is contained in:
parent
0142040ba9
commit
bfeda97e32
@ -31,6 +31,8 @@ CREATE_TYPE_INFO_VTABLE;
|
|||||||
struct compositor_data compositor_data = {0};
|
struct compositor_data compositor_data = {0};
|
||||||
static BOOL vrclient_loaded;
|
static BOOL vrclient_loaded;
|
||||||
|
|
||||||
|
char *g_instance_extensions;
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||||
{
|
{
|
||||||
TRACE("(%p, %lu, %p)\n", instance, reason, reserved);
|
TRACE("(%p, %lu, %p)\n", instance, reason, reserved);
|
||||||
@ -64,6 +66,91 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL get_vulkan_extensions_from_registry(void)
|
||||||
|
{
|
||||||
|
DWORD type, value, size = sizeof(value), wait_result;
|
||||||
|
LSTATUS status;
|
||||||
|
HANDLE event;
|
||||||
|
HKEY vr_key;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
if ((status = RegOpenKeyExA( HKEY_CURRENT_USER, "Software\\Wine\\VR", 0, KEY_READ, &vr_key )))
|
||||||
|
{
|
||||||
|
ERR( "Could not create key, status %#lx.\n", status );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = RegQueryValueExA( vr_key, "state", NULL, &type, (BYTE *)&value, &size )))
|
||||||
|
{
|
||||||
|
ERR( "Could not query VR state, status %#lx\n", status );
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (type != REG_DWORD)
|
||||||
|
{
|
||||||
|
ERR( "Invalid VR state type: %lx\n", type );
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
event = CreateEventA( NULL, FALSE, FALSE, NULL );
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (RegNotifyChangeKeyValue( vr_key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, event, TRUE ))
|
||||||
|
{
|
||||||
|
ERR( "Error registering VR key change notification" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size = sizeof(value);
|
||||||
|
if ((status = RegQueryValueExA( vr_key, "state", NULL, &type, (BYTE *)&value, &size )))
|
||||||
|
{
|
||||||
|
ERR( "Couild not query VR state, status %#lx\n", status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (value) break;
|
||||||
|
while ((wait_result = WaitForSingleObject( event, 1000 )) == WAIT_TIMEOUT)
|
||||||
|
WARN( "Waiting for VR to become ready\n" );
|
||||||
|
|
||||||
|
if (wait_result != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
ERR( "Wait for VR state change failed\n" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != 1)
|
||||||
|
{
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ((status = RegQueryValueExA( vr_key, "openvr_vulkan_instance_extensions", NULL, &type, NULL, &len )))
|
||||||
|
{
|
||||||
|
ERR( "Could not query openvr vulkan instance extensions, status %#lx\n", status );
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(g_instance_extensions = malloc(len)))
|
||||||
|
{
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = RegQueryValueExA( vr_key, "openvr_vulkan_instance_extensions", NULL, &type,
|
||||||
|
(BYTE *)g_instance_extensions, &len )))
|
||||||
|
{
|
||||||
|
ERR( "Error getting openvr_vulkan_instance_extensions, status %#lx.\n", status );
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey( vr_key );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
|
static BOOL array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
|
||||||
{
|
{
|
||||||
SIZE_T max_capacity, new_capacity;
|
SIZE_T max_capacity, new_capacity;
|
||||||
@ -107,7 +194,7 @@ struct w_iface *create_win_interface( const char *name, struct u_iface u_iface )
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_vrclient(void)
|
static int load_vrclient( BOOL initializing_registry )
|
||||||
{
|
{
|
||||||
struct vrclient_init_params params = {.winevulkan = LoadLibraryW( L"winevulkan.dll" )};
|
struct vrclient_init_params params = {.winevulkan = LoadLibraryW( L"winevulkan.dll" )};
|
||||||
WCHAR pathW[PATH_MAX];
|
WCHAR pathW[PATH_MAX];
|
||||||
@ -123,6 +210,12 @@ static int load_vrclient(void)
|
|||||||
|
|
||||||
if (vrclient_loaded) return 1;
|
if (vrclient_loaded) return 1;
|
||||||
|
|
||||||
|
if (!(initializing_registry || get_vulkan_extensions_from_registry()))
|
||||||
|
{
|
||||||
|
TRACE( "Error getting extensions from registry.\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* PROTON_VR_RUNTIME is provided by the proton setup script */
|
/* PROTON_VR_RUNTIME is provided by the proton setup script */
|
||||||
if(!GetEnvironmentVariableW(L"PROTON_VR_RUNTIME", pathW, ARRAY_SIZE(pathW)))
|
if(!GetEnvironmentVariableW(L"PROTON_VR_RUNTIME", pathW, ARRAY_SIZE(pathW)))
|
||||||
{
|
{
|
||||||
@ -184,7 +277,7 @@ void * __stdcall HmdSystemFactory(const char *name, int *return_code)
|
|||||||
{
|
{
|
||||||
struct vrclient_HmdSystemFactory_params params = {.name = name, .return_code = return_code};
|
struct vrclient_HmdSystemFactory_params params = {.name = name, .return_code = return_code};
|
||||||
TRACE("name: %s, return_code: %p\n", name, return_code);
|
TRACE("name: %s, return_code: %p\n", name, return_code);
|
||||||
if (!load_vrclient()) return NULL;
|
if (!load_vrclient( FALSE )) return NULL;
|
||||||
VRCLIENT_CALL( vrclient_HmdSystemFactory, ¶ms );
|
VRCLIENT_CALL( vrclient_HmdSystemFactory, ¶ms );
|
||||||
return create_win_interface( name, params._ret );
|
return create_win_interface( name, params._ret );
|
||||||
}
|
}
|
||||||
@ -193,7 +286,7 @@ void * __stdcall VRClientCoreFactory(const char *name, int *return_code)
|
|||||||
{
|
{
|
||||||
struct vrclient_VRClientCoreFactory_params params = {.name = name, .return_code = return_code};
|
struct vrclient_VRClientCoreFactory_params params = {.name = name, .return_code = return_code};
|
||||||
TRACE("name: %s, return_code: %p\n", name, return_code);
|
TRACE("name: %s, return_code: %p\n", name, return_code);
|
||||||
if (!load_vrclient()) return NULL;
|
if (!load_vrclient( FALSE )) return NULL;
|
||||||
VRCLIENT_CALL( vrclient_VRClientCoreFactory, ¶ms );
|
VRCLIENT_CALL( vrclient_VRClientCoreFactory, ¶ms );
|
||||||
return create_win_interface( name, params._ret );
|
return create_win_interface( name, params._ret );
|
||||||
}
|
}
|
||||||
@ -288,7 +381,7 @@ BOOL CDECL vrclient_init_registry(void)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!load_vrclient())
|
if (!load_vrclient( TRUE ))
|
||||||
{
|
{
|
||||||
TRACE( "Failed to load vrclient\n" );
|
TRACE( "Failed to load vrclient\n" );
|
||||||
set_vr_status( vr_key, -1 );
|
set_vr_status( vr_key, -1 );
|
||||||
|
@ -112,6 +112,8 @@ struct generic_interface
|
|||||||
void (*dtor)(struct w_iface *);
|
void (*dtor)(struct w_iface *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern char *g_instance_extensions;
|
||||||
|
|
||||||
#ifdef __dxvk_interop_h__
|
#ifdef __dxvk_interop_h__
|
||||||
extern w_Texture_t vrclient_translate_texture_dxvk( const w_Texture_t *texture, w_VRVulkanTextureData_t *vkdata,
|
extern w_Texture_t vrclient_translate_texture_dxvk( const w_Texture_t *texture, w_VRVulkanTextureData_t *vkdata,
|
||||||
IDXGIVkInteropSurface *dxvk_surface, IDXGIVkInteropDevice **p_dxvk_device,
|
IDXGIVkInteropSurface *dxvk_surface, IDXGIVkInteropDevice **p_dxvk_device,
|
||||||
|
@ -3,57 +3,6 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(vrclient);
|
WINE_DEFAULT_DEBUG_CHANNEL(vrclient);
|
||||||
|
|
||||||
static BOOL wait_vr_key_ready( HKEY vr_key )
|
|
||||||
{
|
|
||||||
DWORD type, value, size = sizeof(value), wait_result;
|
|
||||||
LSTATUS status;
|
|
||||||
HANDLE event;
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
if ((status = RegQueryValueExA(vr_key, "state", NULL, &type, (BYTE *)&value, &size)))
|
|
||||||
{
|
|
||||||
ERR("Could not query VR state, status %lx\n", status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (type != REG_DWORD)
|
|
||||||
{
|
|
||||||
ERR("Invalid VR state type: %lx\n", type);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (value) return value == 1;
|
|
||||||
|
|
||||||
event = CreateEventA(NULL, FALSE, FALSE, NULL);
|
|
||||||
ret = FALSE;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (RegNotifyChangeKeyValue(vr_key, FALSE, REG_NOTIFY_CHANGE_LAST_SET, event, TRUE))
|
|
||||||
{
|
|
||||||
ERR("Error registering VR key change notification");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
size = sizeof(value);
|
|
||||||
if ((status = RegQueryValueExA(vr_key, "state", NULL, &type, (BYTE *)&value, &size)))
|
|
||||||
{
|
|
||||||
ERR("Couild not query VR state, status %lx\n", status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
ret = value == 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while ((wait_result = WaitForSingleObject(event, 1000)) == WAIT_TIMEOUT)
|
|
||||||
WARN("Waiting for VR to because ready\n");
|
|
||||||
if (wait_result != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
ERR("Wait for VR state change failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CloseHandle(event);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkResult fixup_get_output_device_pre( HMODULE winevulkan, uint32_t *texture_type, VkInstance *instance )
|
VkResult fixup_get_output_device_pre( HMODULE winevulkan, uint32_t *texture_type, VkInstance *instance )
|
||||||
{
|
{
|
||||||
/* OpenVR IVRSystem::GetOutputDevice requires a VkInstance if textureType is Vulkan,
|
/* OpenVR IVRSystem::GetOutputDevice requires a VkInstance if textureType is Vulkan,
|
||||||
@ -62,11 +11,9 @@ VkResult fixup_get_output_device_pre( HMODULE winevulkan, uint32_t *texture_type
|
|||||||
PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr;
|
PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr;
|
||||||
PFN_vkCreateInstance p_vkCreateInstance;
|
PFN_vkCreateInstance p_vkCreateInstance;
|
||||||
const char **instance_extension_list;
|
const char **instance_extension_list;
|
||||||
DWORD type, len, extension_count = 0;
|
|
||||||
char *instance_extensions, *pos;
|
char *instance_extensions, *pos;
|
||||||
|
DWORD extension_count = 0;
|
||||||
VkResult vk_result;
|
VkResult vk_result;
|
||||||
LSTATUS status;
|
|
||||||
HKEY vr_key;
|
|
||||||
|
|
||||||
VkInstanceCreateInfo create_info = {
|
VkInstanceCreateInfo create_info = {
|
||||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||||
@ -75,37 +22,13 @@ VkResult fixup_get_output_device_pre( HMODULE winevulkan, uint32_t *texture_type
|
|||||||
if (*texture_type != TextureType_DirectX && *texture_type != TextureType_DirectX12 && *texture_type != TextureType_DXGISharedHandle)
|
if (*texture_type != TextureType_DirectX && *texture_type != TextureType_DirectX12 && *texture_type != TextureType_DXGISharedHandle)
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
if (!g_instance_extensions)
|
||||||
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
|
|
||||||
p_vkGetInstanceProcAddr = (void *)GetProcAddress(winevulkan, "vkGetInstanceProcAddr");
|
p_vkGetInstanceProcAddr = (void *)GetProcAddress(winevulkan, "vkGetInstanceProcAddr");
|
||||||
p_vkCreateInstance = (void *)p_vkGetInstanceProcAddr(NULL, "vkCreateInstance");
|
p_vkCreateInstance = (void *)p_vkGetInstanceProcAddr(NULL, "vkCreateInstance");
|
||||||
|
|
||||||
if ((status = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\VR", 0, KEY_READ, &vr_key)))
|
instance_extensions = strdup(g_instance_extensions);
|
||||||
{
|
|
||||||
ERR("Failed to open OpenVR registry key, status %lx\n", status);
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
}
|
|
||||||
if (!wait_vr_key_ready(vr_key))
|
|
||||||
{
|
|
||||||
RegCloseKey(vr_key);
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status = RegQueryValueExA(vr_key, "openvr_vulkan_instance_extensions", NULL, &type, NULL, &len)))
|
|
||||||
{
|
|
||||||
ERR("Could not query openvr vulkan instance extensions, status %lx\n", status);
|
|
||||||
RegCloseKey(vr_key);
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_extensions = calloc(len + 1, 1);
|
|
||||||
status = RegQueryValueExA(vr_key, "openvr_vulkan_instance_extensions", NULL, &type, (BYTE *)instance_extensions, &len);
|
|
||||||
RegCloseKey(vr_key);
|
|
||||||
if (status)
|
|
||||||
{
|
|
||||||
ERR("Could not query openvr vulkan instance extensions, status %lx\n", status);
|
|
||||||
free(instance_extensions);
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Creating VkInstance for IVRSystem::GetOutputDevice\n");
|
TRACE("Creating VkInstance for IVRSystem::GetOutputDevice\n");
|
||||||
|
|
||||||
has_get_device_properties2 = strstr(instance_extensions, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) != NULL;
|
has_get_device_properties2 = strstr(instance_extensions, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) != NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user