mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-21 06:42:02 +00:00
[idd] hdr: correct virtual monitor capabilities
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
This commit is contained in:
@@ -36,7 +36,7 @@ static const UINT CTA_DATA_BLOCK_MAX_PAYLOAD_SIZE = 31;
|
|||||||
|
|
||||||
static const BYTE EDID_HEADER[8] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
|
static const BYTE EDID_HEADER[8] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
|
||||||
|
|
||||||
static const WORD EDID_MANUFACTURER_ID_LGD = 0xe430;
|
static const WORD EDID_MANUFACTURER_ID_LGD = 0x30e4;
|
||||||
static const WORD EDID_PRODUCT_CODE = 0x1ddd;
|
static const WORD EDID_PRODUCT_CODE = 0x1ddd;
|
||||||
static const BYTE EDID_SERIAL_NUMBER[4] = { 0x01, 0x00, 0x00, 0x00 };
|
static const BYTE EDID_SERIAL_NUMBER[4] = { 0x01, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
@@ -45,35 +45,29 @@ static const BYTE EDID_MANUFACTURE_YEAR_2026 = 36; // 1990 + 36 = 2026
|
|||||||
static const BYTE EDID_VERSION = 1;
|
static const BYTE EDID_VERSION = 1;
|
||||||
static const BYTE EDID_REVISION = 4;
|
static const BYTE EDID_REVISION = 4;
|
||||||
|
|
||||||
static const BYTE EDID_VIDEO_INPUT_DIGITAL_8BPC_HDMI_A = 0xa2;
|
static const BYTE EDID_VIDEO_INPUT_DIGITAL_8BPC = 0xa0;
|
||||||
static const BYTE EDID_VIDEO_INPUT_DIGITAL_10BPC_HDMI_A = 0xb2;
|
static const BYTE EDID_VIDEO_INPUT_DIGITAL_10BPC = 0xb0;
|
||||||
static const BYTE EDID_HORIZONTAL_SIZE_CM = 52;
|
static const BYTE EDID_DISPLAY_GAMMA_2_2 = 0x78;
|
||||||
static const BYTE EDID_VERTICAL_SIZE_CM = 29;
|
static const BYTE EDID_FEATURES_PREFERRED_TIMING_RGB = 0x0a;
|
||||||
static const BYTE EDID_DISPLAY_GAMMA_2_2 = 0x78;
|
static const BYTE EDID_FEATURES_PREFERRED_TIMING_SRGB = 0x0e;
|
||||||
static const BYTE EDID_FEATURES_PREFERRED_TIMING_RGB = 0x0a;
|
|
||||||
|
|
||||||
static const BYTE EDID_STANDARD_TIMING_UNUSED_X = 0x01;
|
static const BYTE EDID_STANDARD_TIMING_UNUSED_X = 0x01;
|
||||||
static const BYTE EDID_STANDARD_TIMING_UNUSED_AR_REFRESH = 0x01;
|
static const BYTE EDID_STANDARD_TIMING_UNUSED_AR_REFRESH = 0x01;
|
||||||
|
|
||||||
static const DWORD EDID_IMAGE_WIDTH_MM = 520;
|
|
||||||
static const DWORD EDID_IMAGE_HEIGHT_MM = 290;
|
|
||||||
|
|
||||||
static const BYTE EDID_DESCRIPTOR_MONITOR_NAME = 0xfc;
|
static const BYTE EDID_DESCRIPTOR_MONITOR_NAME = 0xfc;
|
||||||
static const BYTE EDID_DTD_FLAGS_DIGITAL_SEPARATE_SYNC_POSITIVE = 0x1e;
|
static const BYTE EDID_DTD_FLAGS_DIGITAL_SEPARATE_SYNC_POSITIVE = 0x1e;
|
||||||
|
|
||||||
static const BYTE CTA_EXTENSION_TAG = 0x02;
|
static const BYTE CTA_EXTENSION_TAG = 0x02;
|
||||||
static const BYTE CTA_REVISION = 0x03;
|
static const BYTE CTA_REVISION = 0x03;
|
||||||
|
|
||||||
static const BYTE CTA_DATA_BLOCK_TAG_VENDOR_SPECIFIC = 0x03;
|
static const BYTE CTA_DATA_BLOCK_TAG_EXTENDED = 0x07;
|
||||||
static const BYTE CTA_DATA_BLOCK_TAG_EXTENDED = 0x07;
|
static const BYTE CTA_DATA_BLOCK_LENGTH_MASK = 0x1f;
|
||||||
static const BYTE CTA_DATA_BLOCK_LENGTH_MASK = 0x1f;
|
|
||||||
|
|
||||||
static const BYTE CTA_EXTENDED_TAG_COLORIMETRY = 0x05;
|
static const BYTE CTA_EXTENDED_TAG_COLORIMETRY = 0x05;
|
||||||
static const BYTE CTA_EXTENDED_TAG_HDR_STATIC_METADATA = 0x06;
|
static const BYTE CTA_EXTENDED_TAG_HDR_STATIC_METADATA = 0x06;
|
||||||
|
|
||||||
static const BYTE CTA_HDR_EOTF_TRADITIONAL_SDR = (BYTE)(1 << 0);
|
static const BYTE CTA_HDR_EOTF_TRADITIONAL_SDR = (BYTE)(1 << 0);
|
||||||
static const BYTE CTA_HDR_EOTF_SMPTE_ST_2084 = (BYTE)(1 << 2);
|
static const BYTE CTA_HDR_EOTF_SMPTE_ST_2084 = (BYTE)(1 << 2);
|
||||||
static const BYTE CTA_HDR_EOTF_HLG = (BYTE)(1 << 3);
|
|
||||||
static const BYTE CTA_HDR_STATIC_METADATA_TYPE_1 = (BYTE)(1 << 0);
|
static const BYTE CTA_HDR_STATIC_METADATA_TYPE_1 = (BYTE)(1 << 0);
|
||||||
// The virtual display is a transport rather than a physical light-emitting
|
// The virtual display is a transport rather than a physical light-emitting
|
||||||
// device. Advertise the complete PQ range so Windows preserves HDR content
|
// device. Advertise the complete PQ range so Windows preserves HDR content
|
||||||
@@ -85,24 +79,7 @@ static const BYTE CTA_HDR_DESIRED_MAX_LUMINANCE = 245;
|
|||||||
static const BYTE CTA_HDR_DESIRED_MAX_FRAME_AVG_LUMINANCE = 245;
|
static const BYTE CTA_HDR_DESIRED_MAX_FRAME_AVG_LUMINANCE = 245;
|
||||||
static const BYTE CTA_HDR_DESIRED_MIN_LUMINANCE = 0;
|
static const BYTE CTA_HDR_DESIRED_MIN_LUMINANCE = 0;
|
||||||
|
|
||||||
static const BYTE CTA_COLORIMETRY_OPYCC_601 = (BYTE)(1 << 3);
|
|
||||||
static const BYTE CTA_COLORIMETRY_OPRGB = (BYTE)(1 << 4);
|
|
||||||
static const BYTE CTA_COLORIMETRY_BT2020_YCC = (BYTE)(1 << 6);
|
|
||||||
static const BYTE CTA_COLORIMETRY_BT2020_RGB = (BYTE)(1 << 7);
|
static const BYTE CTA_COLORIMETRY_BT2020_RGB = (BYTE)(1 << 7);
|
||||||
static const BYTE CTA_COLORIMETRY_DCI_P3 = (BYTE)(1 << 7);
|
|
||||||
|
|
||||||
static const BYTE CTA_HDMI_FORUM_OUI [3] = { 0xd8, 0x5d, 0xc4 };
|
|
||||||
static const BYTE CTA_HDMI_LICENSING_OUI[3] = { 0x03, 0x0c, 0x00 };
|
|
||||||
|
|
||||||
static const BYTE CTA_HDMI_FORUM_VERSION_1 = 0x01;
|
|
||||||
static const BYTE CTA_HDMI_FORUM_MAX_TMDS_CHARACTER_RATE = 0x6e;
|
|
||||||
static const BYTE CTA_HDMI_FORUM_SCDC_PRESENT = 0x80;
|
|
||||||
|
|
||||||
static const BYTE CTA_HDMI_PHYSICAL_ADDRESS_A_B = 0x00;
|
|
||||||
static const BYTE CTA_HDMI_PHYSICAL_ADDRESS_C_D = 0x00;
|
|
||||||
static const BYTE CTA_HDMI_DEEP_COLOR_30_36 = 0x30;
|
|
||||||
static const BYTE CTA_HDMI_MAX_TMDS_CLOCK_UNSPECIFIED = 0x00;
|
|
||||||
static const BYTE CTA_HDMI_LATENCY_FIELDS_NONE = 0x0b;
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct EdidLe16
|
struct EdidLe16
|
||||||
@@ -111,6 +88,12 @@ struct EdidLe16
|
|||||||
BYTE hi;
|
BYTE hi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EdidBe16
|
||||||
|
{
|
||||||
|
BYTE hi;
|
||||||
|
BYTE lo;
|
||||||
|
};
|
||||||
|
|
||||||
struct EdidStandardTiming
|
struct EdidStandardTiming
|
||||||
{
|
{
|
||||||
BYTE horizontalActivePixels;
|
BYTE horizontalActivePixels;
|
||||||
@@ -163,7 +146,7 @@ struct EdidBaseBlock
|
|||||||
{
|
{
|
||||||
BYTE header[8];
|
BYTE header[8];
|
||||||
|
|
||||||
EdidLe16 manufacturerId;
|
EdidBe16 manufacturerId;
|
||||||
EdidLe16 productCode;
|
EdidLe16 productCode;
|
||||||
BYTE serialNumber[4];
|
BYTE serialNumber[4];
|
||||||
|
|
||||||
@@ -222,29 +205,10 @@ struct CtaColorimetryDataBlock
|
|||||||
BYTE metadataAndAdditionalColorimetry;
|
BYTE metadataAndAdditionalColorimetry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CtaHdmiForumVendorSpecificDataBlock
|
|
||||||
{
|
|
||||||
CtaDataBlockHeader header;
|
|
||||||
BYTE ieeeOui[3];
|
|
||||||
BYTE version;
|
|
||||||
BYTE maxTmdsCharacterRate;
|
|
||||||
BYTE flags;
|
|
||||||
BYTE reserved;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CtaHdmiVendorSpecificDataBlock
|
|
||||||
{
|
|
||||||
CtaDataBlockHeader header;
|
|
||||||
BYTE ieeeOui[3];
|
|
||||||
BYTE physicalAddressAB;
|
|
||||||
BYTE physicalAddressCD;
|
|
||||||
BYTE flags;
|
|
||||||
BYTE maxTmdsClock;
|
|
||||||
BYTE latencyFields;
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
static_assert(sizeof(EdidLe16) == 2, "Unexpected EDID little-endian word size");
|
static_assert(sizeof(EdidLe16) == 2, "Unexpected EDID little-endian word size");
|
||||||
|
static_assert(sizeof(EdidBe16) == 2, "Unexpected EDID big-endian word size");
|
||||||
static_assert(sizeof(EdidStandardTiming) == 2, "Unexpected EDID standard timing size");
|
static_assert(sizeof(EdidStandardTiming) == 2, "Unexpected EDID standard timing size");
|
||||||
static_assert(sizeof(EdidDetailedTimingDescriptor) == EDID_DTD_SIZE,
|
static_assert(sizeof(EdidDetailedTimingDescriptor) == EDID_DTD_SIZE,
|
||||||
"Unexpected EDID detailed timing descriptor size");
|
"Unexpected EDID detailed timing descriptor size");
|
||||||
@@ -261,17 +225,17 @@ static_assert(sizeof(CtaHdrStaticMetadataDataBlock) == 7,
|
|||||||
"Unexpected HDR static metadata data block size");
|
"Unexpected HDR static metadata data block size");
|
||||||
static_assert(sizeof(CtaColorimetryDataBlock) == 4,
|
static_assert(sizeof(CtaColorimetryDataBlock) == 4,
|
||||||
"Unexpected colorimetry data block size");
|
"Unexpected colorimetry data block size");
|
||||||
static_assert(sizeof(CtaHdmiForumVendorSpecificDataBlock) == 8,
|
|
||||||
"Unexpected HDMI Forum VSDB size");
|
|
||||||
static_assert(sizeof(CtaHdmiVendorSpecificDataBlock) == 9,
|
|
||||||
"Unexpected HDMI VSDB size");
|
|
||||||
static_assert(CTA_HEADER_SIZE +
|
static_assert(CTA_HEADER_SIZE +
|
||||||
sizeof(CtaHdrStaticMetadataDataBlock) +
|
sizeof(CtaHdrStaticMetadataDataBlock) +
|
||||||
sizeof(CtaColorimetryDataBlock) +
|
sizeof(CtaColorimetryDataBlock) <= EDID_BLOCK_SIZE - 1,
|
||||||
sizeof(CtaHdmiForumVendorSpecificDataBlock) +
|
|
||||||
sizeof(CtaHdmiVendorSpecificDataBlock) <= EDID_BLOCK_SIZE - 1,
|
|
||||||
"CTA data blocks exceed extension block space");
|
"CTA data blocks exceed extension block space");
|
||||||
|
|
||||||
|
static void SetBe16(EdidBe16& dst, DWORD value)
|
||||||
|
{
|
||||||
|
dst.hi = (BYTE)((value >> 8) & 0xff);
|
||||||
|
dst.lo = (BYTE)(value & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
static void SetLe16(EdidLe16& dst, DWORD value)
|
static void SetLe16(EdidLe16& dst, DWORD value)
|
||||||
{
|
{
|
||||||
dst.lo = (BYTE)(value & 0xff);
|
dst.lo = (BYTE)(value & 0xff);
|
||||||
@@ -316,11 +280,9 @@ static EdidStandardTiming MakeUnusedStandardTiming()
|
|||||||
return timing;
|
return timing;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <algorithm> // Ensure this header is included for std::min and std::max
|
|
||||||
|
|
||||||
static WORD EdidChromaticity(double value)
|
static WORD EdidChromaticity(double value)
|
||||||
{
|
{
|
||||||
return (WORD)min(1023.0, max(0.0, value * 1024.0 + 0.5));
|
return (WORD)min(1023.0, max(0.0, value * 1024.0 + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetChromaticityCoordinates(BYTE coordinates[10], bool hdr)
|
static void SetChromaticityCoordinates(BYTE coordinates[10], bool hdr)
|
||||||
@@ -350,27 +312,36 @@ static void SetChromaticityCoordinates(BYTE coordinates[10], bool hdr)
|
|||||||
coordinates[9] = (BYTE)(wy >> 2);
|
coordinates[9] = (BYTE)(wy >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BYTE GetVideoInputDefinition(bool hdr)
|
||||||
|
{
|
||||||
|
return hdr ?
|
||||||
|
EDID_VIDEO_INPUT_DIGITAL_10BPC :
|
||||||
|
EDID_VIDEO_INPUT_DIGITAL_8BPC;
|
||||||
|
}
|
||||||
|
|
||||||
static void InitEdidBaseBlock(EdidBaseBlock& base, bool hdr)
|
static void InitEdidBaseBlock(EdidBaseBlock& base, bool hdr)
|
||||||
{
|
{
|
||||||
memcpy(base.header, EDID_HEADER, sizeof(base.header));
|
memcpy(base.header, EDID_HEADER, sizeof(base.header));
|
||||||
|
|
||||||
// Manufacturer ID: LGD, product/serial values are arbitrary.
|
// Manufacturer ID: LGD, product/serial values identify the virtual monitor.
|
||||||
SetLe16(base.manufacturerId, EDID_MANUFACTURER_ID_LGD);
|
SetBe16(base.manufacturerId, EDID_MANUFACTURER_ID_LGD);
|
||||||
SetLe16(base.productCode, EDID_PRODUCT_CODE);
|
SetLe16(base.productCode , EDID_PRODUCT_CODE);
|
||||||
memcpy(base.serialNumber, EDID_SERIAL_NUMBER, sizeof(base.serialNumber));
|
memcpy (base.serialNumber , EDID_SERIAL_NUMBER, sizeof(base.serialNumber));
|
||||||
|
|
||||||
base.manufactureWeek = EDID_MANUFACTURE_WEEK;
|
base.manufactureWeek = EDID_MANUFACTURE_WEEK;
|
||||||
base.manufactureYear = EDID_MANUFACTURE_YEAR_2026;
|
base.manufactureYear = EDID_MANUFACTURE_YEAR_2026;
|
||||||
base.version = EDID_VERSION;
|
base.version = EDID_VERSION;
|
||||||
base.revision = EDID_REVISION;
|
base.revision = EDID_REVISION;
|
||||||
|
|
||||||
base.videoInputDefinition = hdr ?
|
base.videoInputDefinition = GetVideoInputDefinition(hdr);
|
||||||
EDID_VIDEO_INPUT_DIGITAL_10BPC_HDMI_A :
|
// This is a transport endpoint rather than a physical panel, so leave its
|
||||||
EDID_VIDEO_INPUT_DIGITAL_8BPC_HDMI_A;
|
// physical dimensions unspecified instead of imposing a false DPI/aspect.
|
||||||
base.horizontalSizeCm = EDID_HORIZONTAL_SIZE_CM;
|
base.horizontalSizeCm = 0;
|
||||||
base.verticalSizeCm = EDID_VERTICAL_SIZE_CM;
|
base.verticalSizeCm = 0;
|
||||||
base.displayGamma = EDID_DISPLAY_GAMMA_2_2;
|
base.displayGamma = EDID_DISPLAY_GAMMA_2_2;
|
||||||
base.supportedFeatures = EDID_FEATURES_PREFERRED_TIMING_RGB;
|
base.supportedFeatures = hdr ?
|
||||||
|
EDID_FEATURES_PREFERRED_TIMING_RGB :
|
||||||
|
EDID_FEATURES_PREFERRED_TIMING_SRGB;
|
||||||
SetChromaticityCoordinates(base.chromaticityCoordinates, hdr);
|
SetChromaticityCoordinates(base.chromaticityCoordinates, hdr);
|
||||||
|
|
||||||
for (UINT i = 0; i < EDID_STANDARD_TIMING_COUNT; ++i)
|
for (UINT i = 0; i < EDID_STANDARD_TIMING_COUNT; ++i)
|
||||||
@@ -379,68 +350,84 @@ static void InitEdidBaseBlock(EdidBaseBlock& base, bool hdr)
|
|||||||
base.extensionBlockCount = 1;
|
base.extensionBlockCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool MakeDetailedTiming(
|
bool CEdid::GetTiming(Timing& timing, const CSettings::DisplayMode& mode)
|
||||||
EdidDetailedTimingDescriptor& timing,
|
|
||||||
const CSettings::DisplayMode& mode)
|
|
||||||
{
|
{
|
||||||
memset(&timing, 0, sizeof(timing));
|
timing = {};
|
||||||
|
|
||||||
const DWORD hActive = mode.width;
|
timing.hActive = mode.width;
|
||||||
const DWORD vActive = mode.height;
|
timing.vActive = mode.height;
|
||||||
const DWORD refresh = mode.refresh;
|
|
||||||
|
|
||||||
if (hActive == 0 || vActive == 0 || refresh == 0 ||
|
if (timing.hActive == 0 || timing.vActive == 0 || mode.refresh == 0)
|
||||||
hActive > 4095 || vActive > 4095)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DWORD hBlank = std::max<DWORD>(160, ((hActive / 20) + 7) & ~7UL);
|
timing.hBlank = std::max<DWORD>(160,
|
||||||
DWORD vBlank = std::max<DWORD>(30, vActive / 20);
|
((timing.hActive / 20) + 7) & ~7UL);
|
||||||
if (hBlank > 4095 || vBlank > 4095)
|
timing.vBlank = std::max<DWORD>(30, timing.vActive / 20);
|
||||||
return false;
|
|
||||||
|
|
||||||
DWORD hSync = std::max<DWORD>(32, hActive / 100);
|
timing.hSync = std::max<DWORD>(32, timing.hActive / 100);
|
||||||
hSync = (hSync + 7) & ~7UL;
|
timing.hSync = (timing.hSync + 7) & ~7UL;
|
||||||
|
|
||||||
DWORD hFront = std::max<DWORD>(48, hBlank / 3);
|
timing.hFront = std::max<DWORD>(48, timing.hBlank / 3);
|
||||||
hFront = (hFront + 7) & ~7UL;
|
timing.hFront = (timing.hFront + 7) & ~7UL;
|
||||||
|
|
||||||
if (hFront + hSync >= hBlank)
|
if (timing.hFront + timing.hSync >= timing.hBlank)
|
||||||
{
|
{
|
||||||
hFront = 48;
|
timing.hFront = 48;
|
||||||
hSync = 32;
|
timing.hSync = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DWORD vFront = 3;
|
timing.vFront = 3;
|
||||||
const DWORD vSync = 5;
|
timing.vSync = 5;
|
||||||
if (vFront + vSync >= vBlank)
|
if (timing.vFront + timing.vSync >= timing.vBlank)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const UINT64 pixelClock = (UINT64)(hActive + hBlank) *
|
const UINT64 pixelClock =
|
||||||
(UINT64)(vActive + vBlank) * (UINT64)refresh;
|
(UINT64)(timing.hActive + timing.hBlank) *
|
||||||
|
(UINT64)(timing.vActive + timing.vBlank) *
|
||||||
|
(UINT64)mode.refresh;
|
||||||
const UINT64 pixelClock10KHz = (pixelClock + 5000) / 10000;
|
const UINT64 pixelClock10KHz = (pixelClock + 5000) / 10000;
|
||||||
|
timing.pixelClock = pixelClock10KHz * 10000;
|
||||||
|
return timing.pixelClock != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool MakeDetailedTiming(
|
||||||
|
EdidDetailedTimingDescriptor& descriptor,
|
||||||
|
const CSettings::DisplayMode& mode)
|
||||||
|
{
|
||||||
|
memset(&descriptor, 0, sizeof(descriptor));
|
||||||
|
|
||||||
|
CEdid::Timing timing;
|
||||||
|
if (!CEdid::GetTiming(timing, mode) ||
|
||||||
|
timing.hActive > 4095 || timing.vActive > 4095 ||
|
||||||
|
timing.hBlank > 4095 || timing.vBlank > 4095)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const UINT64 pixelClock10KHz = timing.pixelClock / 10000;
|
||||||
if (pixelClock10KHz == 0 || pixelClock10KHz > 0xffff)
|
if (pixelClock10KHz == 0 || pixelClock10KHz > 0xffff)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SetLe16(timing.pixelClock10KHz, (DWORD)pixelClock10KHz);
|
SetLe16(descriptor.pixelClock10KHz, (DWORD)pixelClock10KHz);
|
||||||
|
|
||||||
timing.hActiveLo = Lo8(hActive);
|
descriptor.hActiveLo = Lo8(timing.hActive);
|
||||||
timing.hBlankLo = Lo8(hBlank);
|
descriptor.hBlankLo = Lo8(timing.hBlank);
|
||||||
timing.hActiveBlankHi = PackMsbNibbles(hActive, hBlank);
|
descriptor.hActiveBlankHi = PackMsbNibbles(timing.hActive, timing.hBlank);
|
||||||
|
|
||||||
timing.vActiveLo = Lo8(vActive);
|
descriptor.vActiveLo = Lo8(timing.vActive);
|
||||||
timing.vBlankLo = Lo8(vBlank);
|
descriptor.vBlankLo = Lo8(timing.vBlank);
|
||||||
timing.vActiveBlankHi = PackMsbNibbles(vActive, vBlank);
|
descriptor.vActiveBlankHi = PackMsbNibbles(timing.vActive, timing.vBlank);
|
||||||
|
|
||||||
timing.hFrontPorchLo = Lo8(hFront);
|
descriptor.hFrontPorchLo = Lo8(timing.hFront);
|
||||||
timing.hSyncPulseWidthLo = Lo8(hSync);
|
descriptor.hSyncPulseWidthLo = Lo8(timing.hSync);
|
||||||
timing.vFrontPorchSyncPulseWidthLo = PackLowNibbles(vFront, vSync);
|
descriptor.vFrontPorchSyncPulseWidthLo =
|
||||||
timing.syncPorchPulseWidthHi = PackSyncPorchPulseWidthHi(hFront, hSync, vFront, vSync);
|
PackLowNibbles(timing.vFront, timing.vSync);
|
||||||
|
descriptor.syncPorchPulseWidthHi = PackSyncPorchPulseWidthHi(
|
||||||
|
timing.hFront, timing.hSync, timing.vFront, timing.vSync);
|
||||||
|
|
||||||
timing.imageWidthMmLo = Lo8(EDID_IMAGE_WIDTH_MM);
|
descriptor.imageWidthMmLo = 0;
|
||||||
timing.imageHeightMmLo = Lo8(EDID_IMAGE_HEIGHT_MM);
|
descriptor.imageHeightMmLo = 0;
|
||||||
timing.imageSizeMmHi = PackMsbNibbles(EDID_IMAGE_WIDTH_MM, EDID_IMAGE_HEIGHT_MM);
|
descriptor.imageSizeMmHi = 0;
|
||||||
|
|
||||||
timing.flags = EDID_DTD_FLAGS_DIGITAL_SEPARATE_SYNC_POSITIVE;
|
descriptor.flags = EDID_DTD_FLAGS_DIGITAL_SEPARATE_SYNC_POSITIVE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,8 +486,7 @@ static CtaHdrStaticMetadataDataBlock MakeCtaHdrStaticMetadataDataBlock()
|
|||||||
block.extendedTag = CTA_EXTENDED_TAG_HDR_STATIC_METADATA;
|
block.extendedTag = CTA_EXTENDED_TAG_HDR_STATIC_METADATA;
|
||||||
block.eotf = (BYTE)(
|
block.eotf = (BYTE)(
|
||||||
CTA_HDR_EOTF_TRADITIONAL_SDR |
|
CTA_HDR_EOTF_TRADITIONAL_SDR |
|
||||||
CTA_HDR_EOTF_SMPTE_ST_2084 |
|
CTA_HDR_EOTF_SMPTE_ST_2084);
|
||||||
CTA_HDR_EOTF_HLG);
|
|
||||||
|
|
||||||
block.staticMetadataDescriptor = CTA_HDR_STATIC_METADATA_TYPE_1;
|
block.staticMetadataDescriptor = CTA_HDR_STATIC_METADATA_TYPE_1;
|
||||||
block.desiredContentMaxLuminance = CTA_HDR_DESIRED_MAX_LUMINANCE;
|
block.desiredContentMaxLuminance = CTA_HDR_DESIRED_MAX_LUMINANCE;
|
||||||
@@ -515,41 +501,9 @@ static CtaColorimetryDataBlock MakeCtaColorimetryDataBlock()
|
|||||||
|
|
||||||
block.header = MakeCtaDataBlockHeader(CTA_DATA_BLOCK_TAG_EXTENDED,
|
block.header = MakeCtaDataBlockHeader(CTA_DATA_BLOCK_TAG_EXTENDED,
|
||||||
(UINT)(sizeof(block) - sizeof(block.header)));
|
(UINT)(sizeof(block) - sizeof(block.header)));
|
||||||
block.extendedTag = CTA_EXTENDED_TAG_COLORIMETRY;
|
block.extendedTag = CTA_EXTENDED_TAG_COLORIMETRY;
|
||||||
block.colorimetry = (BYTE)(CTA_COLORIMETRY_OPYCC_601 |
|
block.colorimetry = CTA_COLORIMETRY_BT2020_RGB;
|
||||||
CTA_COLORIMETRY_OPRGB |
|
block.metadataAndAdditionalColorimetry = 0;
|
||||||
CTA_COLORIMETRY_BT2020_YCC |
|
|
||||||
CTA_COLORIMETRY_BT2020_RGB);
|
|
||||||
block.metadataAndAdditionalColorimetry = CTA_COLORIMETRY_DCI_P3;
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CtaHdmiForumVendorSpecificDataBlock MakeCtaHdmiForumVendorSpecificDataBlock()
|
|
||||||
{
|
|
||||||
CtaHdmiForumVendorSpecificDataBlock block = {};
|
|
||||||
|
|
||||||
block.header = MakeCtaDataBlockHeader(CTA_DATA_BLOCK_TAG_VENDOR_SPECIFIC,
|
|
||||||
(UINT)(sizeof(block) - sizeof(block.header)));
|
|
||||||
memcpy(block.ieeeOui, CTA_HDMI_FORUM_OUI, sizeof(block.ieeeOui));
|
|
||||||
block.version = CTA_HDMI_FORUM_VERSION_1;
|
|
||||||
block.maxTmdsCharacterRate = CTA_HDMI_FORUM_MAX_TMDS_CHARACTER_RATE;
|
|
||||||
block.flags = CTA_HDMI_FORUM_SCDC_PRESENT;
|
|
||||||
block.reserved = 0x00;
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CtaHdmiVendorSpecificDataBlock MakeCtaHdmiVendorSpecificDataBlock()
|
|
||||||
{
|
|
||||||
CtaHdmiVendorSpecificDataBlock block = {};
|
|
||||||
|
|
||||||
block.header = MakeCtaDataBlockHeader(CTA_DATA_BLOCK_TAG_VENDOR_SPECIFIC,
|
|
||||||
(UINT)(sizeof(block) - sizeof(block.header)));
|
|
||||||
memcpy(block.ieeeOui, CTA_HDMI_LICENSING_OUI, sizeof(block.ieeeOui));
|
|
||||||
block.physicalAddressAB = CTA_HDMI_PHYSICAL_ADDRESS_A_B;
|
|
||||||
block.physicalAddressCD = CTA_HDMI_PHYSICAL_ADDRESS_C_D;
|
|
||||||
block.flags = CTA_HDMI_DEEP_COLOR_30_36;
|
|
||||||
block.maxTmdsClock = CTA_HDMI_MAX_TMDS_CLOCK_UNSPECIFIED;
|
|
||||||
block.latencyFields = CTA_HDMI_LATENCY_FIELDS_NONE;
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,7 +536,10 @@ bool CEdid::WriteDetailedTiming(BYTE* dtd, const CSettings::DisplayMode& mode)
|
|||||||
|
|
||||||
void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr)
|
void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr)
|
||||||
{
|
{
|
||||||
m_data.assign(static_cast<std::vector<BYTE, std::allocator<BYTE>>::size_type>(EDID_BLOCK_SIZE) * 2, 0);
|
m_data.assign(
|
||||||
|
static_cast<std::vector<BYTE, std::allocator<BYTE>>::size_type>(
|
||||||
|
EDID_BLOCK_SIZE) * 2,
|
||||||
|
0);
|
||||||
|
|
||||||
EdidBaseBlock baseBlock = {};
|
EdidBaseBlock baseBlock = {};
|
||||||
InitEdidBaseBlock(baseBlock, hdr);
|
InitEdidBaseBlock(baseBlock, hdr);
|
||||||
@@ -637,8 +594,6 @@ void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr)
|
|||||||
{
|
{
|
||||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdrStaticMetadataDataBlock ());
|
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdrStaticMetadataDataBlock ());
|
||||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaColorimetryDataBlock ());
|
AppendCtaDataBlock(cta, dataOffset, MakeCtaColorimetryDataBlock ());
|
||||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdmiForumVendorSpecificDataBlock());
|
|
||||||
AppendCtaDataBlock(cta, dataOffset, MakeCtaHdmiVendorSpecificDataBlock ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctaBlock.dtdOffset = (BYTE)dataOffset;
|
ctaBlock.dtdOffset = (BYTE)dataOffset;
|
||||||
|
|||||||
@@ -29,8 +29,24 @@
|
|||||||
class CEdid
|
class CEdid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Timing
|
||||||
|
{
|
||||||
|
DWORD hActive;
|
||||||
|
DWORD hBlank;
|
||||||
|
DWORD hFront;
|
||||||
|
DWORD hSync;
|
||||||
|
DWORD vActive;
|
||||||
|
DWORD vBlank;
|
||||||
|
DWORD vFront;
|
||||||
|
DWORD vSync;
|
||||||
|
UINT64 pixelClock;
|
||||||
|
};
|
||||||
|
|
||||||
void Build(const CSettings::DisplayModes& modes, bool hdr);
|
void Build(const CSettings::DisplayModes& modes, bool hdr);
|
||||||
|
|
||||||
|
static bool GetTiming(Timing& timing,
|
||||||
|
const CSettings::DisplayMode& mode);
|
||||||
|
|
||||||
const BYTE* Data() const { return m_data.empty() ? nullptr : m_data.data(); }
|
const BYTE* Data() const { return m_data.empty() ? nullptr : m_data.data(); }
|
||||||
UINT Size() const { return (UINT)m_data.size(); }
|
UINT Size() const { return (UINT)m_data.size(); }
|
||||||
|
|
||||||
|
|||||||
@@ -50,10 +50,13 @@ static const UINT IDDCX_VERSION_1_10 = 0x1A00;
|
|||||||
static inline IDDCX_WIRE_BITS_PER_COMPONENT GetWireBitsPerComponent(bool hdr)
|
static inline IDDCX_WIRE_BITS_PER_COMPONENT GetWireBitsPerComponent(bool hdr)
|
||||||
{
|
{
|
||||||
IDDCX_WIRE_BITS_PER_COMPONENT bits = {};
|
IDDCX_WIRE_BITS_PER_COMPONENT bits = {};
|
||||||
|
// This describes the virtual monitor wire, not the swap-chain format.
|
||||||
|
// HDR uses a 10-bpc PQ wire while CAN_PROCESS_FP16 requests the FP16/scRGB
|
||||||
|
// source surface that Looking Glass converts for transport.
|
||||||
bits.Rgb = IDDCX_BITS_PER_COMPONENT_8;
|
bits.Rgb = IDDCX_BITS_PER_COMPONENT_8;
|
||||||
if (hdr)
|
if (hdr)
|
||||||
bits.Rgb = (IDDCX_BITS_PER_COMPONENT)(bits.Rgb |
|
bits.Rgb = (IDDCX_BITS_PER_COMPONENT)(bits.Rgb |
|
||||||
IDDCX_BITS_PER_COMPONENT_10 | IDDCX_BITS_PER_COMPONENT_16);
|
IDDCX_BITS_PER_COMPONENT_10);
|
||||||
bits.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
bits.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
bits.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
bits.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
bits.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
bits.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
@@ -586,21 +589,28 @@ void CIndirectDeviceContext::OnSwapChainReady()
|
|||||||
g_pipe.SetDisplayMode(mode.width, mode.height, mode.refresh);
|
g_pipe.SetDisplayMode(mode.width, mode.height, mode.refresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void FillSignalInfo(DISPLAYCONFIG_VIDEO_SIGNAL_INFO & mode, DWORD width, DWORD height, DWORD vsync, bool monitorMode)
|
static inline void FillSignalInfo(DISPLAYCONFIG_VIDEO_SIGNAL_INFO& signal,
|
||||||
|
const CSettings::DisplayMode& mode, bool monitorMode)
|
||||||
{
|
{
|
||||||
mode.totalSize.cx = mode.activeSize.cx = width;
|
CEdid::Timing timing;
|
||||||
mode.totalSize.cy = mode.activeSize.cy = height;
|
if (!CEdid::GetTiming(timing, mode))
|
||||||
|
return;
|
||||||
|
|
||||||
mode.AdditionalSignalInfo.vSyncFreqDivider = monitorMode ? 0 : 1;
|
signal.activeSize.cx = timing.hActive;
|
||||||
mode.AdditionalSignalInfo.videoStandard = 255;
|
signal.activeSize.cy = timing.vActive;
|
||||||
|
signal.totalSize.cx = timing.hActive + timing.hBlank;
|
||||||
|
signal.totalSize.cy = timing.vActive + timing.vBlank;
|
||||||
|
|
||||||
mode.vSyncFreq.Numerator = vsync;
|
signal.AdditionalSignalInfo.vSyncFreqDivider = monitorMode ? 0 : 1;
|
||||||
mode.vSyncFreq.Denominator = 1;
|
signal.AdditionalSignalInfo.videoStandard = 255;
|
||||||
mode.hSyncFreq.Numerator = vsync * height;
|
|
||||||
mode.hSyncFreq.Denominator = 1;
|
|
||||||
|
|
||||||
mode.scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE;
|
signal.vSyncFreq.Numerator = mode.refresh;
|
||||||
mode.pixelRate = ((UINT64)vsync) * ((UINT64)width) * ((UINT64)height);
|
signal.vSyncFreq.Denominator = 1;
|
||||||
|
signal.hSyncFreq.Numerator = mode.refresh * signal.totalSize.cy;
|
||||||
|
signal.hSyncFreq.Denominator = 1;
|
||||||
|
|
||||||
|
signal.scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE;
|
||||||
|
signal.pixelRate = timing.pixelClock;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS CIndirectDeviceContext::ParseMonitorDescription(
|
NTSTATUS CIndirectDeviceContext::ParseMonitorDescription(
|
||||||
@@ -620,9 +630,9 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription(
|
|||||||
auto * mode = inArgs->pMonitorModes;
|
auto * mode = inArgs->pMonitorModes;
|
||||||
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
||||||
{
|
{
|
||||||
mode->Size = sizeof(IDDCX_MONITOR_MODE);
|
mode->Size = sizeof(IDDCX_MONITOR_MODE);
|
||||||
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
|
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
|
||||||
FillSignalInfo(mode->MonitorVideoSignalInfo, it->width, it->height, it->refresh, true);
|
FillSignalInfo(mode->MonitorVideoSignalInfo, *it, true);
|
||||||
|
|
||||||
if (it->preferred)
|
if (it->preferred)
|
||||||
outArgs->PreferredMonitorModeIdx =
|
outArgs->PreferredMonitorModeIdx =
|
||||||
@@ -649,9 +659,9 @@ NTSTATUS CIndirectDeviceContext::MonitorGetDefaultModes(
|
|||||||
auto* mode = inArgs->pDefaultMonitorModes;
|
auto* mode = inArgs->pDefaultMonitorModes;
|
||||||
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
||||||
{
|
{
|
||||||
mode->Size = sizeof(IDDCX_MONITOR_MODE);
|
mode->Size = sizeof(IDDCX_MONITOR_MODE);
|
||||||
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_DRIVER;
|
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_DRIVER;
|
||||||
FillSignalInfo(mode->MonitorVideoSignalInfo, it->width, it->height, it->refresh, true);
|
FillSignalInfo(mode->MonitorVideoSignalInfo, *it, true);
|
||||||
|
|
||||||
if (it->preferred)
|
if (it->preferred)
|
||||||
outArgs->PreferredMonitorModeIdx =
|
outArgs->PreferredMonitorModeIdx =
|
||||||
@@ -678,7 +688,7 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes(
|
|||||||
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
||||||
{
|
{
|
||||||
mode->Size = sizeof(IDDCX_TARGET_MODE);
|
mode->Size = sizeof(IDDCX_TARGET_MODE);
|
||||||
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
|
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, *it, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@@ -704,9 +714,9 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription2(
|
|||||||
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
|
||||||
{
|
{
|
||||||
ZeroMemory(mode, sizeof(*mode));
|
ZeroMemory(mode, sizeof(*mode));
|
||||||
mode->Size = sizeof(IDDCX_MONITOR_MODE2);
|
mode->Size = sizeof(IDDCX_MONITOR_MODE2);
|
||||||
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
|
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
|
||||||
FillSignalInfo(mode->MonitorVideoSignalInfo, it->width, it->height, it->refresh, true);
|
FillSignalInfo(mode->MonitorVideoSignalInfo, *it, true);
|
||||||
mode->BitsPerComponent = GetWireBitsPerComponent(CanProcessFP16());
|
mode->BitsPerComponent = GetWireBitsPerComponent(CanProcessFP16());
|
||||||
|
|
||||||
if (it->preferred)
|
if (it->preferred)
|
||||||
@@ -738,7 +748,7 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes2(
|
|||||||
{
|
{
|
||||||
ZeroMemory(mode, sizeof(*mode));
|
ZeroMemory(mode, sizeof(*mode));
|
||||||
mode->Size = sizeof(IDDCX_TARGET_MODE2);
|
mode->Size = sizeof(IDDCX_TARGET_MODE2);
|
||||||
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
|
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, *it, false);
|
||||||
mode->BitsPerComponent = GetWireBitsPerComponent(CanProcessFP16());
|
mode->BitsPerComponent = GetWireBitsPerComponent(CanProcessFP16());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -589,12 +589,12 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
|
|||||||
// No per-content metadata is active. Use reasonable internal defaults
|
// No per-content metadata is active. Use reasonable internal defaults
|
||||||
// without publishing the virtual monitor metadata downstream.
|
// without publishing the virtual monitor metadata downstream.
|
||||||
// BT.709/sRGB primaries (in 0.00002 units):
|
// BT.709/sRGB primaries (in 0.00002 units):
|
||||||
srcFormat.displayPrimary[0][0] = 13250; // Rx
|
srcFormat.displayPrimary[0][0] = 32000; // Rx
|
||||||
srcFormat.displayPrimary[0][1] = 34500; // Ry
|
srcFormat.displayPrimary[0][1] = 16500; // Ry
|
||||||
srcFormat.displayPrimary[1][0] = 7500; // Gx
|
srcFormat.displayPrimary[1][0] = 15000; // Gx
|
||||||
srcFormat.displayPrimary[1][1] = 30000; // Gy
|
srcFormat.displayPrimary[1][1] = 30000; // Gy
|
||||||
srcFormat.displayPrimary[2][0] = 34000; // Bx
|
srcFormat.displayPrimary[2][0] = 7500; // Bx
|
||||||
srcFormat.displayPrimary[2][1] = 16000; // By
|
srcFormat.displayPrimary[2][1] = 3000; // By
|
||||||
// D65 white point (in 0.00002 units):
|
// D65 white point (in 0.00002 units):
|
||||||
srcFormat.whitePoint[0] = 15635;
|
srcFormat.whitePoint[0] = 15635;
|
||||||
srcFormat.whitePoint[1] = 16450;
|
srcFormat.whitePoint[1] = 16450;
|
||||||
|
|||||||
@@ -104,23 +104,6 @@ NTSTATUS LGIddAdapterCommitModes(IDDCX_ADAPTER adapter, const IDARG_IN_COMMITMOD
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void FillSignalInfo(DISPLAYCONFIG_VIDEO_SIGNAL_INFO & mode, DWORD width, DWORD height, DWORD vsync, bool monitorMode)
|
|
||||||
{
|
|
||||||
mode.totalSize.cx = mode.activeSize.cx = width;
|
|
||||||
mode.totalSize.cy = mode.activeSize.cy = height;
|
|
||||||
|
|
||||||
mode.AdditionalSignalInfo.vSyncFreqDivider = monitorMode ? 0 : 1;
|
|
||||||
mode.AdditionalSignalInfo.videoStandard = 255;
|
|
||||||
|
|
||||||
mode.vSyncFreq.Numerator = vsync;
|
|
||||||
mode.vSyncFreq.Denominator = 1;
|
|
||||||
mode.hSyncFreq.Numerator = vsync * height;
|
|
||||||
mode.hSyncFreq.Denominator = 1;
|
|
||||||
|
|
||||||
mode.scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE;
|
|
||||||
mode.pixelRate = ((UINT64)vsync) * ((UINT64)width) * ((UINT64)height);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS LGIddParseMonitorDescription(const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs,
|
NTSTATUS LGIddParseMonitorDescription(const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs,
|
||||||
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
|
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
|
||||||
{
|
{
|
||||||
@@ -170,10 +153,8 @@ NTSTATUS LGIddAdapterQueryTargetInfo(IDDCX_ADAPTER adapter,
|
|||||||
(IDDCX_TARGET_CAPS)(IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE |
|
(IDDCX_TARGET_CAPS)(IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE |
|
||||||
IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE) :
|
IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE) :
|
||||||
(IDDCX_TARGET_CAPS)0;
|
(IDDCX_TARGET_CAPS)0;
|
||||||
outArgs->DitheringSupport.Rgb = hdr ?
|
|
||||||
(IDDCX_BITS_PER_COMPONENT)(IDDCX_BITS_PER_COMPONENT_8 |
|
outArgs->DitheringSupport.Rgb = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
IDDCX_BITS_PER_COMPONENT_10) :
|
|
||||||
IDDCX_BITS_PER_COMPONENT_8;
|
|
||||||
outArgs->DitheringSupport.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
outArgs->DitheringSupport.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
outArgs->DitheringSupport.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
outArgs->DitheringSupport.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
outArgs->DitheringSupport.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
outArgs->DitheringSupport.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
|
||||||
|
|||||||
Reference in New Issue
Block a user