[idd] implemented core shared memory functionallity and LGMP setup

This commit is contained in:
Geoffrey McRae 2023-04-10 14:02:47 +10:00
parent 77ddcfe489
commit 3c85957b99
15 changed files with 608 additions and 37 deletions

View File

@ -38,6 +38,13 @@
#define LGMP_Q_FRAME_LEN 2 #define LGMP_Q_FRAME_LEN 2
#define LGMP_Q_POINTER_LEN 20 #define LGMP_Q_POINTER_LEN 20
#ifdef _MSC_VER
// don't warn on zero length arrays
#pragma warning(push)
#pragma warning(disable: 4200)
#endif
enum enum
{ {
CURSOR_FLAG_POSITION = 0x1, CURSOR_FLAG_POSITION = 0x1,
@ -165,4 +172,8 @@ typedef struct KVMFRSetCursorPos
} }
KVMFRSetCursorPos; KVMFRSetCursorPos;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif #endif

View File

@ -5,6 +5,7 @@
#include <algorithm> #include <algorithm>
#include <winioctl.h> #include <winioctl.h>
#include "Debug.h"
#include "ivshmem/ivshmem.h" #include "ivshmem/ivshmem.h"
CIVSHMEM::CIVSHMEM() CIVSHMEM::CIVSHMEM()
@ -81,7 +82,7 @@ bool CIVSHMEM::Init()
{ {
DWORD bus = it->busAddr >> 32; DWORD bus = it->busAddr >> 32;
DWORD addr = it->busAddr & 0xFFFFFFFF; DWORD addr = it->busAddr & 0xFFFFFFFF;
printf("IVSHMEM %u%c on bus 0x%lx, device 0x%lx, function 0x%lx\n", DBGPRINT("IVSHMEM %u%c on bus 0x%lx, device 0x%lx, function 0x%lx\n",
i, i == shmDevice ? '*' : ' ', bus, addr >> 16, addr & 0xFFFF); i, i == shmDevice ? '*' : ' ', bus, addr >> 16, addr & 0xFFFF);
if (i == shmDevice) if (i == shmDevice)
@ -132,7 +133,7 @@ bool CIVSHMEM::Open()
IVSHMEM_SIZE size; IVSHMEM_SIZE size;
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, nullptr, 0, &size, sizeof(size), nullptr, nullptr)) if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, nullptr, 0, &size, sizeof(size), nullptr, nullptr))
{ {
printf("Failed to request ivshmem size\n"); DBGPRINT("Failed to request ivshmem size");
return false; return false;
} }
@ -142,7 +143,7 @@ bool CIVSHMEM::Open()
config.cacheMode = IVSHMEM_CACHE_WRITECOMBINED; config.cacheMode = IVSHMEM_CACHE_WRITECOMBINED;
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_MMAP, &config, sizeof(config), &map, sizeof(map), nullptr, nullptr)) if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_MMAP, &config, sizeof(config), &map, sizeof(map), nullptr, nullptr))
{ {
printf("Failed to request ivshmem mmap\n"); DBGPRINT("Failed to request ivshmem mmap");
return false; return false;
} }
@ -159,7 +160,7 @@ void CIVSHMEM::Close()
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, nullptr, 0, nullptr, 0, nullptr, nullptr)) if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, nullptr, 0, nullptr, 0, nullptr, nullptr))
{ {
printf("Failed to release ivshmem mmap\n"); DBGPRINT("Failed to release ivshmem mmap");
return; return;
} }

View File

@ -15,8 +15,8 @@ private:
std::vector<struct IVSHMEMData> m_devices; std::vector<struct IVSHMEMData> m_devices;
HANDLE m_handle = INVALID_HANDLE_VALUE; HANDLE m_handle = INVALID_HANDLE_VALUE;
size_t m_size; size_t m_size = 0;
void * m_mem = nullptr; void * m_mem = nullptr;
public: public:
CIVSHMEM(); CIVSHMEM();
@ -25,5 +25,8 @@ public:
bool Init(); bool Init();
bool Open(); bool Open();
void Close(); void Close();
size_t GetSize() { return m_size; }
void * GetMem () { return m_mem; }
}; };

View File

