NvAPIWrapper icon indicating copy to clipboard operation
NvAPIWrapper copied to clipboard

Reading EDID?

Open aounmike opened this issue 2 years ago • 2 comments

Thank you very much for your great work creating NvAPIWrapper. Among the many other things I'll be attempting to do, one of the first things I'm attempting to do is read EDIDs from connected DisplayPort and HDMI displays. I am using an RTX 3060. I am currently trying to read EDIDs from a 4K, 144kHz Acer monitor. The EDID has base EDID and two extension blocks on both the HDMI 2.1 port and the DisplayPort port. I first tried using your technique in I2CSample. When I use this technique, first reading the 128 base EDID and examining byte 126 to determine how many externsion blocks there are, it works greate for DisplayPort. After determining that there are two extension blocks, I call it again with a length of 384 and I am able to get the entire EDID. When I attempt to do the same while connected via HDMI 2.1, I don't get valid EDID data when reading the base EDID. When I use the same code to attempt to read the base EDID via the HDMI 2.1 port, I get 128 bytes of data that is just 00h, FFh, FFh, FFh, over and over through the entire 128 bytes. I then attempted to read the EDID using NvAPIWrapper.Native.GPUApi.GetEDID to do the task, but it seems that it is only able to return EDIDV3.MaxDataSize of 256 bytes. So I am not able to get all three blocks of EDID data. I am very much just getting started with your wrapper and I am very much stumbling around. Do you have any advice for me on how I can get all three blocks of the monitor's EDID via the HDMI 2.1 port? Thank you. -Mike

Edit: Here is what I am doing (I modified your I2CSample.I2CReadEDID to have a second parameter called number of blocks that just mulitplies the readDataLength parameter to be 128 * numOfBlocks).

        Dim Displays() As NvAPIWrapper.Display.Display = NvAPIWrapper.Display.Display.GetDisplays()
        Dim byts() As Byte = NVIDIA.I2CSample.I2CReadEDID(Displays(0).Output, 1)
        Dim numOfBlocks As UInteger = byts(126) + 1
        byts = NVIDIA.I2CSample.I2CReadEDID(Displays(0).Output, numOfBlocks)
        
        Works fine on DP, returns 00h, FFh, FFh, FFh, 00h, FFh, FFh, FFh, 00h... for the entire 128 bytes on HDMI 2.1.

aounmike avatar Dec 21 '21 18:12 aounmike

for I2C you need to read DDC documentations. I am not overly familiar with the specifics. isn't 00 FF FF FF the initial bytes to a valid EDID?

well, mine has only one extension block and so Nvidia call returns the full data. so I can't debug it. But you can try sending other offsets to see if it returns more info. check this following code (it is in c# of course) to see if it returns the full edid in your case:

            NVIDIA.Initialize();
            var gpu = PhysicalGPU.GetPhysicalGPUs().First();
            var displays = gpu.GetDisplayDevices();
            var output = displays[1].Output;

            var edid = GPUApi.GetEDID(gpu.Handle, output.OutputId, 0);
            var data = edid.Data.ToArray();
            var identification = edid.Identification;
            var totalSize = edid.TotalSize;
            var offset = edid.DataOffset;

            for (; (totalSize - offset) < totalSize; offset += EDIDV3.MaxDataSize)
            {
                edid = GPUApi.GetEDID(gpu.Handle, output.OutputId, offset, identification);
                if (edid.Identification != identification)
                {
                    // edid changed
                    throw new NotSupportedException();
                }

                totalSize = edid.TotalSize;
                offset = edid.DataOffset;
                var edidData = edid.Data;
                Array.Resize(ref data, data.Length + edidData.Length);
                Array.Copy(edidData, 0, data, data.Length - edidData.Length, edidData.Length);
            }

            var parsed = new EDID(data);

GetEDID is itself a wrapper over I2C, but it is made by NVidia so it should work.

falahati avatar Dec 22 '21 10:12 falahati

for I2C example try increasing the 100ms delay. Maybe DDC on HDMI is slower; just an idea

falahati avatar Dec 22 '21 10:12 falahati