A Wine-specific D3DKMTEscape code to update a previously created and exported global D3DKMT resource runtime data.
-- v2: win32u: Introduce a new D3DKMT_ESCAPE_UPDATE_RESOURCE_WINE code.
From: Rémi Bernon rbernon@codeweavers.com
A Wine-specific D3DKMTEscape code to update a previously created and exported global D3DKMT resource runtime data. --- dlls/win32u/d3dkmt.c | 40 ++++++++++++++++++++++++++++++++++++++-- include/ddk/d3dkmthk.h | 2 ++ server/d3dkmt.c | 24 ++++++++++++++++++++++++ server/protocol.def | 9 +++++++++ 4 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index a048aca740a..50ddfdfaa38 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -202,6 +202,26 @@ static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *object, BOOL shared, return status; }
+static NTSTATUS d3dkmt_object_update( enum d3dkmt_type type, D3DKMT_HANDLE global, HANDLE handle, + const void *runtime, UINT runtime_size ) +{ + NTSTATUS status; + + SERVER_START_REQ( d3dkmt_object_update ) + { + req->type = type; + req->global = global; + req->handle = wine_server_obj_handle( handle ); + if (runtime_size) wine_server_add_data( req, runtime, runtime_size ); + status = wine_server_call( req ); + } + SERVER_END_REQ; + + if (status) WARN( "Failed to update global object %#x/%p, status %#x\n", global, handle, status ); + else TRACE( "Updated global object %#x/%p\n", global, handle ); + return status; +} + static NTSTATUS d3dkmt_object_open( struct d3dkmt_object *obj, D3DKMT_HANDLE global, HANDLE handle, void *runtime, UINT *runtime_size ) { @@ -435,8 +455,24 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ) */ NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ) { - FIXME( "(%p): stub\n", desc ); - return STATUS_NO_MEMORY; + HANDLE shared; + + switch (desc->Type) + { + case D3DKMT_ESCAPE_UPDATE_RESOURCE_WINE: + TRACE( "D3DKMT_ESCAPE_UPDATE_RESOURCE_WINE hContext %#x, pPrivateDriverData %p, PrivateDriverDataSize %#x\n", + desc->hContext, desc->pPrivateDriverData, desc->PrivateDriverDataSize ); + + if (is_d3dkmt_global( desc->hContext )) shared = NULL; + else shared = UlongToHandle( desc->hContext ); + + return d3dkmt_object_update( D3DKMT_RESOURCE, shared ? 0 : desc->hContext, shared, + desc->pPrivateDriverData, desc->PrivateDriverDataSize ); + + default: + FIXME( "(%p): stub\n", desc ); + return STATUS_NO_MEMORY; + } }
/****************************************************************************** diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h index 0cac5c7beaf..2650ff723aa 100644 --- a/include/ddk/d3dkmthk.h +++ b/include/ddk/d3dkmthk.h @@ -768,6 +768,8 @@ typedef enum _D3DKMT_ESCAPETYPE D3DKMT_ESCAPE_SETDRIVERUPDATESTATUS, D3DKMT_ESCAPE_DRT_TEST, D3DKMT_ESCAPE_DIAGNOSTICS, + /* Wine-specific escape codes */ + D3DKMT_ESCAPE_UPDATE_RESOURCE_WINE = 0x80000000, } D3DKMT_ESCAPETYPE;
typedef struct _D3DKMT_ESCAPE diff --git a/server/d3dkmt.c b/server/d3dkmt.c index c09db82ddaf..92c553ea7e8 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -388,6 +388,30 @@ DECL_HANDLER(d3dkmt_object_create) release_object( object ); }
+/* update a global d3dkmt object */ +DECL_HANDLER(d3dkmt_object_update) +{ + struct d3dkmt_object *object; + void *tmp, *runtime; + data_size_t size; + + if (!(size = get_req_data_size())) runtime = NULL; + else if (!(runtime = memdup( get_req_data(), size ))) return; + + if (req->global) object = d3dkmt_object_open( req->global, req->type ); + else object = d3dkmt_object_open_shared( req->handle, req->type ); + if (!object) goto done; + + tmp = object->runtime; + object->runtime = runtime; + object->runtime_size = size; + runtime = tmp; + release_object( object ); + +done: + free( runtime ); +} + /* query a global d3dkmt object */ DECL_HANDLER(d3dkmt_object_query) { diff --git a/server/protocol.def b/server/protocol.def index 42095acb936..eed8cef390d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4182,6 +4182,15 @@ enum inproc_sync_type @END
+/* Update a global/shared d3dkmt object runtime data */ +@REQ(d3dkmt_object_update) + unsigned int type; /* d3dkmt object type */ + d3dkmt_handle_t global; /* global d3dkmt handle */ + obj_handle_t handle; /* shared object handle */ + VARARG(runtime,bytes); /* client runtime data */ +@END + + /* Query a global/shared d3dkmt object */ @REQ(d3dkmt_object_query) unsigned int type; /* d3dkmt object type */