From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 39 ++++++++++++++++++++++++++++++++++++-- dlls/win32u/tests/d3dkmt.c | 12 ++++++------ server/d3dkmt.c | 31 ++++++++++++++++++++++++++++++ server/protocol.def | 8 ++++++++ 4 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 38bfc5e31a3..db1135776ef 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -74,6 +74,11 @@ static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); / static struct d3dkmt_object **objects; static unsigned int object_count, object_capacity, last_index;
+static BOOL is_d3dkmt_global( D3DKMT_HANDLE handle ) +{ + return (handle & 0xc0000000) && (handle & 0x3f) == 2; +} + /* return the position of the first object which handle is not less than * the given local handle, d3dkmt_lock must be held. */ static unsigned int object_handle_lower_bound( D3DKMT_HANDLE local ) @@ -184,6 +189,22 @@ static NTSTATUS d3dkmt_object_create( struct d3dkmt_object *obj, BOOL shared, co return alloc_object_handle( obj ); }
+static NTSTATUS d3dkmt_object_query( enum d3dkmt_type type, D3DKMT_HANDLE global, UINT *runtime_size ) +{ + NTSTATUS status; + + SERVER_START_REQ( d3dkmt_object_query ) + { + req->type = type; + req->global = global; + status = wine_server_call( req ); + *runtime_size = reply->runtime_size; + } + SERVER_END_REQ; + + return status; +} + static void d3dkmt_object_free( struct d3dkmt_object *object ) { if (object->local) free_object_handle( object ); @@ -929,8 +950,22 @@ NTSTATUS WINAPI NtGdiDdDDIOpenNtHandleFromName( D3DKMT_OPENNTHANDLEFROMNAME *par */ NTSTATUS WINAPI NtGdiDdDDIQueryResourceInfo( D3DKMT_QUERYRESOURCEINFO *params ) { - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + struct d3dkmt_object *device; + NTSTATUS status; + + TRACE( "params %p\n", params ); + + if (!params) return STATUS_INVALID_PARAMETER; + 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 ))) + 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 45f56f29a0b..f79bbcccecf 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -1889,7 +1889,7 @@ static void test_D3DKMTCreateAllocation( void ) query.hDevice = create_device.hDevice; query.hGlobalShare = create.hResource; status = D3DKMTQueryResourceInfo( &query ); - todo_wine ok_nt( STATUS_INVALID_PARAMETER, status ); + ok_nt( STATUS_INVALID_PARAMETER, status );
/* D3DKMTOpenResource requires a global handle */ open.hDevice = create_device.hDevice; @@ -1920,12 +1920,12 @@ static void test_D3DKMTCreateAllocation( void ) query.PrivateRuntimeDataSize = sizeof(runtime_data); query.ResourcePrivateDriverDataSize = 0; status = D3DKMTQueryResourceInfo( &query ); - todo_wine ok_nt( STATUS_SUCCESS, status ); - todo_wine ok_x4( query.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_nt( STATUS_SUCCESS, status ); + ok_x4( query.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); todo_wine ok_x4( query.TotalPrivateDriverDataSize, >, 0 ); ok_x4( query.TotalPrivateDriverDataSize, <, sizeof(driver_data) ); ok_x4( query.ResourcePrivateDriverDataSize, ==, 0 ); - todo_wine ok_u4( query.NumAllocations, ==, 1 ); + ok_u4( query.NumAllocations, ==, 1 ); /* runtime data doesn't get updated ? */ ok_u1( runtime_data[0], ==, 0xcd );
@@ -1951,7 +1951,7 @@ static void test_D3DKMTCreateAllocation( void ) todo_wine ok_nt( STATUS_SUCCESS, status ); ok_x4( open.hGlobalShare, ==, create.hGlobalShare ); todo_wine check_d3dkmt_local( open.hResource, &next_local ); - todo_wine ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); ok_x4( open.ResourcePrivateDriverDataSize, ==, 0 ); @@ -1994,7 +1994,7 @@ static void test_D3DKMTCreateAllocation( void ) todo_wine ok_nt( STATUS_SUCCESS, status ); ok_x4( open.hGlobalShare, ==, create.hGlobalShare ); todo_wine check_d3dkmt_local( open.hResource, &next_local ); - todo_wine ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); + ok_x4( open.PrivateRuntimeDataSize, ==, sizeof(expect_runtime_data) ); ok_x4( open.TotalPrivateDriverDataBufferSize, >, 0 ); todo_wine ok_x4( open.TotalPrivateDriverDataBufferSize, <, sizeof(driver_data) ); ok_x4( open.ResourcePrivateDriverDataSize, ==, 0 ); diff --git a/server/d3dkmt.c b/server/d3dkmt.c index fb50ffb59c0..525a37e3e76 100644 --- a/server/d3dkmt.c +++ b/server/d3dkmt.c @@ -168,6 +168,24 @@ static struct d3dkmt_object *d3dkmt_object_create( enum d3dkmt_type type, mem_si return object; }
+/* return a pointer to a d3dkmt object from its global handle */ +static void *d3dkmt_object_open( d3dkmt_handle_t global, enum d3dkmt_type type ) +{ + struct d3dkmt_object *object; + unsigned int index; + + index = object_handle_lower_bound( global ); + if (index >= object_count) object = NULL; + else object = objects[index]; + + if (!object || object->global != global || object->type != type) + { + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + return grab_object( object ); +} + /* create a global d3dkmt object */ DECL_HANDLER(d3dkmt_object_create) { @@ -178,3 +196,16 @@ DECL_HANDLER(d3dkmt_object_create) reply->global = object->global; release_object( object ); } + +/* query a global d3dkmt object */ +DECL_HANDLER(d3dkmt_object_query) +{ + struct d3dkmt_object *object; + + if (!req->global) return; + object = d3dkmt_object_open( req->global, req->type ); + if (!object) return; + + reply->runtime_size = object->runtime_size; + release_object( object ); +} diff --git a/server/protocol.def b/server/protocol.def index 6d5980cc43f..d68513ef3a7 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -4160,3 +4160,11 @@ enum inproc_sync_type obj_handle_t handle; /* process-private handle */ @END
+ +/* Query a global d3dkmt object */ +@REQ(d3dkmt_object_query) + unsigned int type; /* d3dkmt object type */ + d3dkmt_handle_t global; /* global d3dkmt handle */ +@REPLY + mem_size_t runtime_size; /* size of client runtime data */ +@END