@ -1,9 +1,46 @@
#include "CIndirectDeviceContext.h" #include "CIndirectDeviceContext.h"
#include "CIndirectMonitorContext.h" #include "CIndirectMonitorContext.h"
#include "CPlatformInfo.h"
#include "Debug.h"
static const struct LGMPQueueConfig FRAME_QUEUE_CONFIG =
{
LGMP_Q_FRAME, //queueID
LGMP_Q_FRAME_LEN, //numMessages
1000 //subTimeout
};
static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG =
{
LGMP_Q_POINTER, //queueID
LGMP_Q_POINTER_LEN, //numMesages
1000 //subTimeout
};
CIndirectDeviceContext::~CIndirectDeviceContext()
{
if (m_lgmp == nullptr)
return;
if (m_lgmpTimer)
{
WdfTimerStop(m_lgmpTimer, TRUE);
m_lgmpTimer = nullptr;
}
for(int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
lgmpHostMemFree(&m_frameMemory[i]);
for (int i = 0; i < LGMP_Q_POINTER_LEN; ++i)
lgmpHostMemFree(&m_pointerMemory[i]);
for (int i = 0; i < POINTER_SHAPE_BUFFERS; ++i)
lgmpHostMemFree(&m_pointerShapeMemory[i]);
lgmpHostFree(&m_lgmp);
}
void CIndirectDeviceContext::InitAdapter() void CIndirectDeviceContext::InitAdapter()
{ {
if (!m_ivshmem.Init() || !m_ivshmem.Open()) if (!SetupLGMP())
return; return;
IDDCX_ADAPTER_CAPS caps = {}; IDDCX_ADAPTER_CAPS caps = {};
@ -117,4 +154,179 @@ void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
IDARG_OUT_MONITORARRIVAL out; IDARG_OUT_MONITORARRIVAL out;
status = IddCxMonitorArrival(createOut.MonitorObject, &out); status = IddCxMonitorArrival(createOut.MonitorObject, &out);
}
#include <sstream>
bool CIndirectDeviceContext::SetupLGMP()
{
if (!m_ivshmem.Init() || !m_ivshmem.Open())
return false;
std::stringstream ss;
{
KVMFR kvmfr = {};
memcpy_s(kvmfr.magic, sizeof(kvmfr.magic), KVMFR_MAGIC, sizeof(KVMFR_MAGIC) - 1);
kvmfr.version = KVMFR_VERSION;
kvmfr.features = KVMFR_FEATURE_SETCURSORPOS;
strncpy_s(kvmfr.hostver, "FIXME-IDD", sizeof(kvmfr.hostver) - 1);
ss.write(reinterpret_cast<const char *>(&kvmfr), sizeof(kvmfr));
}
{
const std::string & model = CPlatformInfo::GetCPUModel();
KVMFRRecord_VMInfo * vmInfo = static_cast<KVMFRRecord_VMInfo *>(calloc(1, sizeof(*vmInfo)));
vmInfo->cpus = static_cast<uint8_t>(CPlatformInfo::GetProcCount ());
vmInfo->cores = static_cast<uint8_t>(CPlatformInfo::GetCoreCount ());
vmInfo->sockets = static_cast<uint8_t>(CPlatformInfo::GetSocketCount());
const uint8_t * uuid = CPlatformInfo::GetUUID();
memcpy_s (vmInfo->uuid, sizeof(vmInfo->uuid), uuid, 16);
strncpy_s(vmInfo->capture, "Idd Driver", sizeof(vmInfo->capture));
KVMFRRecord * record = static_cast<KVMFRRecord *>(calloc(1, sizeof(*record)));
record->type = KVMFR_RECORD_VMINFO;
record->size = sizeof(*vmInfo) + (uint32_t)model.length() + 1;
ss.write(reinterpret_cast<const char*>(record ), sizeof(*record));
ss.write(reinterpret_cast<const char*>(vmInfo ), sizeof(*vmInfo));
ss.write(reinterpret_cast<const char*>(model.c_str()), model.length() + 1);
}
{
KVMFRRecord_OSInfo * osInfo = static_cast<KVMFRRecord_OSInfo *>(calloc(1, sizeof(*osInfo)));
osInfo->os = KVMFR_OS_WINDOWS;
const std::string & osName = CPlatformInfo::GetProductName();
KVMFRRecord* record = static_cast<KVMFRRecord*>(calloc(1, sizeof(*record)));
record->type = KVMFR_RECORD_OSINFO;
record->size = sizeof(*osInfo) + (uint32_t)osName.length() + 1;
ss.write(reinterpret_cast<const char*>(record), sizeof(*record));
ss.write(reinterpret_cast<const char*>(osInfo), sizeof(*osInfo));
ss.write(reinterpret_cast<const char*>(osName.c_str()), osName.length() + 1);
}
LGMP_STATUS status;
std::string udata = ss.str();
if ((status = lgmpHostInit(m_ivshmem.GetMem(), (uint32_t)m_ivshmem.GetSize(),
&m_lgmp, (uint32_t)udata.size(), (uint8_t*)&udata[0])) != LGMP_OK)
{
DBGPRINT("lgmpHostInit Failed: %s", lgmpStatusString(status));
return false;
}
if ((status = lgmpHostQueueNew(m_lgmp, FRAME_QUEUE_CONFIG, &m_frameQueue)) != LGMP_OK)
{
DBGPRINT("lgmpHostQueueCreate Failed (Frame): %s", lgmpStatusString(status));
return false;
}
if ((status = lgmpHostQueueNew(m_lgmp, POINTER_QUEUE_CONFIG, &m_pointerQueue)) != LGMP_OK)
{
DBGPRINT("lgmpHostQueueCreate Failed (Pointer): %s", lgmpStatusString(status));
return false;
}
for (int i = 0; i < LGMP_Q_POINTER_LEN; ++i)
{
if ((status = lgmpHostMemAlloc(m_lgmp, MAX_POINTER_SIZE, &m_pointerMemory[i])) != LGMP_OK)
{
DBGPRINT("lgmpHostMemAlloc Failed (Pointer): %s", lgmpStatusString(status));
return false;
}
memset(lgmpHostMemPtr(m_pointerMemory[i]), 0, MAX_POINTER_SIZE);
}
for (int i = 0; i < POINTER_SHAPE_BUFFERS; ++i)
{
if ((status = lgmpHostMemAlloc(m_lgmp, MAX_POINTER_SIZE, &m_pointerShapeMemory[i])) != LGMP_OK)
{
DBGPRINT("lgmpHostMemAlloc Failed (Pointer Shapes): %s", lgmpStatusString(status));
return false;
}
memset(lgmpHostMemPtr(m_pointerShapeMemory[i]), 0, MAX_POINTER_SIZE);
}
m_maxFrameSize = lgmpHostMemAvail(m_lgmp);
m_maxFrameSize = (m_maxFrameSize -(CPlatformInfo::GetPageSize() - 1)) & ~(CPlatformInfo::GetPageSize() - 1);
m_maxFrameSize /= LGMP_Q_FRAME_LEN;
DBGPRINT("Max Frame Size: %u MiB\n", (unsigned int)(m_maxFrameSize / 1048576LL));
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
if ((status = lgmpHostMemAllocAligned(m_lgmp, (uint32_t)m_maxFrameSize,
(uint32_t)CPlatformInfo::GetPageSize(), &m_frameMemory[i])) != LGMP_OK)
{
DBGPRINT("lgmpHostMemAllocAligned Failed (Frame): %s", lgmpStatusString(status));
return false;
}
WDF_TIMER_CONFIG config;
WDF_TIMER_CONFIG_INIT_PERIODIC(&config,
[](WDFTIMER timer) -> void
{
WDFOBJECT parent = WdfTimerGetParentObject(timer);
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(parent);
wrapper->context->LGMPTimer();
},
10);
config.AutomaticSerialization = FALSE;
/**
* documentation states that Dispatch is not available under the UDMF, however...
* using Passive returns a not supported error, and Dispatch works.
*/
WDF_OBJECT_ATTRIBUTES attribs;
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
attribs.ParentObject = m_wdfDevice;
attribs.ExecutionLevel = WdfExecutionLevelDispatch;
NTSTATUS s = WdfTimerCreate(&config, &attribs, &m_lgmpTimer);
if (!NT_SUCCESS(s))
{
DBGPRINT("Timer creation failed: 0x%08x", s);
return false;
}
WdfTimerStart(m_lgmpTimer, WDF_REL_TIMEOUT_IN_MS(10));
return true;
}
void CIndirectDeviceContext::LGMPTimer()
{
LGMP_STATUS status;
if ((status = lgmpHostProcess(m_lgmp)) != LGMP_OK)
{
if (status == LGMP_ERR_CORRUPTED)
{
DBGPRINT("LGMP reported the shared memory has been corrupted, attempting to recover\n");
//TODO: fixme - reinit
return;
}
DBGPRINT("lgmpHostProcess Failed: %s", lgmpStatusString(status));
//TODO: fixme - shutdown
return;
}
uint8_t data[LGMP_MSGS_SIZE];
size_t size;
while ((status = lgmpHostReadData(m_pointerQueue, &data, &size)) == LGMP_OK)
{
KVMFRMessage * msg = (KVMFRMessage *)data;
switch (msg->type)
{
case KVMFR_MESSAGE_SETCURSORPOS:
{
KVMFRSetCursorPos *sp = (KVMFRSetCursorPos *)msg;
SetCursorPos(sp->x, sp->y);
break;
}
}
lgmpHostAckData(m_pointerQueue);
}
} }

View File

@ -3,8 +3,17 @@
#include <Windows.h> #include <Windows.h>
#include <wdf.h> #include <wdf.h>
#include <IddCx.h> #include <IddCx.h>
#include "CIVSHMEM.h" #include "CIVSHMEM.h"
extern "C" {
#include "lgmp/host.h"
}
#include "common/KVMFR.h"
#define MAX_POINTER_SIZE (sizeof(KVMFRCursor) + (512 * 512 * 4))
#define POINTER_SHAPE_BUFFERS 3
class CIndirectDeviceContext class CIndirectDeviceContext
{ {
private: private:
@ -12,11 +21,27 @@ private:
IDDCX_ADAPTER m_adapter = nullptr; IDDCX_ADAPTER m_adapter = nullptr;
CIVSHMEM m_ivshmem; CIVSHMEM m_ivshmem;
PLGMPHost m_lgmp = nullptr;
PLGMPHostQueue m_frameQueue = nullptr;
PLGMPHostQueue m_pointerQueue = nullptr;
PLGMPMemory m_pointerMemory [LGMP_Q_POINTER_LEN ] = {};
PLGMPMemory m_pointerShapeMemory[POINTER_SHAPE_BUFFERS] = {};
size_t m_maxFrameSize = 0;
PLGMPMemory m_frameMemory[LGMP_Q_FRAME_LEN] = {};
bool SetupLGMP();
void LGMPTimer();
WDFTIMER m_lgmpTimer = nullptr;
public: public:
CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) : CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
m_wdfDevice(wdfDevice) {}; m_wdfDevice(wdfDevice) {};
virtual ~CIndirectDeviceContext() {}; virtual ~CIndirectDeviceContext();
void InitAdapter(); void InitAdapter();

View File

@ -4,18 +4,15 @@
CIndirectMonitorContext::CIndirectMonitorContext(_In_ IDDCX_MONITOR monitor) : CIndirectMonitorContext::CIndirectMonitorContext(_In_ IDDCX_MONITOR monitor) :
m_monitor(monitor) m_monitor(monitor)
{ {
OutputDebugStringA(__FUNCTION__);
} }
CIndirectMonitorContext::~CIndirectMonitorContext() CIndirectMonitorContext::~CIndirectMonitorContext()
{ {
OutputDebugStringA(__FUNCTION__);
m_thread.reset(); m_thread.reset();
} }
void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent) void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent)
{ {
OutputDebugStringA(__FUNCTION__);
m_thread.reset(); m_thread.reset();
auto device = std::make_shared<Direct3DDevice>(renderAdapter); auto device = std::make_shared<Direct3DDevice>(renderAdapter);
if (FAILED(device->Init())) if (FAILED(device->Init()))
@ -29,6 +26,5 @@ void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID re
void CIndirectMonitorContext::UnassignSwapChain() void CIndirectMonitorContext::UnassignSwapChain()
{ {
OutputDebugStringA(__FUNCTION__);
m_thread.reset(); m_thread.reset();
} }

253
idd/LGIdd/CPlatformInfo.cpp Normal file
View File

@ -0,0 +1,253 @@
#include "CPlatformInfo.h"
#include "Debug.h"
#include <Windows.h>
size_t CPlatformInfo::m_pageSize = 0;
std::string CPlatformInfo::m_productName = "Unknown";
uint8_t CPlatformInfo::m_uuid[16];
std::string CPlatformInfo::m_model = "Unknown";
int CPlatformInfo::m_cores = 0;
int CPlatformInfo::m_procs = 0;
int CPlatformInfo::m_sockets = 0;
void CPlatformInfo::Init()
{
SYSTEM_INFO si;
GetSystemInfo(&si);
m_pageSize = (size_t)si.dwPageSize;
// we only use this for reporting, it's OK that it might not be exactly accurate
#pragma warning(push)
#pragma warning(disable : 4996)
OSVERSIONINFOA osvi = {};
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionExA(&osvi);
#pragma warning(pop)
DWORD bufferSize = 0;
LSTATUS status = RegGetValueA(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName",
RRF_RT_REG_SZ, nullptr, nullptr, &bufferSize);
if (status == ERROR_SUCCESS)
{
m_productName.resize(bufferSize);
status = RegGetValueA(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName",
RRF_RT_REG_SZ, nullptr, &m_productName[0], &bufferSize);
if (status != ERROR_SUCCESS)
{
m_productName = "Unknown";
DBGPRINT("Failed to read the ProductName");
}
else
m_productName.resize(bufferSize - 1); // remove the double null termination
}
else
{
m_productName = "Windows " +
std::to_string(osvi.dwMajorVersion) + "." +
std::to_string(osvi.dwMinorVersion);
}
m_productName += " (Build: " +
std::to_string(osvi.dwBuildNumber) + ") " +
osvi.szCSDVersion;
InitUUID();
InitCPUInfo();
}
#define TABLE_SIG(x) (\
((uint32_t)(x[0]) << 24) | \
((uint32_t)(x[1]) << 16) | \
((uint32_t)(x[2]) << 8 ) | \
((uint32_t)(x[3]) << 0 ))
#define SMB_SST_SystemInformation 1
#define SMBVER(major, minor) \
((smbData->SMBIOSMajorVersion == major && \
smbData->SMBIOSMinorVersion >= minor) || \
(smbData->SMBIOSMajorVersion > major))
#define REVERSE32(x) \
*(uint32_t*)(x) = ((*(uint32_t*)(x) & 0xFFFF0000) >> 16) | \
((*(uint32_t*)(x) & 0x0000FFFF) << 16)
#define REVERSE16(x) \
*(uint16_t*)(x) = ((*(uint16_t*)(x) & 0xFF00) >> 8) | \
((*(uint16_t*)(x) & 0x00FF) << 8)
static void* smbParseData(uint8_t** data, char* strings[])
{
#pragma pack(push, 1)
struct SMBHeader
{
uint8_t type;
uint8_t length;
};
#pragma pack(pop)
SMBHeader* h = (SMBHeader*)*data;
*data += h->length;
if (**data)
for (int i = 1; i < 256 && **data; ++i)
{
strings[i] = (char*)*data;
*data += strlen((char*)*data) + 1;
}
else
++* data;
++* data;
return h;
}
void CPlatformInfo::InitUUID()
{
// don't warn on zero length arrays
#pragma warning(push)
#pragma warning(disable: 4200)
struct RawSMBIOSData
{
BYTE Used20CallingMethod;
BYTE SMBIOSMajorVersion;
BYTE SMBIOSMinorVersion;
BYTE DmiRevision;
DWORD Length;
BYTE SMBIOSTableData[];
};
#pragma warning(pop)
#pragma pack(push, 1)
struct SMBSystemInformation
{
uint8_t type;
uint8_t length;
uint16_t handle;
uint8_t manufacturerStr;
uint8_t productStr;
uint8_t versionStr;
uint8_t serialStr;
uint8_t uuid[16];
uint8_t wakeupType;
uint8_t skuNumberStr;
uint8_t familyStr;
};
#pragma pack(pop)
DWORD smbDataSize;
RawSMBIOSData * smbData;
smbDataSize = GetSystemFirmwareTable(TABLE_SIG("RSMB"), 0, nullptr, 0);
smbData = (RawSMBIOSData*)new BYTE[smbDataSize];
if (!smbData)
{
DBGPRINT("out of memory");
return;
}
if (GetSystemFirmwareTable(TABLE_SIG("RSMB"), 0, smbData, smbDataSize)
!= smbDataSize)
{
DBGPRINT("Failed to read the RSMB table");
delete[] smbData;
return;
}
uint8_t * data = (uint8_t *)smbData->SMBIOSTableData;
uint8_t * end = (uint8_t *)smbData->SMBIOSTableData + smbData->Length;
char * strings[256] = {};
while (data != end)
{
if (data[0] == SMB_SST_SystemInformation)
{
SMBSystemInformation * info = (SMBSystemInformation *)smbParseData(&data, strings);
memcpy(&m_uuid, &info->uuid, 16);
REVERSE32(&m_uuid[0]);
REVERSE16(&m_uuid[0]);
REVERSE16(&m_uuid[2]);
REVERSE16(&m_uuid[4]);
REVERSE16(&m_uuid[6]);
break;
}
smbParseData(&data, strings);
}
delete[] smbData;
}
void CPlatformInfo::InitCPUInfo()
{
DWORD bufferSize = 0;
LSTATUS status = RegGetValueA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\SYSTEM\\CentralProcessor\\0",
"ProcessorNameString", RRF_RT_REG_SZ, nullptr, nullptr, &bufferSize);
if (status == ERROR_SUCCESS)
{
m_model.resize(bufferSize);
status = RegGetValueA(HKEY_LOCAL_MACHINE,
"HARDWARE\\DESCRIPTION\\SYSTEM\\CentralProcessor\\0",
"ProcessorNameString", RRF_RT_REG_SZ, nullptr, &m_model[0], &bufferSize);
if (status != ERROR_SUCCESS)
{
m_model = "Unknown";
DBGPRINT("Failed to read the CPU Model");
}
else
{
m_model.resize(bufferSize - 1); // remove the double null termination
m_model.erase(m_model.find_last_not_of(" \t\n\r\f\v") + 1);
}
}
DWORD cb = 0;
GetLogicalProcessorInformationEx(RelationAll, nullptr, &cb);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
DBGPRINT("Failed to call GetLogicalProcessorInformationEx");
return;
}
BYTE * buffer = static_cast<BYTE *>(_malloca(cb));
if (!GetLogicalProcessorInformationEx(RelationAll,
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer, &cb))
{
DBGPRINT("Failed to call GetLogicalProcessorInformationEx");
_freea(buffer);
return;
}
DWORD offset = 0;
while (offset < cb)
{
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi =
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)(buffer + offset);
switch (lpi->Relationship)
{
case RelationProcessorCore:
++m_cores;
for(int i = 0; i < lpi->Processor.GroupCount; ++i)
m_procs += (int)__popcnt64(lpi->Processor.GroupMask[i].Mask);
break;
case RelationProcessorPackage:
++m_sockets;
default:
break;
}
offset += lpi->Size;
}
_freea(buffer);
}

