Commit 4573910a authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

win32u: Move D3DKMT vulkan implementation out of winex11.

parent dc9229e6
......@@ -59,6 +59,70 @@ static struct list d3dkmt_adapters = LIST_INIT( d3dkmt_adapters );
static struct list d3dkmt_devices = LIST_INIT( d3dkmt_devices );
static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /* VidPN source information list */
static VkInstance d3dkmt_vk_instance; /* Vulkan instance for D3DKMT functions */
static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR;
static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR;
static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices;
static const struct vulkan_funcs *vulkan_funcs;
static void d3dkmt_init_vulkan(void)
{
static const char *extensions[] =
{
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
};
VkInstanceCreateInfo create_info =
{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.enabledExtensionCount = ARRAY_SIZE( extensions ),
.ppEnabledExtensionNames = extensions,
};
VkResult vr;
if (!(vulkan_funcs = __wine_get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION )))
{
WARN( "Failed to open the Vulkan driver\n" );
return;
}
if ((vr = vulkan_funcs->p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance )))
{
WARN( "Failed to create a Vulkan instance, vr %d.\n", vr );
vulkan_funcs = NULL;
return;
}
#define LOAD_VK_FUNC( f ) \
if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( d3dkmt_vk_instance, #f ))) \
{ \
WARN( "Failed to load " #f ".\n" ); \
vulkan_funcs->p_vkDestroyInstance( d3dkmt_vk_instance, NULL ); \
vulkan_funcs = NULL; \
return; \
}
LOAD_VK_FUNC( vkEnumeratePhysicalDevices )
LOAD_VK_FUNC( vkGetPhysicalDeviceProperties2KHR )
LOAD_VK_FUNC( vkGetPhysicalDeviceMemoryProperties2KHR )
#undef LOAD_VK_FUNC
}
static BOOL d3dkmt_use_vulkan(void)
{
static pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once( &once, d3dkmt_init_vulkan );
return !!vulkan_funcs;
}
/* d3dkmt_lock must be held */
static struct d3dkmt_adapter *find_adapter_from_handle( D3DKMT_HANDLE handle )
{
struct d3dkmt_adapter *adapter;
LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry )
if (adapter->handle == handle) return adapter;
return NULL;
}
/******************************************************************************
* NtGdiDdDDIOpenAdapterFromHdc (win32u.@)
*/
......@@ -89,22 +153,15 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
if (!desc || !desc->hAdapter) return STATUS_INVALID_PARAMETER;
if (get_display_driver()->pD3DKMTCloseAdapter)
get_display_driver()->pD3DKMTCloseAdapter( desc );
pthread_mutex_lock( &d3dkmt_lock );
LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry )
if ((adapter = find_adapter_from_handle( desc->hAdapter )))
{
if (adapter->handle == desc->hAdapter)
{
list_remove( &adapter->entry );
free( adapter );
status = STATUS_SUCCESS;
break;
}
list_remove( &adapter->entry );
status = STATUS_SUCCESS;
}
pthread_mutex_unlock( &d3dkmt_lock );
free( adapter );
return status;
}
......@@ -128,6 +185,45 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC
return STATUS_SUCCESS;
}
static VkPhysicalDevice get_vulkan_physical_device( const GUID *uuid )
{
VkPhysicalDevice *devices, device;
UINT device_count, i;
VkResult vr;
if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, NULL )))
{
WARN( "vkEnumeratePhysicalDevices returned %d\n", vr );
return VK_NULL_HANDLE;
}
if (!device_count || !(devices = malloc( device_count * sizeof(*devices) )))
return VK_NULL_HANDLE;
if ((vr = pvkEnumeratePhysicalDevices( d3dkmt_vk_instance, &device_count, devices )))
{
WARN( "vkEnumeratePhysicalDevices returned %d\n", vr );
free( devices );
return VK_NULL_HANDLE;
}
for (i = 0, device = VK_NULL_HANDLE; i < device_count; ++i)
{
VkPhysicalDeviceIDProperties id = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES};
VkPhysicalDeviceProperties2 properties2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &id};
pvkGetPhysicalDeviceProperties2KHR( devices[i], &properties2 );
if (IsEqualGUID( uuid, id.deviceUUID ))
{
device = devices[i];
break;
}
}
free( devices );
return device;
}
/******************************************************************************
* NtGdiDdDDIOpenAdapterFromLuid (win32u.@)
*/
......@@ -135,17 +231,23 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc
{
static D3DKMT_HANDLE handle_start = 0;
struct d3dkmt_adapter *adapter;
GUID uuid = {0};
if (!(adapter = malloc( sizeof(*adapter) ))) return STATUS_NO_MEMORY;
if (!(adapter = calloc( 1, sizeof(*adapter) ))) return STATUS_NO_MEMORY;
if (!d3dkmt_use_vulkan())
WARN( "Vulkan is unavailable.\n" );
else if (!get_vulkan_uuid_from_luid( &desc->AdapterLuid, &uuid ))
WARN( "Failed to find Vulkan device with LUID %08x:%08x.\n",
(int)desc->AdapterLuid.HighPart, (int)desc->AdapterLuid.LowPart );
else if (!(adapter->vk_device = get_vulkan_physical_device( &uuid )))
WARN( "Failed to find vulkan device with GUID %s\n", debugstr_guid( &uuid ) );
pthread_mutex_lock( &d3dkmt_lock );
desc->hAdapter = adapter->handle = ++handle_start;
list_add_tail( &d3dkmt_adapters, &adapter->entry );
pthread_mutex_unlock( &d3dkmt_lock );
if (get_display_driver()->pD3DKMTOpenAdapterFromLuid)
get_display_driver()->pD3DKMTOpenAdapterFromLuid( desc );
return STATUS_SUCCESS;
}
......@@ -155,7 +257,6 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc
NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc )
{
static D3DKMT_HANDLE handle_start = 0;
struct d3dkmt_adapter *adapter;
struct d3dkmt_device *device;
BOOL found = FALSE;
......@@ -164,14 +265,7 @@ NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc )
if (!desc) return STATUS_INVALID_PARAMETER;
pthread_mutex_lock( &d3dkmt_lock );
LIST_FOR_EACH_ENTRY( adapter, &d3dkmt_adapters, struct d3dkmt_adapter, entry )
{
if (adapter->handle == desc->hAdapter)
{
found = TRUE;
break;
}
}
found = !!find_adapter_from_handle( desc->hAdapter );
pthread_mutex_unlock( &d3dkmt_lock );
if (!found) return STATUS_INVALID_PARAMETER;
......@@ -248,8 +342,12 @@ NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats )
*/
NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
{
VkPhysicalDeviceMemoryBudgetPropertiesEXT budget;
VkPhysicalDeviceMemoryProperties2 properties2;
struct d3dkmt_adapter *adapter;
OBJECT_BASIC_INFORMATION info;
NTSTATUS status;
unsigned int i;
TRACE( "(%p)\n", desc );
......@@ -266,8 +364,35 @@ NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *des
if (status != STATUS_SUCCESS) return status;
if (!(info.GrantedAccess & PROCESS_QUERY_INFORMATION)) return STATUS_ACCESS_DENIED;
if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo) return STATUS_PROCEDURE_NOT_FOUND;
return get_display_driver()->pD3DKMTQueryVideoMemoryInfo( desc );
desc->Budget = 0;
desc->CurrentUsage = 0;
desc->CurrentReservation = 0;
desc->AvailableForReservation = 0;
pthread_mutex_lock( &d3dkmt_lock );
if ((adapter = find_adapter_from_handle( desc->hAdapter )) && adapter->vk_device)
{
memset( &budget, 0, sizeof(budget) );
budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
properties2.pNext = &budget;
pvkGetPhysicalDeviceMemoryProperties2KHR( adapter->vk_device, &properties2 );
for (i = 0; i < properties2.memoryProperties.memoryHeapCount; ++i)
{
if ((desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL &&
properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ||
(desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL &&
!(properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)))
{
desc->Budget += budget.heapBudget[i];
desc->CurrentUsage += budget.heapUsage[i];
}
}
desc->AvailableForReservation = desc->Budget / 2;
}
pthread_mutex_unlock( &d3dkmt_lock );
return adapter ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER;
}
/******************************************************************************
......
......@@ -707,9 +707,6 @@ const struct gdi_dc_funcs dib_driver =
dibdrv_StrokeAndFillPath, /* pStrokeAndFillPath */
dibdrv_StrokePath, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCloseAdapter */
NULL, /* pD3DKMTOpenAdapterFromLuid */
NULL, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_DIB_DRV /* priority */
};
......@@ -1266,8 +1263,5 @@ static const struct gdi_dc_funcs window_driver =
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCloseAdapter */
NULL, /* pD3DKMTOpenAdapterFromLuid */
NULL, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_DIB_DRV + 10 /* priority */
};
......@@ -522,21 +522,6 @@ static BOOL nulldrv_UnrealizePalette( HPALETTE palette )
return FALSE;
}
static NTSTATUS nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
{
return STATUS_PROCEDURE_NOT_FOUND;
}
static NTSTATUS nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc )
{
return STATUS_PROCEDURE_NOT_FOUND;
}
static NTSTATUS nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
{
return STATUS_PROCEDURE_NOT_FOUND;
}
const struct gdi_dc_funcs null_driver =
{
nulldrv_AbortDoc, /* pAbortDoc */
......@@ -628,9 +613,6 @@ const struct gdi_dc_funcs null_driver =
nulldrv_StrokeAndFillPath, /* pStrokeAndFillPath */
nulldrv_StrokePath, /* pStrokePath */
nulldrv_UnrealizePalette, /* pUnrealizePalette */
nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */
nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */
nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_NULL_DRV /* priority */
};
......
......@@ -519,9 +519,6 @@ static const struct gdi_dc_funcs emfdrv_driver =
EMFDRV_StrokeAndFillPath, /* pStrokeAndFillPath */
EMFDRV_StrokePath, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCloseAdapter */
NULL, /* pD3DKMTOpenAdapterFromLuid */
NULL, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_GRAPHICS_DRV /* priority */
};
......
......@@ -4785,9 +4785,6 @@ const struct gdi_dc_funcs font_driver =
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCloseAdapter */
NULL, /* pD3DKMTOpenAdapterFromLuid */
NULL, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_FONT_DRV /* priority */
};
......
......@@ -2118,8 +2118,5 @@ const struct gdi_dc_funcs path_driver =
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCloseAdapter */
NULL, /* pD3DKMTOpenAdapterFromLuid */
NULL, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_PATH_DRV /* priority */
};
......@@ -6681,3 +6681,24 @@ done:
while (count) gpu_release( current_gpus[--count] );
return status;
}
/* Find the Vulkan device UUID corresponding to a LUID */
BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid )
{
BOOL found = FALSE;
struct gpu *gpu;
if (!lock_display_devices()) return FALSE;
LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry )
{
if ((found = !memcmp( &gpu->luid, luid, sizeof(*luid) )))
{
*uuid = gpu->vulkan_uuid;
break;
}
}
unlock_display_devices();
return found;
}
......@@ -191,6 +191,7 @@ extern BOOL update_display_cache( BOOL force );
extern void user_lock(void);
extern void user_unlock(void);
extern void user_check_not_lock(void);
extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid );
/* winstation.c */
extern BOOL is_virtual_desktop(void);
......
......@@ -376,9 +376,6 @@ static const struct user_driver_funcs x11drv_funcs =
.dc_funcs.pStrokeAndFillPath = X11DRV_StrokeAndFillPath,
.dc_funcs.pStrokePath = X11DRV_StrokePath,
.dc_funcs.pUnrealizePalette = X11DRV_UnrealizePalette,
.dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter,
.dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid,
.dc_funcs.pD3DKMTQueryVideoMemoryInfo = X11DRV_D3DKMTQueryVideoMemoryInfo,
.dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV,
.pActivateKeyboardLayout = X11DRV_ActivateKeyboardLayout,
......
......@@ -158,9 +158,6 @@ extern BOOL X11DRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend );
extern BOOL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend );
extern NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc );
extern NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc );
extern NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc );
extern BOOL X11DRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom );
extern BOOL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType );
extern BOOL X11DRV_FillPath( PHYSDEV dev );
......
......@@ -2234,9 +2234,6 @@ static const struct gdi_dc_funcs xrender_funcs =
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCloseAdapter */
NULL, /* pD3DKMTOpenAdapterFromLuid */
NULL, /* pD3DKMTQueryVideoMemoryInfo */
GDI_PRIORITY_GRAPHICS_DRV + 10 /* priority */
};
......
......@@ -166,9 +166,6 @@ struct gdi_dc_funcs
BOOL (*pStrokeAndFillPath)(PHYSDEV);
BOOL (*pStrokePath)(PHYSDEV);
BOOL (*pUnrealizePalette)(HPALETTE);
NTSTATUS (*pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *);
NTSTATUS (*pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *);
NTSTATUS (*pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *);
/* priority order for the driver on the stack */
UINT priority;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment