mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-05-14 15:42:34 +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 = [
|
||||
'vrclient_init',
|
||||
'vrclient_init_registry',
|
||||
'vrclient_get_unix_buffer',
|
||||
'vrclient_HmdSystemFactory',
|
||||
'vrclient_VRClientCoreFactory',
|
||||
'vrclient_unload',
|
||||
|
@ -30,6 +30,7 @@ extern NTSTATUS vrclient_init_registry( void *args );
|
||||
extern NTSTATUS vrclient_unload( void *args );
|
||||
extern NTSTATUS vrclient_HmdSystemFactory( 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 void vrclient_free_path( char *path );
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
#include <winternl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#define WINE_VK_HOST
|
||||
#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 );
|
||||
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;
|
||||
};
|
||||
|
||||
struct vrclient_get_unix_buffer_params
|
||||
{
|
||||
struct u_buffer buf;
|
||||
void *ptr; /* client-side ptr */
|
||||
};
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#define VRCLIENT_CALL( code, args ) \
|
||||
|
@ -9,6 +9,7 @@ extern "C" const unixlib_entry_t __wine_unix_call_funcs[] =
|
||||
{
|
||||
vrclient_init,
|
||||
vrclient_init_registry,
|
||||
vrclient_get_unix_buffer,
|
||||
vrclient_HmdSystemFactory,
|
||||
vrclient_VRClientCoreFactory,
|
||||
vrclient_unload,
|
||||
|
@ -29223,6 +29223,7 @@ enum unix_funcs
|
||||
{
|
||||
unix_vrclient_init,
|
||||
unix_vrclient_init_registry,
|
||||
unix_vrclient_get_unix_buffer,
|
||||
unix_vrclient_HmdSystemFactory,
|
||||
unix_vrclient_VRClientCoreFactory,
|
||||
unix_vrclient_unload,
|
||||
|
@ -314,6 +314,24 @@ BOOL CDECL vrclient_init_registry(void)
|
||||
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)
|
||||
{
|
||||
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 );
|
||||
void free_compositor_data_d3d12_device(void);
|
||||
|
||||
extern void *get_unix_buffer( struct u_buffer buf );
|
||||
|
||||
struct generic_interface
|
||||
{
|
||||
struct w_iface *object;
|
||||
|
@ -134,3 +134,13 @@ struct u_iface
|
||||
template< typename T > operator T*() const { return (T*)(UINT_PTR)this->handle; }
|
||||
#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