All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Betschart <adrian.betschart@cinemaone.ch>
To: Harry Wentland <harry.wentland@amd.com>,
	Leo Li <sunpeng.li@amd.com>,
	Rodrigo Siqueira <siqueira@igalia.com>,
	Alex Deucher <alexander.deucher@amd.com>
Cc: "Christian König" <christian.koenig@amd.com>,
	amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 1/3] drm/amd/display: support HDMI 1.4 3D modes on HDMI connectors
Date: Mon,  7 Sep 2026 12:06:24 +0200	[thread overview]
Message-ID: <20260907100626.54465-2-adrian.betschart@cinemaone.ch> (raw)
In-Reply-To: <20260907100626.54465-1-adrian.betschart@cinemaone.ch>

Allow the stereo modes drm_edid derives from a sink's HDMI VSDB on
HDMI connectors, and drive them the way a 2D stream is driven: the
source (compositor or media player) lays both views out in the frame
itself - side by side, top and bottom, or the doubled frame-packing
timing with the 45-line active space between the eyes - and the only
3D-specific output is the HDMI vendor infoframe that tells the sink
how the frame is laid out.

Keep the DC timing at TIMING_3D_FORMAT_NONE for all of them. Any DC
stereo timing format, including the SW_PACKED variants, makes the
hardware treat the surface as two views: the pipe is split and both
view addresses point at the same surface, so the whole frame ends up
in each half of the output. The new vsif_3d_format stream field
carries the layout to mod_build_hf_vsif_infopacket() instead, so the
VSIF is right and stays right when the freesync code rebuilds it for
ALLM.

Frame packing needs the doubled CRTC timing; pass CRTC_STEREO_DOUBLE
wherever amdgpu_dm recomputes the CRTC fields itself.

Limit stereo_allowed to native HDMI connectors: on the DP-to-HDMI
converter paths link validation rejects the 3D timings.

Tested on a Radeon RX 7600 (DCN 3.2.1) driving a JVC DLA-RS4100
projector through an HDFury VRROOM, with Kodi rendering the packed
frames: frame packing, top-and-bottom and side-by-side at
1920x1080p24, RGB 12 bpc, all engage the projector's 3D mode with
correct per-eye geometry and eye assignment (checked with per-eye
test patterns through shutter glasses).

Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
---
 .../display/amdgpu_dm/amdgpu_dm_connector.c   | 41 +++++++++++++++++--
 drivers/gpu/drm/amd/display/dc/dc_stream.h    |  7 ++++
 .../display/modules/info_packet/info_packet.c |  3 ++
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index 0e71ba498..7a2beb175 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -851,6 +851,25 @@ STATIC_IFN_KUNIT bool adjust_colour_depth_from_display_info(
 }
 EXPORT_IF_KUNIT(adjust_colour_depth_from_display_info);
 
