From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 25 +++++++++++++++++++------ dlls/win32u/tests/d3dkmt.c | 22 +++++++++++----------- server/d3dkmt.c | 34 ++++++++++++++++++++++++++++++++-- server/protocol.def | 3 ++- 4 files changed, 64 insertions(+), 20 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 2deefd7aada..3536d8732e1 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -226,7 +226,8 @@ static NTSTATUS d3dkmt_object_open( struct d3dkmt_object *obj, D3DKMT_HANDLE glo return status; }
-static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global, UINT *runtime_size ) +static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global, HANDLE handle, + UINT *runtime_size ) { NTSTATUS status;
@@ -234,13 +235,14 @@ static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global { req->type = type; req->global = global; + req->handle = wine_server_obj_handle( handle ); status = wine_server_call( req ); *runtime_size = reply->runtime_size; } SERVER_END_REQ;
- if (status) WARN( "Failed to query global object %#x, status %#x\n", global, status ); - else TRACE( "Found global object %#x with runtime size %#x\n", global, *runtime_size ); + if (status) WARN( "Failed to query global object %#x/%p, status %#x\n", global, handle, status ); + else TRACE( "Found global object %#x/%p with runtime size %#x\n", global, handle, *runtime_size ); return status; }
@@ -1211,7 +1213,8 @@ NTSTATUS WINAPI NtGdiDdDDIQueryResourceInfo( D3DKMT_QUERYRESOURCEINFO *params ) if (!(device = get_d3dkmt_object( params->hDevice, D3DKMT_DEVICE ))) return STATUS_INVALID_PARAMETER; if (!is_d3dkmt_global( params->hGlobalShare )) return STATUS_INVALID_PARAMETER;
- if ((status = d3dkmt_object_query( D3DKMT_RESOURCE, params->hGlobalShare, ¶ms->PrivateRuntimeDataSize ))) + if ((status = d3dkmt_object_query( D3DKMT_RESOURCE, params->hGlobalShare, NULL, + ¶ms->PrivateRuntimeDataSize ))) return status;
params->TotalPrivateDriverDataSize = 0; @@ -1225,8 +1228,18 @@ NTSTATUS WINAPI NtGdiDdDDIQueryResourceInfo( D3DKMT_QUERYRESOURCEINFO *params ) */ NTSTATUS WINAPI NtGdiDdDDIQueryResourceInfoFromNtHandle( D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if ((status = d3dkmt_object_query( D3DKMT_RESOURCE, 0, params->hNtHandle, + ¶ms->PrivateRuntimeDataSize ))) + return status; + + params->TotalPrivateDriverDataSize = 0; + params->ResourcePrivateDriverDataSize = 0; + params->NumAllocations = 1; + return STATUS_SUCCESS; }
diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index baa4b95355f..ececd663449 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -2590,19 +2590,19 @@ static void test_D3DKMTShareObjects( void ) query_resource.ResourcePrivateDriverDataSize = 0xdeadbeef; query_resource.NumAllocations = 0xdeadbeef; status = D3DKMTQueryResourceInfoFromNtHandle( &query_resource ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); - ok_x4( query_resource.TotalPrivateDriverDataSize, >, 0 ); - todo_wine ok_x4( query_resource.TotalPrivateDriverDataSize, <, sizeof(driver_data) ); - todo_wine ok_x4( query_resource.ResourcePrivateDriverDataSize, ==, 0 ); - todo_wine ok_u4( query_resource.NumAllocations, ==, 1 ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + todo_wine ok_x4( query_resource.TotalPrivateDriverDataSize, >, 0 ); + ok_x4( query_resource.TotalPrivateDriverDataSize, <, sizeof(driver_data) ); + ok_x4( query_resource.ResourcePrivateDriverDataSize, ==, 0 ); + ok_u4( query_resource.NumAllocations, ==, 1 );
memset( runtime_data, 0xcd, sizeof(runtime_data) ); query_resource.pPrivateRuntimeData = runtime_data; query_resource.PrivateRuntimeDataSize = sizeof(runtime_data); status = D3DKMTQueryResourceInfoFromNtHandle( &query_resource ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( query_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_u1( runtime_data[0], ==, 0xcd );
memset( runtime_data, 0xcd, sizeof(runtime_data) ); @@ -2623,10 +2623,10 @@ static void test_D3DKMTShareObjects( void ) status = D3DKMTOpenResourceFromNtHandle( &open_resource ); todo_wine ok_nt( STATUS_SUCCESS, status ); ok_u4( open_resource.NumAllocations, ==, 1 ); - todo_wine ok_x4( open_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_x4( open_resource.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_x4( open_resource.ResourcePrivateDriverDataSize, ==, 0 ); - ok_x4( open_resource.TotalPrivateDriverDataBufferSize, >, 0 ); - todo_wine ok_x4( open_resource.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); + todo_wine ok_x4( open_resource.TotalPrivateDriverDataBufferSize, >, 0 ); + ok_x4( open_resource.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); todo_wine check_d3dkmt_local( open_resource.hResource, NULL ); todo_wine check_d3dkmt_local( open_resource.hKeyedMutex, NULL ); ok_x4( open_resource.KeyedMutexPrivateRuntimeDataSize, ==, sizeof(expect_mutex_data) ); diff --git a/server/d3dkmt.c b/server/d3dkmt.c index 0939cdecbb3..ce81521a2ff 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -347,6 +347,36 @@ static void *d3dkmt_object_open( d3dkmt_handle_t global, enum d3dkmt_type type ) return grab_object( object ); }
+static struct d3dkmt_object *d3dkmt_object_open_shared( obj_handle_t handle, enum d3dkmt_type type ) +{ + struct object *obj, *ret = NULL; + + if ((obj = get_handle_obj( current->process, handle, 0, &dxgk_shared_resource_ops ))) + { + struct dxgk_shared_resource *shared = (struct dxgk_shared_resource *)obj; + if (type == D3DKMT_RESOURCE) ret = grab_object( shared->resource ); + else if (type == D3DKMT_MUTEX && shared->mutex) ret = grab_object( shared->mutex ); + else if (type == D3DKMT_SYNC && shared->sync) ret = grab_object( shared->sync ); + release_object( obj ); + if (!ret) set_error( STATUS_INVALID_PARAMETER ); + return (struct d3dkmt_object *)ret; + } + + if (type != D3DKMT_SYNC) return NULL; + + /* try again looking for a shared sync if client asked for a sync object */ + set_error( STATUS_SUCCESS ); + + if ((obj = get_handle_obj( current->process, handle, 0, &dxgk_shared_sync_ops ))) + { + struct dxgk_shared_sync *shared = (struct dxgk_shared_sync *)obj; + ret = grab_object( shared->sync ); + release_object( obj ); + } + + return (struct d3dkmt_object *)ret; +} + /* create a global d3dkmt object */ DECL_HANDLER(d3dkmt_object_create) { @@ -363,8 +393,8 @@ DECL_HANDLER(d3dkmt_object_query) { struct d3dkmt_object *object;
- if (!req->global) return; - object = d3dkmt_object_open( req->global, req->type ); + if (req->global) object = d3dkmt_object_open( req->global, req->type ); + else object = d3dkmt_object_open_shared( req->handle, req->type ); if (!object) return;
reply->runtime_size = object->runtime_size; diff --git a/server/protocol.def b/server/protocol.def index 2e9c4d6ea27..036e35cdf68 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4163,10 +4163,11 @@ enum inproc_sync_type @END
-/* Query a global d3dkmt object */ +/* Query a global/shared d3dkmt object */ @REQ(d3dkmt_object_query) unsigned int type; /* d3dkmt object type */ d3dkmt_handle_t global; /* global d3dkmt handle */ + obj_handle_t handle; /* shared object handle */ @REPLY data_size_t runtime_size; /* size of client runtime data */ @END