[PATCH 4/4] server, ntdll: Allow storage of API data inside of GPU Resource objects.
Derek Lesho
dlesho at codeweavers.com
Wed Oct 30 11:46:50 CDT 2019
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 at 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);
+ at END
+
+/* Sets the userdata of the GPU resource */
+ at REQ(set_userdata_gpu_resource)
+ obj_handle_t handle;
+ VARARG(userdata,bytes);
@END
--
2.23.0
More information about the wine-devel
mailing list