31
idd/LGIdd/CPlatformInfo.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <string>
class CPlatformInfo
{
private:
static size_t m_pageSize;
static std::string m_productName;
static uint8_t m_uuid[16];
static std::string m_model;
static int m_cores;
static int m_procs;
static int m_sockets;
static void InitUUID();
static void InitCPUInfo();
public:
static void Init();
inline static size_t GetPageSize() { return m_pageSize; }
inline static const std::string& GetProductName() { return m_productName; }
inline static const uint8_t* GetUUID() { return m_uuid; }
inline static const std::string & GetCPUModel() { return m_model; }
inline static int GetCoreCount() { return m_cores; }
inline static int GetProcCount() { return m_procs; }
inline static int GetSocketCount() { return m_sockets; }
};

View File

@ -8,14 +8,12 @@ CSwapChainProcessor::CSwapChainProcessor(IDDCX_SWAPCHAIN hSwapChain, std::shared
m_device(device), m_device(device),
m_newFrameEvent(newFrameEvent) m_newFrameEvent(newFrameEvent)
{ {
OutputDebugStringA(__FUNCTION__);
m_terminateEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr)); m_terminateEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr));
m_thread.Attach(CreateThread(nullptr, 0, RunThread, this, 0, nullptr)); m_thread.Attach(CreateThread(nullptr, 0, RunThread, this, 0, nullptr));
} }
CSwapChainProcessor::~CSwapChainProcessor() CSwapChainProcessor::~CSwapChainProcessor()
{ {
OutputDebugStringA(__FUNCTION__);
SetEvent(m_terminateEvent.Get()); SetEvent(m_terminateEvent.Get());
if (m_thread.Get()) if (m_thread.Get())
WaitForSingleObject(m_thread.Get(), INFINITE); WaitForSingleObject(m_thread.Get(), INFINITE);
@ -23,7 +21,6 @@ CSwapChainProcessor::~CSwapChainProcessor()
DWORD CALLBACK CSwapChainProcessor::RunThread(LPVOID argument) DWORD CALLBACK CSwapChainProcessor::RunThread(LPVOID argument)
{ {
OutputDebugStringA(__FUNCTION__);
reinterpret_cast<CSwapChainProcessor*>(argument)->Run(); reinterpret_cast<CSwapChainProcessor*>(argument)->Run();
return 0; return 0;
} }

32
idd/LGIdd/Debug.cpp Normal file
View File

@ -0,0 +1,32 @@
#include <Windows.h>
#include <malloc.h>
#include <strsafe.h>
/* credit: https://stackoverflow.com/questions/29049686/is-there-a-better-way-to-pass-formatted-output-to-outputdebugstring */
VOID _DBGPRINT(PCSTR kwszFunction, INT iLineNumber, LPCSTR kszDebugFormatString, ...) \
{
INT cbFormatString = 0;
va_list args;
PCHAR szDebugString = NULL;
size_t st_Offset = 0;
va_start(args, kszDebugFormatString);
cbFormatString = _scprintf("[%s:%d] ", kwszFunction, iLineNumber) * sizeof(CHAR);
cbFormatString += _vscprintf(kszDebugFormatString, args) * sizeof(CHAR) + 2;
/* Depending on the size of the format string, allocate space on the stack or the heap. */
szDebugString = (PCHAR)_malloca(cbFormatString);
if (!szDebugString)
return;
/* Populate the buffer with the contents of the format string. */
StringCbPrintfA(szDebugString, cbFormatString, "[%s:%d] ", kwszFunction, iLineNumber);
StringCbLengthA(szDebugString, cbFormatString, &st_Offset);
StringCbVPrintfA(&szDebugString[st_Offset / sizeof(CHAR)], cbFormatString - st_Offset, kszDebugFormatString, args);
OutputDebugStringA(szDebugString);
_freea(szDebugString);
va_end(args);
}

8
idd/LGIdd/Debug.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <Windows.h>
#include <tchar.h>
VOID _DBGPRINT(PCSTR kszFunction, INT iLineNumber, LPCSTR kszDebugFormatString, ...);
#define DBGPRINT(kszDebugFormatString, ...) \
_DBGPRINT(__FUNCTION__, __LINE__, kszDebugFormatString, __VA_ARGS__)

View File

@ -16,7 +16,7 @@ NTSTATUS LGIddDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previousSta
{ {
UNREFERENCED_PARAMETER(previousState); UNREFERENCED_PARAMETER(previousState);
UNREFERENCED_PARAMETER(device); UNREFERENCED_PARAMETER(device);
auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device); auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device);
wrapper->context->InitAdapter(); wrapper->context->InitAdapter();
@ -132,7 +132,6 @@ NTSTATUS LGIddMonitorUnassignSwapChain(IDDCX_MONITOR monitor)
NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit) NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
{ {
OutputDebugStringA(__FUNCTION__);
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
pnpPowerCallbacks.EvtDeviceD0Entry = LGIddDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Entry = LGIddDeviceD0Entry;
@ -150,10 +149,7 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
NTSTATUS status = IddCxDeviceInitConfig(deviceInit, &config); NTSTATUS status = IddCxDeviceInitConfig(deviceInit, &config);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
{
OutputDebugStringA(__FUNCTION__ " FAILURE1");
return status; return status;
}
WDF_OBJECT_ATTRIBUTES deviceAttributes; WDF_OBJECT_ATTRIBUTES deviceAttributes;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, CIndirectDeviceContextWrapper); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, CIndirectDeviceContextWrapper);
@ -167,16 +163,11 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
WDFDEVICE device = nullptr; WDFDEVICE device = nullptr;
status = WdfDeviceCreate(&deviceInit, &deviceAttributes, &device); status = WdfDeviceCreate(&deviceInit, &deviceAttributes, &device);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
{
OutputDebugStringA(__FUNCTION__ " FAILURE2");
return status; return status;
}
status = IddCxDeviceInitialize(device); status = IddCxDeviceInitialize(device);
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device); auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device);
wrapper->context = new CIndirectDeviceContext(device); wrapper->context = new CIndirectDeviceContext(device);
OutputDebugStringA(__FUNCTION__ " SUCCESS");
return status; return status;
} }

