Skip to content

Commit e3f58b6

Browse files
author
bud3699
committed
Added support for changing colour format
- Added support for changing colour format in xml Supported formats: RGB YCbCr444 YCbCr422 YCbCr420 - XML Grouped
1 parent e4bc402 commit e3f58b6

File tree

2 files changed

+166
-24
lines changed

2 files changed

+166
-24
lines changed

Virtual Display Driver (HDR)/MttVDD/Driver.cpp

Lines changed: 152 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,28 @@ IDDCX_XOR_CURSOR_SUPPORT XorCursorSupportLevel = IDDCX_XOR_CURSOR_SUPPORT_FULL;
110110
IDDCX_BITS_PER_COMPONENT SDRCOLOUR = IDDCX_BITS_PER_COMPONENT_8;
111111
IDDCX_BITS_PER_COMPONENT HDRCOLOUR = IDDCX_BITS_PER_COMPONENT_10;
112112

113+
wstring ColourFormat = L"RGB";
114+
113115
std::map<std::wstring, std::pair<std::wstring, std::wstring>> SettingsQueryMap = {
114116
{L"LoggingEnabled", {L"LOGS", L"logging"}},
115117
{L"DebugLoggingEnabled", {L"DEBUGLOGS", L"debuglogging"}},
116-
{L"HDRPlusEnabled", {L"HDRPLUS", L"HDRPlus"}},
117-
{L"SDR10Enabled", {L"SDR10BIT", L"SDR10bit"}},
118118
{L"CustomEdidEnabled", {L"CUSTOMEDID", L"CustomEdid"}},
119-
{L"HardwareCursorEnabled", {L"HARDWARECURSOR", L"HardwareCursor"}},
119+
120120
{L"PreventMonitorSpoof", {L"PREVENTMONITORSPOOF", L"PreventSpoof"}},
121121
{L"EdidCeaOverride", {L"EDIDCEAOVERRIDE", L"EdidCeaOverride"}},
122122
{L"SendLogsThroughPipe", {L"SENDLOGSTHROUGHPIPE", L"SendLogsThroughPipe"}},
123-
//Cursor
123+
//Cursor Begin
124+
{L"HardwareCursorEnabled", {L"HARDWARECURSOR", L"HardwareCursor"}},
124125
{L"AlphaCursorSupport", {L"ALPHACURSORSUPPORT", L"AlphaCursorSupport"}},
125126
{L"CursorMaxX", {L"CURSORMAXX", L"CursorMaxX"}},
126127
{L"CursorMaxY", {L"CURSORMAXY", L"CursorMaxY"}},
127128
{L"XorCursorSupportLevel", {L"XORCURSORSUPPORTLEVEL", L"XorCursorSupportLevel"}},
128-
129+
///Cursor End
130+
//Colour Begin
131+
{L"HDRPlusEnabled", {L"HDRPLUS", L"HDRPlus"}},
132+
{L"SDR10Enabled", {L"SDR10BIT", L"SDR10bit"}},
133+
{L"ColourFormat", {L"COLOURFORMAT", L"ColourFormat"}},
134+
//Colour End
129135
};
130136

131137
const char* XorCursorSupportLevelToString(IDDCX_XOR_CURSOR_SUPPORT level) {
@@ -167,6 +173,14 @@ void LogQueries(const char* severity, const std::wstring& xmlName) {
167173
}
168174
}
169175

176+
string WStringToString(const wstring& wstr) { //basically just a function for converting strings since codecvt is depricated in c++ 17
177+
if (wstr.empty()) return "";
178+
179+
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), NULL, 0, NULL, NULL);
180+
string str(size_needed, 0);
181+
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), &str[0], size_needed, NULL, NULL);
182+
return str;
183+
}
170184

