mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-05-14 23:52:35 +03:00
vrclient: Introduce unix-side buffer cache with PE allocate pointers.
There are several steam API calls that currently pass unix pointers for e.g. strings directly to the PE-side, this allows for caching such return values and returning a PE-side pointer instead.
This commit is contained in:
parent
6c13702ab3
commit
85151b7dfa
@ -223,6 +223,7 @@ unique_structs = []
|
|||||||
UNIX_FUNCS = [
|
UNIX_FUNCS = [
|
||||||
'vrclient_init',
|
'vrclient_init',
|
||||||
'vrclient_init_registry',
|
'vrclient_init_registry',
|
||||||
|
'vrclient_get_unix_buffer',
|
||||||
'vrclient_HmdSystemFactory',
|
'vrclient_HmdSystemFactory',
|
||||||
'vrclient_VRClientCoreFactory',
|
'vrclient_VRClientCoreFactory',
|
||||||
'vrclient_unload',
|
'vrclient_unload',
|
||||||
|
@ -30,6 +30,7 @@ extern NTSTATUS vrclient_init_registry( void *args );
|
|||||||
extern NTSTATUS vrclient_unload( void *args );
|
extern NTSTATUS vrclient_unload( void *args );
|
||||||
extern NTSTATUS vrclient_HmdSystemFactory( void *args );
|
extern NTSTATUS vrclient_HmdSystemFactory( void *args );
|
||||||
extern NTSTATUS vrclient_VRClientCoreFactory( void *args );
|
extern NTSTATUS vrclient_VRClientCoreFactory( void *args );
|
||||||
|
extern NTSTATUS vrclient_get_unix_buffer( void *args );
|
||||||
|
|
||||||
extern char *vrclient_dos_to_unix_path( const char *src );
|
extern char *vrclient_dos_to_unix_path( const char *src );
|
||||||
extern void vrclient_free_path( char *path );
|
extern void vrclient_free_path( char *path );
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#define WINE_VK_HOST
|
#define WINE_VK_HOST
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
@ -370,3 +372,35 @@ NTSTATUS IVRTrackedCamera_IVRTrackedCamera_001_GetVideoStreamFrame( void *args )
|
|||||||
*(w_CameraVideoStreamFrame_t_0914 *)params->_ret = *iface->GetVideoStreamFrame( params->nDeviceIndex );
|
*(w_CameraVideoStreamFrame_t_0914 *)params->_ret = *iface->GetVideoStreamFrame( params->nDeviceIndex );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<> struct hash< struct u_buffer >
|
||||||
|
{
|
||||||
|
using argument_type = struct u_buffer;
|
||||||
|
using result_type = std::size_t;
|
||||||
|
result_type operator()( argument_type const& buf ) const { return buf.ptr; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static pthread_mutex_t buffer_cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static std::unordered_map< struct u_buffer, void * > buffer_cache;
|
||||||
|
|
||||||
|
NTSTATUS vrclient_get_unix_buffer( void *args )
|
||||||
|
{
|
||||||
|
struct vrclient_get_unix_buffer_params *params = (struct vrclient_get_unix_buffer_params *)args;
|
||||||
|
struct cache_entry *entry;
|
||||||
|
struct rb_entry *ptr;
|
||||||
|
|
||||||
|
pthread_mutex_lock( &buffer_cache_lock );
|
||||||
|
auto iter = buffer_cache.find( params->buf );
|
||||||
|
if (iter != buffer_cache.end()) params->ptr = iter->second;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy( params->ptr, (char *)params->buf, params->buf.len );
|
||||||
|
buffer_cache[params->buf] = params->ptr;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock( &buffer_cache_lock );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -73,6 +73,12 @@ struct vrclient_VRClientCoreFactory_params
|
|||||||
int *return_code;
|
int *return_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vrclient_get_unix_buffer_params
|
||||||
|
{
|
||||||
|
struct u_buffer buf;
|
||||||
|
void *ptr; /* client-side ptr */
|
||||||
|
};
|
||||||
|
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
|
|
||||||
#define VRCLIENT_CALL( code, args ) \
|
#define VRCLIENT_CALL( code, args ) \
|
||||||
|
@ -9,6 +9,7 @@ extern "C" const unixlib_entry_t __wine_unix_call_funcs[] =
|
|||||||
{
|
{
|
||||||
vrclient_init,
|
vrclient_init,
|
||||||
vrclient_init_registry,
|
vrclient_init_registry,
|
||||||
|
vrclient_get_unix_buffer,
|
||||||
vrclient_HmdSystemFactory,
|
vrclient_HmdSystemFactory,
|
||||||
vrclient_VRClientCoreFactory,
|
vrclient_VRClientCoreFactory,
|
||||||
vrclient_unload,
|
vrclient_unload,
|
||||||
|
@ -29223,6 +29223,7 @@ enum unix_funcs
|
|||||||
{
|
{
|
||||||
unix_vrclient_init,
|
unix_vrclient_init,
|
||||||
unix_vrclient_init_registry,
|
unix_vrclient_init_registry,
|
||||||
|
unix_vrclient_get_unix_buffer,
|
||||||
unix_vrclient_HmdSystemFactory,
|
unix_vrclient_HmdSystemFactory,
|
||||||
unix_vrclient_VRClientCoreFactory,
|
unix_vrclient_VRClientCoreFactory,
|
||||||
unix_vrclient_unload,
|
unix_vrclient_unload,
|
||||||
|
@ -314,6 +314,24 @@ BOOL CDECL vrclient_init_registry(void)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *get_unix_buffer( struct u_buffer buf )
|
||||||
|
{
|
||||||
|
struct vrclient_get_unix_buffer_params params = {.buf = buf};
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if ((UINT_PTR)buf.ptr == buf.ptr && (UINT_PTR)(buf.ptr + buf.len) == (buf.ptr + buf.len))
|
||||||
|
return (void *)(UINT_PTR)buf.ptr;
|
||||||
|
|
||||||
|
if (!(params.ptr = ret = HeapAlloc( GetProcessHeap(), 0, buf.len ))) return NULL;
|
||||||
|
if (VRCLIENT_CALL( vrclient_get_unix_buffer, ¶ms ) || (ret != params.ptr))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, ret );
|
||||||
|
ret = params.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int8_t is_hmd_present_reg(void)
|
static int8_t is_hmd_present_reg(void)
|
||||||
{
|
{
|
||||||
DWORD type, value, wait_status, size;
|
DWORD type, value, wait_status, size;
|
||||||
|
@ -104,6 +104,8 @@ extern void init_rtti( char *base );
|
|||||||
struct w_iface *create_win_interface( const char *name, struct u_iface u_iface );
|
struct w_iface *create_win_interface( const char *name, struct u_iface u_iface );
|
||||||
void free_compositor_data_d3d12_device(void);
|
void free_compositor_data_d3d12_device(void);
|
||||||
|
|
||||||
|
extern void *get_unix_buffer( struct u_buffer buf );
|
||||||
|
|
||||||
struct generic_interface
|
struct generic_interface
|
||||||
{
|
{
|
||||||
struct w_iface *object;
|
struct w_iface *object;
|
||||||
|
@ -134,3 +134,13 @@ struct u_iface
|
|||||||
template< typename T > operator T*() const { return (T*)(UINT_PTR)this->handle; }
|
template< typename T > operator T*() const { return (T*)(UINT_PTR)this->handle; }
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct u_buffer
|
||||||
|
{
|
||||||
|
UINT64 ptr;
|
||||||
|
UINT64 len;
|
||||||
|
#ifdef __cplusplus
|
||||||
|
struct u_buffer &operator=(const char* value) { this->ptr = (UINT_PTR)value; this->len = value ? strlen( value ) + 1 : 0; return *this; }
|
||||||
|
operator char*() const { return (char*)(UINT_PTR)this->ptr; }
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user