diff --git a/libraries/platform/src/platform/PlatformKeys.h b/libraries/platform/src/platform/PlatformKeys.h index e6c255ce75..bb71e88f94 100644 --- a/libraries/platform/src/platform/PlatformKeys.h +++ b/libraries/platform/src/platform/PlatformKeys.h @@ -30,6 +30,7 @@ namespace platform { namespace keys{ extern const char* model; extern const char* videoMemory; extern const char* driver; + extern const char* displays; } namespace nic { extern const char* mac; @@ -42,6 +43,7 @@ namespace platform { namespace keys{ extern const char* coordsRight; extern const char* coordsTop; extern const char* coordsBottom; + extern const char* gpu; } namespace memory { extern const char* memTotal; diff --git a/libraries/platform/src/platform/backend/Platform.cpp b/libraries/platform/src/platform/backend/Platform.cpp index 9284e0b3a0..a8c0f1b111 100644 --- a/libraries/platform/src/platform/backend/Platform.cpp +++ b/libraries/platform/src/platform/backend/Platform.cpp @@ -31,6 +31,7 @@ namespace platform { namespace keys { const char* model = "model"; const char* videoMemory = "videoMemory"; const char* driver = "driver"; + const char* displays = "displays"; } namespace nic { const char* mac = "mac"; @@ -43,6 +44,7 @@ namespace platform { namespace keys { const char* coordsRight = "coordinatesright"; const char* coordsTop = "coordinatestop"; const char* coordsBottom = "coordinatesbottom"; + const char* gpu = "gpu"; } namespace memory { const char* memTotal = "memTotal"; diff --git a/libraries/platform/src/platform/backend/PlatformInstance.cpp b/libraries/platform/src/platform/backend/PlatformInstance.cpp index 33b19cd012..69825cbfa5 100644 --- a/libraries/platform/src/platform/backend/PlatformInstance.cpp +++ b/libraries/platform/src/platform/backend/PlatformInstance.cpp @@ -98,6 +98,7 @@ json Instance::listAllKeys() { keys::gpu::model, keys::gpu::videoMemory, keys::gpu::driver, + keys::gpu::displays, keys::display::description, keys::display::name, @@ -105,6 +106,7 @@ json Instance::listAllKeys() { keys::display::coordsRight, keys::display::coordsTop, keys::display::coordsBottom, + keys::display::gpu, keys::memory::memTotal, diff --git a/libraries/platform/src/platform/backend/WINPlatform.cpp b/libraries/platform/src/platform/backend/WINPlatform.cpp index d07bb83510..0c09ae2de6 100644 --- a/libraries/platform/src/platform/backend/WINPlatform.cpp +++ b/libraries/platform/src/platform/backend/WINPlatform.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#pragma comment(lib, "dxgi.lib") #endif using namespace platform; @@ -34,6 +36,106 @@ void WINInstance::enumerateCpus() { } void WINInstance::enumerateGpus() { +#ifdef Q_OS_WIN + struct ConvertLargeIntegerToQString { + QString convert(const LARGE_INTEGER& version) { + QString value; + value.append(QString::number(uint32_t(((version.HighPart & 0xFFFF0000) >> 16) & 0x0000FFFF))); + value.append("."); + value.append(QString::number(uint32_t((version.HighPart) & 0x0000FFFF))); + value.append("."); + value.append(QString::number(uint32_t(((version.LowPart & 0xFFFF0000) >> 16) & 0x0000FFFF))); + value.append("."); + value.append(QString::number(uint32_t((version.LowPart) & 0x0000FFFF))); + return value; + } + } convertDriverVersionToString; + + // Create the DXGI factory + // Let s get into DXGI land: + HRESULT hr = S_OK; + + IDXGIFactory1* pFactory = nullptr; + hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory)); + if (hr != S_OK || pFactory == nullptr) { +// qCDebug(shared) << "Unable to create DXGI"; + return; + } + + std::vector validAdapterList; + using AdapterEntry = std::pair, std::vector>; + std::vector adapterToOutputs; + // Enumerate adapters and outputs + { + UINT adapterNum = 0; + IDXGIAdapter1* pAdapter = nullptr; + while (pFactory->EnumAdapters1(adapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND) { + // Found an adapter, get descriptor + DXGI_ADAPTER_DESC1 adapterDesc; + pAdapter->GetDesc1(&adapterDesc); + + LARGE_INTEGER version; + hr = pAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version); + + std::wstring wDescription(adapterDesc.Description); + std::string description(wDescription.begin(), wDescription.end()); + + json gpu = {}; + gpu[keys::gpu::model] = description; + gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get()); + const SIZE_T BYTES_PER_MEGABYTE = 1024 * 1024; + gpu[keys::gpu::videoMemory] = (uint32_t)(adapterDesc.DedicatedVideoMemory / BYTES_PER_MEGABYTE); + gpu[keys::gpu::driver] = convertDriverVersionToString.convert(version).toStdString(); + + + std::vector displayIndices; + + UINT outputNum = 0; + IDXGIOutput* pOutput; + bool hasOutputConnectedToDesktop = false; + while (pAdapter->EnumOutputs(outputNum, &pOutput) != DXGI_ERROR_NOT_FOUND) { + // FOund an output attached to the adapter, get descriptor + DXGI_OUTPUT_DESC outputDesc; + pOutput->GetDesc(&outputDesc); + + // Grab the Monitor desc + // MONITOR_DESC + + json display = {}; + + // Desiplay name + std::wstring wDeviceName(outputDesc.DeviceName); + std::string deviceName(wDeviceName.begin(), wDeviceName.end()); + display[keys::display::name] = deviceName; + display[keys::display::description] = ""; + + // Rect region of the desktop in desktop units + display["desktopRect"] = (outputDesc.AttachedToDesktop ? true : false); + display[keys::display::coordsLeft] = outputDesc.DesktopCoordinates.left; + display[keys::display::coordsRight] = outputDesc.DesktopCoordinates.right; + display[keys::display::coordsBottom] = outputDesc.DesktopCoordinates.bottom; + display[keys::display::coordsTop] = outputDesc.DesktopCoordinates.top; + + // Add the display index to the list of displays of the gpu + displayIndices.push_back(_displays.size()); + + // And set the gpu index to the display description + display[keys::display::gpu] = _gpus.size(); + + // One more display desc + _displays.push_back(display); + pOutput->Release(); + outputNum++; + } + gpu[keys::gpu::displays] = displayIndices; + + _gpus.push_back(gpu); + pAdapter->Release(); + adapterNum++; + } + } + pFactory->Release(); +#endif GPUIdent* ident = GPUIdent::getInstance(); @@ -44,7 +146,7 @@ void WINInstance::enumerateGpus() { gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData(); _gpus.push_back(gpu); - _displays = ident->getOutput(); + // _displays = ident->getOutput(); } void WINInstance::enumerateMemory() {