+/*
+ * 3D layout to announce in the HDMI vendor infoframe for a DRM 3D mode. The
+ * stream timing itself stays 2D (see fill_stream_properties_from_drm_display_mode).
+ */
+static enum dc_timing_3d_format amdgpu_dm_vsif_3d_format(unsigned int mode_flags)
+{
+	switch (mode_flags & DRM_MODE_FLAG_3D_MASK) {
+	case DRM_MODE_FLAG_3D_FRAME_PACKING:
+		return TIMING_3D_FORMAT_SW_FRAME_PACKING;
+	case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
+		return TIMING_3D_FORMAT_TB_SW_PACKED;
+	case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
+	case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
+		return TIMING_3D_FORMAT_SBS_SW_PACKED;
+	default:
+		return TIMING_3D_FORMAT_NONE;
+	}
+}
+
 STATIC_IFN_KUNIT void fill_stream_properties_from_drm_display_mode(
 	struct dc_stream_state *stream,
 	const struct drm_display_mode *mode_in,
@@ -887,7 +906,15 @@ STATIC_IFN_KUNIT void fill_stream_properties_from_drm_display_mode(
 	 */
 	timing_out->pixel_encoding = requested_encoding;
 
+	/*
+	 * The source packs both views into the frame itself (side-by-side,
+	 * top-and-bottom, or the doubled frame-packing timing), so the display
+	 * core scans it out as a plain 2D stream and only the HDMI vendor
+	 * infoframe tells the sink how the frame is laid out. Any DC stereo
+	 * timing format would make the hardware treat the surface as two views.
+	 */
 	timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
+	stream->vsif_3d_format = amdgpu_dm_vsif_3d_format(mode_in->flags);
 	timing_out->display_color_depth = amdgpu_dm_convert_color_depth_from_display_info(
 		connector,
 		(timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420),
@@ -1451,6 +1478,9 @@ create_stream_for_sink(struct drm_connector *connector,
 	struct dc_sink *sink = NULL;
 
 	drm_mode_init(&mode, drm_mode);
+	/* frame packing scans out both views plus the active space in one frame */
+	if (mode.flags & DRM_MODE_FLAG_3D_FRAME_PACKING)
+		drm_mode_set_crtcinfo(&mode, CRTC_STEREO_DOUBLE);
 	memset(&saved_mode, 0, sizeof(saved_mode));
 
 	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
@@ -1530,7 +1560,9 @@ create_stream_for_sink(struct drm_connector *connector,
 	}
 
 	if (recalculate_timing)
-		drm_mode_set_crtcinfo(&saved_mode, 0);
+		drm_mode_set_crtcinfo(&saved_mode,
+				      (saved_mode.flags & DRM_MODE_FLAG_3D_FRAME_PACKING) ?
+				      CRTC_STEREO_DOUBLE : 0);
 
 	/*
 	 * If scaling is enabled and refresh rate didn't change
@@ -2449,7 +2481,9 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
 	if (!test_mode)
 		goto fail;
 
-	drm_mode_set_crtcinfo(test_mode, 0);
+	drm_mode_set_crtcinfo(test_mode,
+			      (test_mode->flags & DRM_MODE_FLAG_3D_FRAME_PACKING) ?
+			      CRTC_STEREO_DOUBLE : 0);
 
 	stream = amdgpu_dm_create_validate_stream_for_sink(connector, test_mode,
 						 to_dm_connector_state(connector->state),
@@ -3143,7 +3177,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 	aconnector->dc_link = link;
 	aconnector->base.interlace_allowed = false;
 	aconnector->base.doublescan_allowed = false;
-	aconnector->base.stereo_allowed = false;
+	/* HDMI 1.4 3D only; DP-to-HDMI converters reject the timings in link validation */
+	aconnector->base.stereo_allowed = connector_type == DRM_MODE_CONNECTOR_HDMIA;
 	aconnector->base.dpms = DRM_MODE_DPMS_OFF;
 	aconnector->hpd.hpd = AMDGPU_HPD_NONE; /* not used */
 	aconnector->audio_inst = -1;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 934ae381e..e6fd75b87 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -235,6 +235,13 @@ struct dc_stream_state {
 
 	enum view_3d_format view_format;
 
+	/**
+	 * @vsif_3d_format: 3D layout announced in the HDMI vendor infoframe when
+	 * the source packs both views into the frame itself and the timing is
+	 * therefore left at TIMING_3D_FORMAT_NONE.
+	 */
+	enum dc_timing_3d_format vsif_3d_format;
+
 	bool use_vsc_sdp_for_colorimetry;
 	bool ignore_msa_timing_param;
 
diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
index 32b697f46..13478b8bd 100644
--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
+++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
@@ -536,6 +536,9 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
 		format = stream->timing.timing_3d_format;
 		if (stream->view_format == VIEW_3D_FORMAT_NONE)
 			format = TIMING_3D_FORMAT_NONE;
+		/* a 2D scanout of a frame the source packed itself */
+		if (format == TIMING_3D_FORMAT_NONE)
+			format = stream->vsif_3d_format;
 
 		if (stream->timing.hdmi_vic != 0
 				&& stream->timing.h_total >= 3840
-- 
2.43.0


  reply	other threads:[~2026-09-08  7:09 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-07 10:06 [PATCH 0/3] drm/amd/display: HDMI 1.4 3D output (frame packing, top-and-bottom, side-by-side) Adrian Betschart
2026-09-07 10:06 ` Adrian Betschart [this message]
2026-09-07 11:32   ` [PATCH 1/3] drm/amd/display: support HDMI 1.4 3D modes on HDMI connectors sashiko-bot
2026-09-07 10:06 ` [PATCH 2/3] drm/amd/display: send the 3D_Ext_Data byte for top-and-bottom too Adrian Betschart
2026-09-07 10:06 ` [PATCH 3/3] drm/amd/display: size frame-packed streams by the doubled timing Adrian Betschart
2026-09-07 11:27   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260907100626.54465-2-adrian.betschart@cinemaone.ch \
    --to=adrian.betschart@cinemaone.ch \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=harry.wentland@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=siqueira@igalia.com \
    --cc=sunpeng.li@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.