View File

@ -1,10 +1,10 @@
#include "driver.h" #include "driver.h"
#include "driver.tmh" #include "driver.tmh"
#include "CPlatformInfo.h"
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{ {
OutputDebugStringA(__FUNCTION__);
WDF_DRIVER_CONFIG config; WDF_DRIVER_CONFIG config;
NTSTATUS status; NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes; WDF_OBJECT_ATTRIBUTES attributes;
@ -21,10 +21,10 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Reg
attributes.EvtCleanupCallback = LGIddEvtDriverContextCleanup; attributes.EvtCleanupCallback = LGIddEvtDriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(&config, LGIddEvtDeviceAdd); WDF_DRIVER_CONFIG_INIT(&config, LGIddEvtDeviceAdd);
CPlatformInfo::Init();
status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE); status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE);
if (!NT_SUCCESS(status)) if (!NT_SUCCESS(status))
{ {
OutputDebugStringA(__FUNCTION__ " FAILURE");
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status); TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0 #if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
WPP_CLEANUP(); WPP_CLEANUP();
@ -35,14 +35,11 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Reg
} }
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
OutputDebugStringA(__FUNCTION__ " SUCCESS");
return status; return status;
} }
NTSTATUS LGIddEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit) NTSTATUS LGIddEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
{ {
OutputDebugStringA(__FUNCTION__);
NTSTATUS status; NTSTATUS status;
UNREFERENCED_PARAMETER(Driver); UNREFERENCED_PARAMETER(Driver);
@ -54,8 +51,6 @@ NTSTATUS LGIddEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT Device
VOID LGIddEvtDriverContextCleanup(_In_ WDFOBJECT DriverObject) VOID LGIddEvtDriverContextCleanup(_In_ WDFOBJECT DriverObject)
{ {
OutputDebugStringA(__FUNCTION__);
UNREFERENCED_PARAMETER(DriverObject); UNREFERENCED_PARAMETER(DriverObject);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");

View File

@ -41,7 +41,9 @@
<ClCompile Include="CIndirectDeviceContext.cpp" /> <ClCompile Include="CIndirectDeviceContext.cpp" />
<ClCompile Include="CIndirectMonitorContext.cpp" /> <ClCompile Include="CIndirectMonitorContext.cpp" />
<ClCompile Include="CIVSHMEM.cpp" /> <ClCompile Include="CIVSHMEM.cpp" />
<ClCompile Include="CPlatformInfo.cpp" />
<ClCompile Include="CSwapChainProcessor.cpp" /> <ClCompile Include="CSwapChainProcessor.cpp" />
<ClCompile Include="Debug.cpp" />
<ClCompile Include="Device.cpp" /> <ClCompile Include="Device.cpp" />
<ClCompile Include="Direct3DDevice.cpp" /> <ClCompile Include="Direct3DDevice.cpp" />
<ClCompile Include="Driver.cpp" /> <ClCompile Include="Driver.cpp" />
@ -49,7 +51,9 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="CIndirectMonitorContext.h" /> <ClInclude Include="CIndirectMonitorContext.h" />
<ClInclude Include="CIVSHMEM.h" /> <ClInclude Include="CIVSHMEM.h" />
<ClInclude Include="CPlatformInfo.h" />
<ClInclude Include="CSwapChainProcessor.h" /> <ClInclude Include="CSwapChainProcessor.h" />
<ClInclude Include="Debug.h" />
<ClInclude Include="Device.h" /> <ClInclude Include="Device.h" />
<ClInclude Include="Direct3DDevice.h" /> <ClInclude Include="Direct3DDevice.h" />
<ClInclude Include="Driver.h" /> <ClInclude Include="Driver.h" />
@ -220,7 +224,7 @@
<WppRecorderEnabled>true</WppRecorderEnabled> <WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
@ -232,7 +236,7 @@
<WppRecorderEnabled>true</WppRecorderEnabled> <WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
@ -244,7 +248,7 @@
<WppRecorderEnabled>true</WppRecorderEnabled> <WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
@ -256,7 +260,7 @@
<WppRecorderEnabled>true</WppRecorderEnabled> <WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>

View File

@ -54,6 +54,12 @@
<ClInclude Include="CIVSHMEM.h"> <ClInclude Include="CIVSHMEM.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Debug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CPlatformInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Device.cpp"> <ClCompile Include="Device.cpp">
@ -77,5 +83,11 @@
<ClCompile Include="CIVSHMEM.cpp"> <ClCompile Include="CIVSHMEM.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Debug.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CPlatformInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>