171185
bool EnabledQuery(const std::wstring& settingKey) {
172186
auto it = SettingsQueryMap.find(settingKey);
@@ -351,16 +365,79 @@ int GetIntegerSetting(const std::wstring& settingKey) {
351365
return xmlLoggingValue;
352366
}
353367

368+
std::wstring GetStringSetting(const std::wstring& settingKey) {
369+
auto it = SettingsQueryMap.find(settingKey);
370+
if (it == SettingsQueryMap.end()) {
371+
vddlog("e", "requested data not found in xml, consider updating xml!");
372+
return L"";
373+
}
354374

355-
string WStringToString(const wstring& wstr) { //basically just a function for converting strings since codecvt is depricated in c++ 17
356-
if (wstr.empty()) return "";
375+
std::wstring regName = it->second.first;
376+
std::wstring xmlName = it->second.second;
357377

358-
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), NULL, 0, NULL, NULL);
359-
string str(size_needed, 0);
360-
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), &str[0], size_needed, NULL, NULL);
361-
return str;
378+
std::wstring settingsname = confpath + L"\\vdd_settings.xml";
379+
HKEY hKey;
380+
DWORD dwBufferSize = MAX_PATH;
381+
wchar_t buffer[MAX_PATH];
382+
383+
LONG lResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\MikeTheTech\\VirtualDisplayDriver", 0, KEY_READ, &hKey);
384+
if (lResult == ERROR_SUCCESS) {
385+
lResult = RegQueryValueExW(hKey, regName.c_str(), NULL, NULL, (LPBYTE)buffer, &dwBufferSize);
386+
RegCloseKey(hKey);
387+
388+
if (lResult == ERROR_SUCCESS) {
389+
LogQueries("d", xmlName + L" - Retrieved string value from registry: " + buffer);
390+
return std::wstring(buffer);
391+
}
392+
else {
393+
LogQueries("d", xmlName + L" - Failed to retrieve string value from registry. Attempting to read as XML.");
394+
}
395+
}
396+
397+
CComPtr<IStream> pFileStream;
398+
HRESULT hr = SHCreateStreamOnFileEx(settingsname.c_str(), STGM_READ, FILE_ATTRIBUTE_NORMAL, FALSE, nullptr, &pFileStream);
399+
if (FAILED(hr)) {
400+
LogQueries("d", xmlName + L" - Failed to create file stream for XML settings.");
401+
return L"";
402+
}
403+
404+
CComPtr<IXmlReader> pReader;
405+
hr = CreateXmlReader(__uuidof(IXmlReader), (void**)&pReader, nullptr);
406+
if (FAILED(hr)) {
407+
LogQueries("d", xmlName + L" - Failed to create XML reader.");
408+
return L"";
409+
}
410+
411+
hr = pReader->SetInput(pFileStream);
412+
if (FAILED(hr)) {
413+
LogQueries("d", xmlName + L" - Failed to set input for XML reader.");
414+
return L"";
415+
}
416+
417+
XmlNodeType nodeType;
418+
const wchar_t* pwszLocalName;
419+
std::wstring xmlLoggingValue = L"";
420+
421+
while (S_OK == pReader->Read(&nodeType)) {
422+
if (nodeType == XmlNodeType_Element) {
423+
pReader->GetLocalName(&pwszLocalName, nullptr);
424+
if (wcscmp(pwszLocalName, xmlName.c_str()) == 0) {
425+
pReader->Read(&nodeType);
426+
if (nodeType == XmlNodeType_Text) {
427+
const wchar_t* pwszValue;
428+
pReader->GetValue(&pwszValue, nullptr);
429+
xmlLoggingValue = pwszValue;
430+
LogQueries("i", xmlName + L" - Retrieved from XML: " + xmlLoggingValue);
431+
break;
432+
}
433+
}
434+
}
435+
}
436+
437+
return xmlLoggingValue;
362438
}
363439

