nvt: only parse per-VIC 3D entries when 3D_present is set - #1308
Open
clinche wants to merge 1 commit into
Open
Conversation
parseEdidHDMILLCTiming() ends with a loop that consumes the remaining bytes of the HDMI VSDB and interprets each one as an NVT_3D_MULTI_LIST entry. Unlike the two 3D parsing blocks above it, this loop is not guarded by pHDMIVideo->ThreeD_Present, so trailing reserved or padding bytes are treated as 3D mode descriptors. Because NVT_HDMI_3D_SUPPORTED_STRUCT_MASK(x) is 1 << x, any byte value yields a non-zero StereoStructureMask, including 0x00. A single padding byte is therefore enough to leave HDMI3DSupported set on a display whose VSDB advertises 3D_present = 0. The cost is user-visible: nvDpyIsHDRCapable() then returns FALSE, so atomic commits setting the DRM Colorspace property to BT2020_RGB or BT2020_YCC fail with EINVAL, and SendHDRInfoFrame() returns early, so the Dynamic Range and Mastering InfoFrame is never transmitted. HDR is either unavailable or appears to enable while the sink stays in SDR. Guard the loop the same way the preceding ones are.
This was referenced Aug 19, 2026
Collaborator
|
Thanks for the proposed patch. Could you please attach the EDID you used to test this? I'd like to step through this path. |
Author
|
I'm attaching 3 EDIDs, zipped together as github doesn't allow upload raw bin files:
To wrap it up:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes HDR being unavailable on HDMI displays whose Vendor Specific Data
Block ends with reserved or padding bytes.
The final loop in parseEdidHDMILLCTiming() is missing the
ThreeD_Present guard that the two preceding 3D parsing blocks have, so
it reinterprets leftover VSDB bytes as per-VIC 3D entries. Any byte
value sets a non-zero stereo mask, so HDMI3DSupported ends up set on
displays that advertise no 3D support at all.
This trips two gates: nvDpyIsHDRCapable() (EINVAL on any BT2020
Colorspace commit, with no kernel log at any debug level) and
SendHDRInfoFrame() (the DRM InfoFrame is never sent, so the display
stays in SDR while the compositor composites in PQ/BT2020).
This accounts for both failure modes people report. If HDR cannot
be enabled at all, it is the first gate. If HDR appears to enable
but the picture is washed out and the display stays in SDR, as
in #779, it is the second: the compositor composites in
PQ/BT2020 while the sink is never told to switch.
Reproducer: RTX 5080 (GB203), 610.57.04, kernel 7.1.8, KDE Plasma 6.7.4
Wayland, Acer XV322QK KV over HDMI. Its VSDB is 13 bytes and ends with
one padding byte after two HDMI VICs, with 3D_present = 0 and
HDMI_3D_Len = 0. The parser walk gives DataSz = 5 and DataCnt = 4, so
the loop runs once on the padding byte.
Verified by instrumenting nvDpyIsHDRCapable(): every condition passes
except hdmi3D. Independently confirmed on a stock driver by overriding
the EDID via drm.edid_firmware to widen HDMI_VIC_Len so the trailing
byte is consumed as an (ignored) HDMI VIC instead: HDR then enables and
the monitor leaves SDR.
Note that trailing reserved bytes in a VSDB are expected and are meant
to be ignored by parsers for forward compatibility, so this is likely
to affect a range of displays rather than one vendor's EDID.
A stricter variant would bound the loop by HDMI_3D_Len rather than
gating on ThreeD_Present, which would also cover displays that do
advertise 3D and have padding. I kept the change minimal and
symmetrical with the surrounding code; happy to switch if you prefer.