Skip to content

Commit 48abe2c

Browse files
committed
CW HACK 23560 - Diablo IV (Steam)
1 parent af22b10 commit 48abe2c

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

dlls/setupapi/devinst.c

+90
Original file line numberDiff line numberDiff line change
@@ -4396,6 +4396,87 @@ static LSTATUS get_device_property(struct device *device, const DEVPROPKEY *prop
43964396
return ls;
43974397
}
43984398

4399+
/* CW HACK 23560: Diablo IV needs GPU LUIDs to match between setupapi and (D3DMetal's) dxgi */
4400+
#ifdef __x86_64__
4401+
#define COBJMACROS
4402+
#include <dxgi.h>
4403+
4404+
static const DEVPROPKEY DEVPROPKEY_GPU_LUID =
4405+
{ { 0x60b193cb, 0x5276, 0x4d0f, { 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6 } }, 2 };
4406+
4407+
static const GUID my_IDXGIFactory =
4408+
{ 0x7b7166ec, 0x21c7, 0x44ae, { 0xb2,0x1a, 0xc9,0xae,0x32,0x1a,0xe3,0x69 } };
4409+
4410+
static BOOL CALLBACK check_is_diablo_iv(INIT_ONCE *once, void *param, void **context)
4411+
{
4412+
BOOL *is_d4 = param;
4413+
WCHAR name[MAX_PATH], *module_exe;
4414+
if (GetModuleFileNameW(NULL, name, ARRAYSIZE(name)))
4415+
{
4416+
module_exe = wcsrchr(name, '\\');
4417+
module_exe = module_exe ? module_exe + 1 : name;
4418+
*is_d4 = !wcsicmp(module_exe, L"Diablo IV.exe");
4419+
}
4420+
4421+
return TRUE;
4422+
}
4423+
4424+
static BOOL is_diablo_iv(void)
4425+
{
4426+
static BOOL is_d4 = FALSE;
4427+
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
4428+
InitOnceExecuteOnce(&once, check_is_diablo_iv, &is_d4, NULL);
4429+
return is_d4;
4430+
}
4431+
4432+
static BOOL using_d3dmetal(void)
4433+
{
4434+
/* D3DMetal's dxgi.dll doesn't include a version resource (or any resources) */
4435+
return (GetFileVersionInfoSizeW(L"dxgi.dll", NULL) > 0) ? FALSE : TRUE;
4436+
}
4437+
4438+
static void get_luid_from_d3dmetal(LUID *luid)
4439+
{
4440+
/* Diablo IV retrieves the GPU LUID through setupapi and expects it to match the LUID reported by
4441+
* D3DMetal.
4442+
*
4443+
* For now, load D3DMetal's dxgi and get its LUID.
4444+
*
4445+
* This assumes there's only one GPU (which is currently always true on Apple Silicon Macs).
4446+
*/
4447+
static HMODULE dxgi;
4448+
typeof(CreateDXGIFactory) *dxgi_CreateDXGIFactory;
4449+
IDXGIFactory *factory = NULL;
4450+
IDXGIAdapter *adapter = NULL;
4451+
DXGI_ADAPTER_DESC desc;
4452+
4453+
if (!dxgi)
4454+
{
4455+
dxgi = LoadLibraryW(L"dxgi.dll");
4456+
if (!dxgi) return;
4457+
}
4458+
4459+
dxgi_CreateDXGIFactory = (void *)GetProcAddress(dxgi, "CreateDXGIFactory");
4460+
if (!dxgi_CreateDXGIFactory) goto done;
4461+
4462+
dxgi_CreateDXGIFactory(&my_IDXGIFactory, (void **)&factory);
4463+
if (!factory) goto done;
4464+
4465+
IDXGIFactory_EnumAdapters(factory, 0, &adapter);
4466+
if (!adapter) goto done;
4467+
4468+
if (IDXGIAdapter_GetDesc(adapter, &desc) != S_OK)
4469+
goto done;
4470+
4471+
TRACE("Using LUID %08lx:%08lx from D3DMetal dxgi\n", desc.AdapterLuid.HighPart, desc.AdapterLuid.LowPart);
4472+
memcpy(luid, &desc.AdapterLuid, sizeof(*luid));
4473+
4474+
done:
4475+
if (adapter) IDXGIAdapter_Release(adapter);
4476+
if (factory) IDXGIFactory_Release(factory);
4477+
}
4478+
#endif
4479+
43994480
/***********************************************************************
44004481
* SetupDiGetDevicePropertyW (SETUPAPI.@)
44014482
*/
@@ -4414,6 +4495,15 @@ BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_
44144495

44154496
ls = get_device_property(device, prop_key, prop_type, prop_buff, prop_buff_size, required_size, flags);
44164497

4498+
#ifdef __x86_64__
4499+
/* CW HACK 23560 */
4500+
if (ls == NO_ERROR && prop_buff && prop_buff_size == sizeof(LUID) &&
4501+
IsEqualDevPropKey(*prop_key, DEVPROPKEY_GPU_LUID) && is_diablo_iv() && using_d3dmetal())
4502+
{
4503+
get_luid_from_d3dmetal((LUID *)prop_buff);
4504+
}
4505+
#endif
4506+
44174507
SetLastError(ls);
44184508
return !ls;
44194509
}

0 commit comments

Comments
 (0)