ohmu
·
2026-10-15
1extern "C" {
2#include "gpu.h"
3#include "common/library.h"
4#include "common/debug.h"
5}
6
7#if __has_include(<directx/dxcore.h>) && __has_include(<dxguids/dxguids.h>)
8
9 #include <directx/dxcore.h>
10 #include <dxguids/dxguids.h>
11 #include "common/windows/util.hpp"
12
13static IDXCoreAdapterFactory* loadDxCoreFactory() {
14 static bool initialized = false;
15 static IDXCoreAdapterFactory* factory = nullptr;
16 if (initialized) {
17 return factory; // Already loaded
18 }
19
20 initialized = true;
21 FF_LIBRARY_LOAD(dxcore, nullptr, "dxcore" FF_LIBRARY_EXTENSION, 1)
22
23 // DXCoreCreateAdapterFactory is a reloaded function, so we can't use FF_LIBRARY_LOAD_SYMBOL_MESSAGE here
24 typedef HRESULT (*DXCoreCreateAdapterFactory_t)(REFIID riid, void** ppvFactory);
25
26 #ifndef FF_DISABLE_DLOPEN
27 auto ffDXCoreCreateAdapterFactory = (DXCoreCreateAdapterFactory_t) dlsym(dxcore, "DXCoreCreateAdapterFactory");
28 if (ffDXCoreCreateAdapterFactory == nullptr) {
29 return nullptr;
30 }
31 #else
32 auto ffDXCoreCreateAdapterFactory = (DXCoreCreateAdapterFactory_t) DXCoreCreateAdapterFactory;
33 #endif
34
35 HRESULT hr = ffDXCoreCreateAdapterFactory(IID_PPV_ARGS(&factory));
36 if (FAILED(hr)) {
37 FF_DEBUG("DXCoreCreateAdapterFactory failed with HRESULT: 0x%08lX (%s)", hr, ffDebugHResult(hr));
38 return nullptr;
39 }
40
41 dxcore = nullptr; // Don't unload
42 return factory;
43}
44
45extern "C" const char* ffGPUDetectTypeWithDXCore(LUID adapterLuid, FFGPUResult* gpu) {
46 auto* factory = loadDxCoreFactory();
47 if (!factory) {
48 return "Failed to load DXCore library or create adapter factory";
49 }
50
51 IDXCoreAdapter* adapter = nullptr;
52 HRESULT hr = factory->GetAdapterByLuid(adapterLuid, IID_PPV_ARGS(&adapter));
53 if (FAILED(hr)) {
54 FF_DEBUG("GetAdapterByLuid failed with HRESULT: 0x%08lX (%s)", hr, ffDebugHResult(hr));
55 return "Failed to get adapter by LUID";
56 }
57
58 on_scope_exit releaseAdapter{ [adapter] { adapter->Release(); } };
59
60 bool isIntegrated = false;
61 hr = adapter->GetProperty(DXCoreAdapterProperty::IsIntegrated, sizeof(isIntegrated), &isIntegrated);
62 if (FAILED(hr)) {
63 FF_DEBUG("GetProperty(IsIntegrated) failed with HRESULT: 0x%08lX (%s)", hr, ffDebugHResult(hr));
64 return "Failed to get adapter properties";
65 }
66
67 gpu->type = isIntegrated ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
68 FF_DEBUG("GPU type determined using DXCore: %s", isIntegrated ? "Integrated" : "Discrete");
69
70 return nullptr;
71}
72
73#else
74
75 #warning "DXCore headers not available, GPU type detection may be less accurate"
76
77extern "C" const char* ffGPUDetectTypeWithDXCore(LUID adapterLuid, FFGPUResult* gpu) {
78 FF_UNUSED(adapterLuid, gpu);
79 FF_DEBUG("DXCore not available, skipping GPU type detection with DXCore");
80 return "DXCore not available";
81}
82
83#endif