mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 05:42:58 +00:00
[idd] implement CIVSHMEM and open it
This commit is contained in:
parent
d228ef135e
commit
77ddcfe489
6 changed files with 218 additions and 8 deletions
168
idd/LGIdd/CIVSHMEM.cpp
Normal file
168
idd/LGIdd/CIVSHMEM.cpp
Normal file
|
@ -0,0 +1,168 @@
|
|||
#include "CIVSHMEM.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <algorithm>
|
||||
#include <winioctl.h>
|
||||
|
||||
#include "ivshmem/ivshmem.h"
|
||||
|
||||
CIVSHMEM::CIVSHMEM()
|
||||
{
|
||||
}
|
||||
|
||||
CIVSHMEM::~CIVSHMEM()
|
||||
{
|
||||
if (m_handle == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
Close();
|
||||
CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
bool CIVSHMEM::Init()
|
||||
{
|
||||
HDEVINFO devInfoSet;
|
||||
SP_DEVINFO_DATA devInfoData;
|
||||
SP_DEVICE_INTERFACE_DATA devInterfaceData;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA infData = nullptr;
|
||||
|
||||
devInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_IVSHMEM, nullptr, nullptr,
|
||||
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
|
||||
devInfoData.cbSize = sizeof(devInfoData);
|
||||
devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
|
||||
m_devices.clear();
|
||||
for (int i = 0; SetupDiEnumDeviceInfo(devInfoSet, i, &devInfoData); ++i)
|
||||
{
|
||||
DWORD bus, addr;
|
||||
if (!SetupDiGetDeviceRegistryProperty(devInfoSet, &devInfoData, SPDRP_BUSNUMBER,
|
||||
nullptr, (BYTE*)&bus, sizeof(bus), nullptr))
|
||||
bus = 0xffff;
|
||||
|
||||
if (!SetupDiGetDeviceRegistryProperty(devInfoSet, &devInfoData, SPDRP_ADDRESS,
|
||||
nullptr, (BYTE*)&addr, sizeof(addr), nullptr))
|
||||
addr = 0xffff;
|
||||
|
||||
IVSHMEMData data;
|
||||
data.busAddr = ((DWORD64)bus) << 32 | addr;
|
||||
memcpy(&data.devInfoData, &devInfoData, sizeof(devInfoData));
|
||||
m_devices.push_back(data);
|
||||
}
|
||||
|
||||
if (GetLastError() != ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
m_devices.clear();
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(m_devices.begin(), m_devices.end(),
|
||||
[](const IVSHMEMData & a, const IVSHMEMData & b) -> bool
|
||||
{ return a.busAddr < b.busAddr; });
|
||||
|
||||
|
||||
HKEY hkeyLG;
|
||||
IVSHMEMData * device = nullptr;
|
||||
DWORD shmDevice = 0;
|
||||
|
||||
if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Looking Glass", &hkeyLG) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD dataType;
|
||||
DWORD dataSize = sizeof(shmDevice);
|
||||
if (RegQueryValueExA(hkeyLG, "shmDevice", nullptr, &dataType, (BYTE*)&shmDevice, &dataSize) != ERROR_SUCCESS ||
|
||||
dataType != REG_DWORD)
|
||||
shmDevice = 0;
|
||||
}
|
||||
|
||||
DWORD i = 0;
|
||||
for (auto it = m_devices.begin(); it != m_devices.end(); ++it, ++i)
|
||||
{
|
||||
DWORD bus = it->busAddr >> 32;
|
||||
DWORD addr = it->busAddr & 0xFFFFFFFF;
|
||||
printf("IVSHMEM %u%c on bus 0x%lx, device 0x%lx, function 0x%lx\n",
|
||||
i, i == shmDevice ? '*' : ' ', bus, addr >> 16, addr & 0xFFFF);
|
||||
|
||||
if (i == shmDevice)
|
||||
device = &(*it);
|
||||
}
|
||||
|
||||
if (!device)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SetupDiEnumDeviceInterfaces(devInfoSet, &devInfoData, &GUID_DEVINTERFACE_IVSHMEM, 0, &devInterfaceData) == FALSE)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD reqSize = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterfaceData, nullptr, 0, &reqSize, nullptr);
|
||||
if (!reqSize)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return false;
|
||||
}
|
||||
|
||||
infData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)calloc(1, reqSize);
|
||||
infData->cbSize = sizeof(PSP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
if (!SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterfaceData, infData, reqSize, nullptr, nullptr))
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_handle = CreateFile(infData->DevicePath, 0, 0, nullptr, OPEN_EXISTING, 0, 0);
|
||||
if (m_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(devInfoSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CIVSHMEM::Open()
|
||||
{
|
||||
IVSHMEM_SIZE size;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, nullptr, 0, &size, sizeof(size), nullptr, nullptr))
|
||||
{
|
||||
printf("Failed to request ivshmem size\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
IVSHMEM_MMAP_CONFIG config = {};
|
||||
IVSHMEM_MMAP map = {};
|
||||
|
||||
config.cacheMode = IVSHMEM_CACHE_WRITECOMBINED;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_MMAP, &config, sizeof(config), &map, sizeof(map), nullptr, nullptr))
|
||||
{
|
||||
printf("Failed to request ivshmem mmap\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_size = (size_t)size;
|
||||
m_mem = map.ptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIVSHMEM::Close()
|
||||
{
|
||||
if (m_mem == nullptr)
|
||||
return;
|
||||
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, nullptr, 0, nullptr, 0, nullptr, nullptr))
|
||||
{
|
||||
printf("Failed to release ivshmem mmap\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_size = 0;
|
||||
m_mem = nullptr;
|
||||
}
|
29
idd/LGIdd/CIVSHMEM.h
Normal file
29
idd/LGIdd/CIVSHMEM.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <vector>
|
||||
|
||||
class CIVSHMEM
|
||||
{
|
||||
private:
|
||||
struct IVSHMEMData
|
||||
{
|
||||
SP_DEVINFO_DATA devInfoData;
|
||||
DWORD64 busAddr;
|
||||
};
|
||||
|
||||
std::vector<struct IVSHMEMData> m_devices;
|
||||
HANDLE m_handle = INVALID_HANDLE_VALUE;
|
||||
size_t m_size;
|
||||
void * m_mem = nullptr;
|
||||
|
||||
public:
|
||||
CIVSHMEM();
|
||||
~CIVSHMEM();
|
||||
|
||||
bool Init();
|
||||
bool Open();
|
||||
void Close();
|
||||
};
|
||||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
void CIndirectDeviceContext::InitAdapter()
|
||||
{
|
||||
if (!m_ivshmem.Init() || !m_ivshmem.Open())
|
||||
return;
|
||||
|
||||
IDDCX_ADAPTER_CAPS caps = {};
|
||||
caps.Size = sizeof(caps);
|
||||
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
#include <Windows.h>
|
||||
#include <wdf.h>
|
||||
#include <IddCx.h>
|
||||
#include "CIVSHMEM.h"
|
||||
|
||||
class CIndirectDeviceContext
|
||||
{
|
||||
private:
|
||||
WDFDEVICE m_wdfDevice;
|
||||
IDDCX_ADAPTER m_adapter = nullptr;
|
||||
CIVSHMEM m_ivshmem;
|
||||
|
||||
public:
|
||||
CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="CIndirectDeviceContext.cpp" />
|
||||
<ClCompile Include="CIndirectMonitorContext.cpp" />
|
||||
<ClCompile Include="CIVSHMEM.cpp" />
|
||||
<ClCompile Include="CSwapChainProcessor.cpp" />
|
||||
<ClCompile Include="Device.cpp" />
|
||||
<ClCompile Include="Direct3DDevice.cpp" />
|
||||
|
@ -47,6 +48,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CIndirectMonitorContext.h" />
|
||||
<ClInclude Include="CIVSHMEM.h" />
|
||||
<ClInclude Include="CSwapChainProcessor.h" />
|
||||
<ClInclude Include="Device.h" />
|
||||
<ClInclude Include="Direct3DDevice.h" />
|
||||
|
@ -217,8 +219,8 @@
|
|||
<WppEnabled>true</WppEnabled>
|
||||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
@ -229,8 +231,8 @@
|
|||
<WppEnabled>true</WppEnabled>
|
||||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
@ -241,8 +243,8 @@
|
|||
<WppEnabled>true</WppEnabled>
|
||||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
@ -253,8 +255,8 @@
|
|||
<WppEnabled>true</WppEnabled>
|
||||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
<ClInclude Include="Direct3DDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CIVSHMEM.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Device.cpp">
|
||||
|
@ -71,5 +74,8 @@
|
|||
<ClCompile Include="Direct3DDevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CIVSHMEM.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in a new issue