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};
|
||||
static BOOL vrclient_loaded;
|
||||
|
||||
char *g_instance_extensions;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||
{
|
||||
TRACE("(%p, %lu, %p)\n", instance, reason, reserved);
|
||||
@ -64,6 +66,91 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static int load_vrclient(void)
|
||||
static int load_vrclient( BOOL initializing_registry )
|
||||
{
|
||||
struct vrclient_init_params params = {.winevulkan = LoadLibraryW( L"winevulkan.dll" )};
|
||||
WCHAR pathW[PATH_MAX];
|
||||
@ -123,6 +210,12 @@ static int load_vrclient(void)
|
||||
|
||||
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 */
|
||||
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};
|
||||
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 );
|
||||
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};
|
||||
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 );
|
||||
return create_win_interface( name, params._ret );
|
||||
}
|
||||
@ -288,7 +381,7 @@ BOOL CDECL vrclient_init_registry(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!load_vrclient())
|
||||
if (!load_vrclient( TRUE ))
|
||||
{
|
||||
TRACE( "Failed to load vrclient\n" );
|
||||
set_vr_status( vr_key, -1 );
|
||||
|
@ -112,6 +112,8 @@ struct generic_interface
|
||||
void (*dtor)(struct w_iface *);
|
||||
};
|
||||
|
||||
extern char *g_instance_extensions;
|
||||
|
||||
#ifdef __dxvk_interop_h__
|
||||
extern w_Texture_t vrclient_translate_texture_dxvk( const w_Texture_t *texture, w_VRVulkanTextureData_t *vkdata,
|
||||
IDXGIVkInteropSurface *dxvk_surface, IDXGIVkInteropDevice **p_dxvk_device,
|
||||
|
@ -3,57 +3,6 @@
|
||||
|
||||
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 )
|
||||
{
|
||||
/* 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_vkCreateInstance p_vkCreateInstance;
|
||||
const char **instance_extension_list;
|
||||
DWORD type, len, extension_count = 0;
|
||||
char *instance_extensions, *pos;
|
||||
DWORD extension_count = 0;
|
||||
VkResult vk_result;
|
||||
LSTATUS status;
|
||||
HKEY vr_key;
|
||||
|
||||
VkInstanceCreateInfo 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)
|
||||
return VK_SUCCESS;
|
||||
|
||||
if (!g_instance_extensions)
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
|
||||
p_vkGetInstanceProcAddr = (void *)GetProcAddress(winevulkan, "vkGetInstanceProcAddr");
|
||||
p_vkCreateInstance = (void *)p_vkGetInstanceProcAddr(NULL, "vkCreateInstance");
|
||||
|
||||
if ((status = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\VR", 0, KEY_READ, &vr_key)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
instance_extensions = strdup(g_instance_extensions);
|
||||
TRACE("Creating VkInstance for IVRSystem::GetOutputDevice\n");
|
||||
|
||||
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