This is necessary when Graphics API Layers are emulating APIs that support sharing resources with more details than just the underlying memory.
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/ntdll/gpu_resource.c | 30 +++++++++++++++++++++--- dlls/ntdll/ntdll.spec | 3 ++- dlls/winevulkan/vulkan.c | 4 ++-- server/gpu_resource.c | 49 +++++++++++++++++++++++++++++++++++---- server/protocol.def | 9 ++++++- 5 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/gpu_resource.c b/dlls/ntdll/gpu_resource.c index 63488016b1..00d07cd4fd 100644 --- a/dlls/ntdll/gpu_resource.c +++ b/dlls/ntdll/gpu_resource.c @@ -87,16 +87,40 @@ NTSTATUS CDECL __wine_get_gpu_resource_fd(HANDLE handle, int *fd, int *needs_clo return ret; }
-/* gets KMT handle */ -NTSTATUS CDECL __wine_get_gpu_resource_info(HANDLE handle, HANDLE *kmt_handle) +/* gets KMT handle and userdata */ +NTSTATUS CDECL __wine_get_gpu_resource_info(HANDLE handle, HANDLE *kmt_handle, void *user_data_buf, unsigned int *user_data_len) { NTSTATUS ret; + BOOL get_user_data = user_data_buf && user_data_len;
SERVER_START_REQ(query_gpu_resource) { req->handle = wine_server_obj_handle( handle ); + if (get_user_data) + wine_server_set_reply(req, user_data_buf, *user_data_len); if (!(ret = wine_server_call(req))) - *kmt_handle = wine_server_ptr_handle( reply->kmt_handle ); + { + if (kmt_handle) + *kmt_handle = wine_server_ptr_handle( reply->kmt_handle ); + if (user_data_len) + *user_data_len = wine_server_reply_size(reply); + } + } + SERVER_END_REQ; + + return ret; +} + +/* Updates the userdata of the GPU resource */ +NTSTATUS CDECL __wine_set_gpu_resource_userdata(HANDLE handle, void *user_data, unsigned int user_data_len) +{ + NTSTATUS ret; + + SERVER_START_REQ(set_userdata_gpu_resource) + { + req->handle = wine_server_obj_handle(handle); + wine_server_add_data(req, user_data, user_data_len); + ret = wine_server_call( req ); } SERVER_END_REQ;
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 4cc03469f9..e80b28f14f 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1574,4 +1574,5 @@ @ cdecl __wine_create_gpu_resource(ptr ptr long ptr long) @ cdecl __wine_open_gpu_resource(ptr ptr long ptr) @ cdecl __wine_get_gpu_resource_fd(ptr ptr ptr) -@ cdecl __wine_get_gpu_resource_info(ptr ptr) \ No newline at end of file +@ cdecl __wine_get_gpu_resource_info(ptr ptr ptr ptr) +@ cdecl __wine_set_gpu_resource_userdata(ptr ptr long) \ No newline at end of file diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 01cab11e21..36da6e2326 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -1169,7 +1169,7 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle, extern NTSTATUS CDECL __wine_create_gpu_resource(PHANDLE handle, PHANDLE kmt_handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, int fd ); extern NTSTATUS CDECL __wine_open_gpu_resource(HANDLE kmt_handle, OBJECT_ATTRIBUTES *attr, DWORD access, PHANDLE handle ); extern NTSTATUS CDECL __wine_get_gpu_resource_fd(HANDLE handle, int *fd, int *needs_close); -extern NTSTATUS CDECL __wine_get_gpu_resource_info(HANDLE handle, HANDLE *kmt_handle); +extern NTSTATUS CDECL __wine_get_gpu_resource_info(HANDLE handle, HANDLE *kmt_handle, void *user_data_buf, unsigned int *user_data_len);
static NTSTATUS server_create_dxgi_resource( PHANDLE handle, PHANDLE kmt_handle, int fd, DWORD access, SECURITY_ATTRIBUTES *sa, LPCWSTR name ) { @@ -1318,7 +1318,7 @@ VkResult WINAPI wine_vkAllocateMemory(VkDevice device, const VkMemoryAllocateInf { /* occurs if the caller imports *and* exports the memory */ if (handle_types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT && object->kmt_handle == INVALID_HANDLE_VALUE) - __wine_get_gpu_resource_info(object->handle, &object->kmt_handle); + __wine_get_gpu_resource_info(object->handle, &object->kmt_handle, NULL, NULL); } else { int fd; VkMemoryGetFdInfoKHR host_fd_info; diff --git a/server/gpu_resource.c b/server/gpu_resource.c index bc083a2f42..e9fd493ab5 100644 --- a/server/gpu_resource.c +++ b/server/gpu_resource.c @@ -22,6 +22,10 @@ struct gpu_resource struct list kernel_object; struct fd *fd; obj_handle_t kmt_handle; /* more like an ID */ + + /* used by API layers to store extra information about a resource */ + void *user_data; + data_size_t user_data_len; };
/* gpu_resource functions */ @@ -216,6 +220,7 @@ struct gpu_resource *create_gpu_resource(struct object *root, const struct unico return NULL; } resource->kmt_handle = alloc_kmt_handle( resource ); + resource->user_data = 0; allow_fd_caching( resource->fd ); } } @@ -287,12 +292,48 @@ struct gpu_resource *get_resource_obj( struct process *process, obj_handle_t han return (struct gpu_resource *)get_handle_obj( process, handle, access, &gpu_resource_ops ); }
-/* Query KMT handle of GPU Resource */ +/* Query KMT handle and user data of GPU Resource */ DECL_HANDLER(query_gpu_resource) { struct gpu_resource *resource; + data_size_t reply_size = get_reply_max_size(); + + if ((resource = get_resource_obj( current->process, req->handle, 0 ))) + { + reply->kmt_handle = resource->kmt_handle; + + if (reply_size) + { + if (reply_size >= resource->user_data_len) + set_reply_data(resource->user_data, resource->user_data_len); + else + set_error(STATUS_BUFFER_TOO_SMALL); + }
- if (!(resource = get_resource_obj( current->process, req->handle, 0 ))) return; - reply->kmt_handle = resource->kmt_handle; - release_object(resource); + release_object(resource); + } } + +/* Sets the user data of the GPU resource */ +DECL_HANDLER(set_userdata_gpu_resource) +{ + struct gpu_resource *resource; + data_size_t len = get_req_data_size(); + + if ((resource = get_resource_obj( current->process, req->handle, 0 ))) + { + free(resource->user_data); + resource->user_data = mem_alloc(len); + if (resource->user_data) + { + memcpy(resource->user_data, get_req_data(), len); + resource->user_data_len = len; + } + else + { + set_error(STATUS_NO_MEMORY); + } + + release_object(resource); + } +} \ No newline at end of file diff --git a/server/protocol.def b/server/protocol.def index a4bc550544..33d0287b37 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3960,11 +3960,18 @@ struct handle_info @END
-/* Query KMT Handle of GPU Resource */ +/* Query KMT Handle and user data of GPU Resource */ @REQ(query_gpu_resource) obj_handle_t handle; @REPLY obj_handle_t kmt_handle; + VARARG(userdata,bytes); +@END + +/* Sets the userdata of the GPU resource */ +@REQ(set_userdata_gpu_resource) + obj_handle_t handle; + VARARG(userdata,bytes); @END