440+
364441
int gcd(int a, int b) {
365442
while (b != 0) {
366443
int temp = b;
@@ -1346,16 +1423,20 @@ extern "C" NTSTATUS DriverEntry(
13461423
initpath();
13471424
logsEnabled = EnabledQuery(L"LoggingEnabled");
13481425
debugLogs = EnabledQuery(L"DebugLoggingEnabled");
1349-
HDRPlus = EnabledQuery(L"HDRPlusEnabled");
1350-
SDR10 = EnabledQuery(L"SDR10Enabled");
1351-
HDRCOLOUR = HDRPlus ? IDDCX_BITS_PER_COMPONENT_12 : IDDCX_BITS_PER_COMPONENT_10;
1352-
SDRCOLOUR = SDR10 ? IDDCX_BITS_PER_COMPONENT_10 : IDDCX_BITS_PER_COMPONENT_8;
13531426

13541427
customEdid = EnabledQuery(L"CustomEdidEnabled");
13551428
preventManufacturerSpoof = EnabledQuery(L"PreventMonitorSpoof");
13561429
edidCeaOverride = EnabledQuery(L"EdidCeaOverride");
13571430
sendLogsThroughPipe = EnabledQuery(L"SendLogsThroughPipe");
13581431

1432+
1433+
//colour
1434+
HDRPlus = EnabledQuery(L"HDRPlusEnabled");
1435+
SDR10 = EnabledQuery(L"SDR10Enabled");
1436+
HDRCOLOUR = HDRPlus ? IDDCX_BITS_PER_COMPONENT_12 : IDDCX_BITS_PER_COMPONENT_10;
1437+
SDRCOLOUR = SDR10 ? IDDCX_BITS_PER_COMPONENT_10 : IDDCX_BITS_PER_COMPONENT_8;
1438+
ColourFormat = GetStringSetting(L"ColourFormat");
1439+
13591440
//Cursor
13601441
hardwareCursor = EnabledQuery(L"HardwareCursorEnabled");
13611442
alphaCursorSupport = EnabledQuery(L"AlphaCursorSupport");
@@ -2820,14 +2901,31 @@ void CreateTargetMode2(IDDCX_TARGET_MODE2& Mode, UINT Width, UINT Height, UINT V
28202901
vddlog("d", logStream.str().c_str());
28212902

28222903
Mode.Size = sizeof(Mode);
2823-
Mode.BitsPerComponent.Rgb = SDRCOLOUR | HDRCOLOUR;
2904+
2905+
2906+
if (ColourFormat == L"RGB") {
2907+
Mode.BitsPerComponent.Rgb = SDRCOLOUR | HDRCOLOUR;
2908+
}
2909+
else if (ColourFormat == L"YCbCr444") {
2910+
Mode.BitsPerComponent.YCbCr444 = SDRCOLOUR | HDRCOLOUR;
2911+
}
2912+
else if (ColourFormat == L"YCbCr422") {
2913+
Mode.BitsPerComponent.YCbCr422 = SDRCOLOUR | HDRCOLOUR;
2914+
}
2915+
else if (ColourFormat == L"YCbCr420") {
2916+
Mode.BitsPerComponent.YCbCr420 = SDRCOLOUR | HDRCOLOUR;
2917+
}
2918+
else {
2919+
Mode.BitsPerComponent.Rgb = SDRCOLOUR | HDRCOLOUR; // Default to RGB
2920+
}
28242921

28252922

28262923
logStream.str("");
28272924
logStream << "IDDCX_TARGET_MODE2 configured with Size: " << Mode.Size
2828-
<< " and BitsPerComponent.Rgb: " << Mode.BitsPerComponent.Rgb;
2925+
<< " and colour format " << WStringToString(ColourFormat);
28292926
vddlog("d", logStream.str().c_str());
28302927

2928+
28312929
CreateTargetMode(Mode.TargetVideoSignalInfo.targetVideoSignalInfo, Width, Height, VSyncNum, VSyncDen);
28322930
}
28332931

@@ -2920,11 +3018,26 @@ NTSTATUS VirtualDisplayDriverEvtIddCxAdapterQueryTargetInfo(
29203018
UNREFERENCED_PARAMETER(pInArgs);
29213019

29223020
pOutArgs->TargetCaps = IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE | IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE;
2923-
pOutArgs->DitheringSupport.Rgb = HDRCOLOUR;
3021+
3022+
if (ColourFormat == L"RGB") {
3023+
pOutArgs->DitheringSupport.Rgb = SDRCOLOUR | HDRCOLOUR;
3024+
}
3025+
else if (ColourFormat == L"YCbCr444") {
3026+
pOutArgs->DitheringSupport.YCbCr444 = SDRCOLOUR | HDRCOLOUR;
3027+
}
3028+
else if (ColourFormat == L"YCbCr422") {
3029+
pOutArgs->DitheringSupport.YCbCr422 = SDRCOLOUR | HDRCOLOUR;
3030+
}
3031+
else if (ColourFormat == L"YCbCr420") {
3032+
pOutArgs->DitheringSupport.YCbCr420 = SDRCOLOUR | HDRCOLOUR;
3033+
}
3034+
else {
3035+
pOutArgs->DitheringSupport.Rgb = SDRCOLOUR | HDRCOLOUR; // Default to RGB
3036+
}
29243037

29253038
logStream.str("");
29263039
logStream << "Target capabilities set to: " << pOutArgs->TargetCaps
2927-
<< "\nDithering support set to: " << pOutArgs->DitheringSupport.Rgb;
3040+
<< "\nDithering support colour format set to: " << WStringToString(ColourFormat);
29283041
vddlog("d", logStream.str().c_str());
29293042

29303043
return STATUS_SUCCESS;
@@ -2995,13 +3108,30 @@ NTSTATUS VirtualDisplayDriverEvtIddCxParseMonitorDescription2(
29953108
pInArgs->pMonitorModes[ModeIndex].Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
29963109
pInArgs->pMonitorModes[ModeIndex].MonitorVideoSignalInfo = s_KnownMonitorModes2[ModeIndex];
29973110

2998-
pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.Rgb = SDRCOLOUR | HDRCOLOUR;
3111+
3112+
if (ColourFormat == L"RGB") {
3113+
pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.Rgb = SDRCOLOUR | HDRCOLOUR;
3114+
3115+
}
3116+
else if (ColourFormat == L"YCbCr444") {
3117+
pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.YCbCr444 = SDRCOLOUR | HDRCOLOUR;
3118+
}
3119+
else if (ColourFormat == L"YCbCr422") {
3120+
pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.YCbCr422 = SDRCOLOUR | HDRCOLOUR;
3121+
}
3122+
else if (ColourFormat == L"YCbCr420") {
3123+
pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.YCbCr420 = SDRCOLOUR | HDRCOLOUR;
3124+
}
3125+
else {
3126+
pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.Rgb = SDRCOLOUR | HDRCOLOUR; // Default to RGB
3127+
}
3128+
29993129

30003130

30013131
logStream << "\n ModeIndex: " << ModeIndex
30023132
<< "\n Size: " << pInArgs->pMonitorModes[ModeIndex].Size
30033133
<< "\n Origin: " << pInArgs->pMonitorModes[ModeIndex].Origin
3004-
<< "\n BitsPerComponent.Rgb: " << pInArgs->pMonitorModes[ModeIndex].BitsPerComponent.Rgb;
3134+
<< "\n Colour Format: " << WStringToString(ColourFormat);
30053135
}
30063136

30073137
vddlog("d", logStream.str().c_str());
@@ -3062,7 +3192,7 @@ NTSTATUS VirtualDisplayDriverEvtIddCxMonitorQueryTargetModes2(
30623192
{
30633193
logStream << "\n TargetModeIndex: " << i
30643194
<< "\n Size: " << TargetModes[i].Size
3065-
<< "\n BitsPerComponent.Rgb: " << TargetModes[i].BitsPerComponent.Rgb;
3195+
<< "\n ColourFormat: " << WStringToString(ColourFormat);
30663196
}
30673197
vddlog("d", logStream.str().c_str());
30683198
}

Virtual Display Driver (HDR)/vdd_settings.xml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@
4848
<CustomEdid>false</CustomEdid> <!-- Custom Edid should be named "user_edid.bin"! This does not support emulating resolutions!-->
4949
<PreventSpoof>false</PreventSpoof> <!--Enable this to prevent manufacturer spoofing when using custom edid. Please only do so if you need to!-->
5050
<EdidCeaOverride>false</EdidCeaOverride> <!--Enable this to override or add hard coded cea-extension block to custom Edid support allowing you to enable HDR-->
51-
<SDR10bit>false</SDR10bit>
52-
<HDRPlus>false</HDRPlus> <!-- If you have SDR10 bit enabled, HDRPlus wont work - there’s a conflict because the display system cannot simultaneously handle both high dynamic range 12-bit and standard dynamic range 10-bit settings. -->
5351
<logging>false</logging>
5452
<!-- DEBUG LOGGING FOR EXPERTS ONLY!-->
5553
<debuglogging>false</debuglogging>
@@ -72,4 +70,18 @@
7270
3 = IDDCX_XOR_CURSOR_SUPPORT_EMULATION
7371
-->
7472
</cursor>
73+
<colour>
74+
<SDR10bit>false</SDR10bit>
75+
<HDRPlus>false</HDRPlus> <!-- If you have SDR10 bit enabled, HDRPlus wont work - there’s a conflict because the display system cannot simultaneously handle both high dynamic range 12-bit and standard dynamic range 10-bit settings. -->
76+
<ColourFormat>RGB</ColourFormat>
77+
<!--
78+
Supported colour formats:
79+
RGB
80+
YCbCr444
81+
YCbCr422
82+
YCbCr420
83+
84+
Any invalid colour formats which are used will default to use RGB
85+
-->
86+
</colour>
7587
</vdd_settings>

0 commit comments

Comments
 (0)