* [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support
@ 2025-02-13 13:25 Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 1/7] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged() Vinod Govindapillai
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
Dirty rect support for FBC in xe3 onwards based on the comments after the
initial RFC series.
v2: Dirty rect related compute and storage moved to fbc state (Ville)
V3: Dont call fbc activate if FBC is already active
v4: Dirty rect compute and programming moved within DSB scope
New changes are added as separate patches to make it easy for review
But could be squashed if the reviews as ok.
v5: add HAS_FBC_DIRTY_RECT()
FBC Damage area updates in 3 steps.
1. As part of plane_atomic_check() get, adjust coordinates and store
the merged damage area in plane_state
2. Atomic_commit, update merged damage are to fbc_state and prepare the
damage area satifying all conditions
3 update the FBC dirty rect registers as part of DSB commit.
v6: Use dmage_merged helper earlier to handle bigjoiner cases (Ville)
Place the damage_merged handling code under HAS_FBC_DIRTY_RECT()
Added a variable to check if the damage_merged received from
the helper is valid. And if it is not valid, the FBC dirty rect
is updated with full plane reqion.
v7: Reordering of the patches
Updates to storage of damage to plane state as per comments from Ville
Updates to dirty rect handling in FBC as per comments from Ville
v8: Patch subject and description updates
Address to comments from Ville
Vinod Govindapillai (7):
drm/damage-helper: add const qualifier in
drm_atomic_helper_damage_merged()
drm/i915/display: update and store the plane damage clips
drm/i915/fbc: add register definitions for fbc dirty rect support
drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC dirty rect
support
drm/i915/fbc: avoid calling fbc activate if fbc is active
drm/i915/fbc: dirty rect support for FBC
drm/i915/fbc: disable FBC if PSR2 selective fetch is enabled
drivers/gpu/drm/drm_damage_helper.c | 2 +-
.../gpu/drm/i915/display/intel_atomic_plane.c | 32 ++++++
drivers/gpu/drm/i915/display/intel_display.c | 3 +
.../drm/i915/display/intel_display_device.h | 1 +
.../drm/i915/display/intel_display_types.h | 2 +
drivers/gpu/drm/i915/display/intel_fbc.c | 105 +++++++++++++++++-
drivers/gpu/drm/i915/display/intel_fbc.h | 5 +
drivers/gpu/drm/i915/display/intel_fbc_regs.h | 9 ++
.../drm/i915/display/skl_universal_plane.c | 46 +++++++-
include/drm/drm_damage_helper.h | 2 +-
10 files changed, 202 insertions(+), 5 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v8 1/7] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged()
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 2/7] drm/i915/display: update and store the plane damage clips Vinod Govindapillai
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
Add a const qualifier for the "state" parameter as well as we could
use this helper to get the combined damage in cases of const
drm_plane_state as well. Needed mainly for xe driver big joiner cases
where we need to track the damage from immutable plane state.
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
drivers/gpu/drm/drm_damage_helper.c | 2 +-
include/drm/drm_damage_helper.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c
index afb02aae707b..44a5a36806e3 100644
--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -308,7 +308,7 @@ EXPORT_SYMBOL(drm_atomic_helper_damage_iter_next);
* True if there is valid plane damage otherwise false.
*/
bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state,
- struct drm_plane_state *state,
+ const struct drm_plane_state *state,
struct drm_rect *rect)
{
struct drm_atomic_helper_damage_iter iter;
diff --git a/include/drm/drm_damage_helper.h b/include/drm/drm_damage_helper.h
index effda42cce31..a58cbcd11276 100644
--- a/include/drm/drm_damage_helper.h
+++ b/include/drm/drm_damage_helper.h
@@ -78,7 +78,7 @@ bool
drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter,
struct drm_rect *rect);
bool drm_atomic_helper_damage_merged(const struct drm_plane_state *old_state,
- struct drm_plane_state *state,
+ const struct drm_plane_state *state,
struct drm_rect *rect);
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v8 2/7] drm/i915/display: update and store the plane damage clips
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 1/7] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged() Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 3/7] drm/i915/fbc: add register definitions for fbc dirty rect support Vinod Govindapillai
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
Userspace can pass damage area clips per plane to track
changes in a plane and some display components can utilze
these damage clips for efficiently handling use cases like
FBC, PSR etc. A merged damage area is generated and its
coordinates are updated relative to viewport and HW and
stored in the plane_state. This merged damage areas will be
used for FBC dirty rect support in xe3 in the follow-up
patch.
Big thanks to Ville Syrjala for his contribuitions in shaping
up of this series.
v1: - Move damage_merged helper to cover bigjoiner case and use
the correct plane state for damage find helper (Ville)
- Damage handling code under HAS_FBC_DIRTY_RECT() so the
the related part will be executed only for xe3+
- Changed dev_priv to i915 in one of the functions
v2: - damage reported is stored in the plane state after coords
adjustmentments irrespective of fbc dirty rect support.
- Damage to be empty in case of plane not visible (Ville)
- Handle fb could be NULL and plane not visible cases (Ville)
v3: - No need to empty damage in case disp ver < 12 (Ville)
- update to the patch subject
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
.../gpu/drm/i915/display/intel_atomic_plane.c | 29 ++++++++++++
.../drm/i915/display/intel_display_types.h | 2 +
.../drm/i915/display/skl_universal_plane.c | 46 ++++++++++++++++++-
3 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 8a49d87d9bd9..2278412200fd 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -36,6 +36,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
+#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -117,6 +118,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL;
intel_state->flags = 0;
+ intel_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
/* add reference to fb */
if (intel_state->hw.fb)
@@ -322,6 +324,25 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
memset(&plane_state->hw, 0, sizeof(plane_state->hw));
}
+static void
+intel_plane_copy_uapi_plane_damage(struct intel_plane_state *new_plane_state,
+ const struct intel_plane_state *old_uapi_plane_state,
+ const struct intel_plane_state *new_uapi_plane_state)
+{
+ struct intel_display *display = to_intel_display(new_plane_state);
+ struct drm_rect *damage = &new_plane_state->damage;
+
+ /* damage property tracking enabled from display version 12 onwards */
+ if (DISPLAY_VER(display) < 12)
+ return;
+
+ if (!drm_atomic_helper_damage_merged(&old_uapi_plane_state->uapi,
+ &new_uapi_plane_state->uapi,
+ damage))
+ /* Incase helper fails, mark whole plane region as damage */
+ *damage = drm_plane_state_src(&new_uapi_plane_state->uapi);
+}
+
void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
const struct intel_plane_state *from_plane_state,
struct intel_crtc *crtc)
@@ -691,6 +712,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
const struct intel_plane_state *new_primary_crtc_plane_state;
+ const struct intel_plane_state *old_primary_crtc_plane_state;
struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@@ -705,10 +727,17 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
new_primary_crtc_plane_state =
intel_atomic_get_new_plane_state(state, primary_crtc_plane);
+ old_primary_crtc_plane_state =
+ intel_atomic_get_old_plane_state(state, primary_crtc_plane);
} else {
new_primary_crtc_plane_state = new_plane_state;
+ old_primary_crtc_plane_state = old_plane_state;
}
+ intel_plane_copy_uapi_plane_damage(new_plane_state,
+ old_primary_crtc_plane_state,
+ new_primary_crtc_plane_state);
+
intel_plane_copy_uapi_to_hw_state(new_plane_state,
new_primary_crtc_plane_state,
crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 6a82c6ade549..844f92ea4f45 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -697,6 +697,8 @@ struct intel_plane_state {
u64 ccval;
const char *no_fbc_reason;
+
+ struct drm_rect damage;
};
struct intel_initial_plane_config {
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index eb85d3d6cdc3..3e3c22a26357 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -2260,6 +2260,44 @@ static void check_protection(struct intel_plane_state *plane_state)
!plane_state->decrypt;
}
+static void
+make_damage_viewport_relative(struct intel_plane_state *plane_state)
+{
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
+ const struct drm_rect *src = &plane_state->uapi.src;
+ unsigned int rotation = plane_state->hw.rotation;
+ struct drm_rect *damage = &plane_state->damage;
+
+ if (!drm_rect_visible(damage))
+ return;
+
+ if (!fb || !plane_state->uapi.visible) {
+ plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
+ return;
+ }
+
+ if (drm_rotation_90_or_270(rotation)) {
+ drm_rect_rotate(damage, fb->width, fb->height,
+ DRM_MODE_ROTATE_270);
+ drm_rect_translate(damage, -(src->y1 >> 16), -(src->x1 >> 16));
+ } else {
+ drm_rect_translate(damage, -(src->x1 >> 16), -(src->y1 >> 16));
+ }
+}
+
+static void clip_damage(struct intel_plane_state *plane_state)
+{
+ struct drm_rect *damage = &plane_state->damage;
+ struct drm_rect src;
+
+ if (!drm_rect_visible(damage))
+ return;
+
+ drm_rect_fp_to_int(&src, &plane_state->uapi.src);
+ drm_rect_translate(damage, src.x1, src.y1);
+ drm_rect_intersect(damage, &src);
+}
+
static int skl_plane_check(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
@@ -2285,6 +2323,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
+ make_damage_viewport_relative(plane_state);
+
ret = skl_check_plane_surface(plane_state);
if (ret)
return ret;
@@ -2300,6 +2340,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
+ clip_damage(plane_state);
+
ret = skl_plane_check_nv12_rotation(plane_state);
if (ret)
return ret;
@@ -2307,8 +2349,10 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
check_protection(plane_state);
/* HW only has 8 bits pixel precision, disable plane if invisible */
- if (!(plane_state->hw.alpha >> 8))
+ if (!(plane_state->hw.alpha >> 8)) {
plane_state->uapi.visible = false;
+ plane_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
+ }
plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v8 3/7] drm/i915/fbc: add register definitions for fbc dirty rect support
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 1/7] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged() Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 2/7] drm/i915/display: update and store the plane damage clips Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 4/7] drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC " Vinod Govindapillai
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
Register definitions for FBC dirty rect support
v2: - update to the patch subject
Bspec: 71675, 73424
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
drivers/gpu/drm/i915/display/intel_fbc_regs.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_fbc_regs.h b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
index ae0699c3c2fe..b1d0161a3196 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc_regs.h
@@ -100,6 +100,15 @@
#define FBC_STRIDE_MASK REG_GENMASK(14, 0)
#define FBC_STRIDE(x) REG_FIELD_PREP(FBC_STRIDE_MASK, (x))
+#define XE3_FBC_DIRTY_RECT(fbc_id) _MMIO_PIPE((fbc_id), 0x43230, 0x43270)
+#define FBC_DIRTY_RECT_END_LINE_MASK REG_GENMASK(31, 16)
+#define FBC_DIRTY_RECT_END_LINE(val) REG_FIELD_PREP(FBC_DIRTY_RECT_END_LINE_MASK, (val))
+#define FBC_DIRTY_RECT_START_LINE_MASK REG_GENMASK(15, 0)
+#define FBC_DIRTY_RECT_START_LINE(val) REG_FIELD_PREP(FBC_DIRTY_RECT_START_LINE_MASK, (val))
+
+#define XE3_FBC_DIRTY_CTL(fbc_id) _MMIO_PIPE((fbc_id), 0x43234, 0x43274)
+#define FBC_DIRTY_RECT_EN REG_BIT(31)
+
#define ILK_FBC_RT_BASE _MMIO(0x2128)
#define ILK_FBC_RT_VALID REG_BIT(0)
#define SNB_FBC_FRONT_BUFFER REG_BIT(1)
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v8 4/7] drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC dirty rect support
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
` (2 preceding siblings ...)
2025-02-13 13:25 ` [PATCH v8 3/7] drm/i915/fbc: add register definitions for fbc dirty rect support Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 5/7] drm/i915/fbc: avoid calling fbc activate if fbc is active Vinod Govindapillai
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
Introduce a macro to check if the platform supports FBC dirty
rect capability.
v2: - update to the patch subject
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
drivers/gpu/drm/i915/display/intel_display_device.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index fc33791f02b9..717286981687 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -163,6 +163,7 @@ struct intel_display_platforms {
#define HAS_DSC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dsc)
#define HAS_DSC_MST(__display) (DISPLAY_VER(__display) >= 12 && HAS_DSC(__display))
#define HAS_FBC(__display) (DISPLAY_RUNTIME_INFO(__display)->fbc_mask != 0)
+#define HAS_FBC_DIRTY_RECT(__display) (DISPLAY_VER(__display) >= 30)
#define HAS_FPGA_DBG_UNCLAIMED(__display) (DISPLAY_INFO(__display)->has_fpga_dbg)
#define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3)
#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4)
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v8 5/7] drm/i915/fbc: avoid calling fbc activate if fbc is active
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
` (3 preceding siblings ...)
2025-02-13 13:25 ` [PATCH v8 4/7] drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC " Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 6/7] drm/i915/fbc: dirty rect support for FBC Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 7/7] drm/i915/fbc: disable FBC if PSR2 selective fetch is enabled Vinod Govindapillai
6 siblings, 0 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
If FBC is already active, we don't need to call FBC activate
routine again unless there are changes to the fences. So skip
this on all platforms that don't have fences. Any FBC register
updates done after enabling the dirty rect support in xe3 will
trigger nuke by FBC which is counter productive to the fbc
dirty rect feature.
The front buffer rendering sequence will call intel_fbc_flush()
and which will call intel_fbc_nuke() or intel_fbc_activate()
based on FBC status explicitly and won't get impacted by this
change.
v2: use HAS_FBC_DIRTY_RECT()
move this functionality within intel_fbc_activate()
v3: update to intel_fbc_activate logic (Ville)
update to the patch description
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
drivers/gpu/drm/i915/display/intel_fbc.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index df05904bac8a..d2917e017e7b 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -739,8 +739,19 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
static void intel_fbc_activate(struct intel_fbc *fbc)
{
+ struct intel_display *display = fbc->display;
+
lockdep_assert_held(&fbc->lock);
+ /* only the fence can change for a flip nuke */
+ if (fbc->active && !intel_fbc_has_fences(display))
+ return;
+ /*
+ * In case of FBC dirt rect, any updates to the FBC registers will
+ * trigger the nuke.
+ */
+ drm_WARN_ON(display->drm, fbc->active && HAS_FBC_DIRTY_RECT(display));
+
intel_fbc_hw_activate(fbc);
intel_fbc_nuke(fbc);
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v8 6/7] drm/i915/fbc: dirty rect support for FBC
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
` (4 preceding siblings ...)
2025-02-13 13:25 ` [PATCH v8 5/7] drm/i915/fbc: avoid calling fbc activate if fbc is active Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
2025-02-13 13:51 ` Ville Syrjälä
2025-02-13 13:25 ` [PATCH v8 7/7] drm/i915/fbc: disable FBC if PSR2 selective fetch is enabled Vinod Govindapillai
6 siblings, 1 reply; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
Dirty rectangle feature allows FBC to recompress a subsection
of a frame. When this feature is enabled, display will read
the scan lines between dirty rectangle start line and dirty
rectangle end line in subsequent frames.
Use the merged damage clip stored in the plane state to
configure the FBC dirty rect areas.
v2: - Move dirty rect handling to fbc state (Ville)
v3: - Use intel_fbc_dirty_rect_update_noarm (Ville)
- Split plane damage collection and dirty rect preparation
- Handle case where dirty rect fall outside the visible region
v4: - A state variable to check if we need to update dirty rect
registers in case intel_fbc_can_flip_nuke() (Ville)
v5: - No need to use a separate valid flag, updates to the
conditions for prepare damage rect (Ville)
- Usage of locks in fbc dirty rect related functions (Ville)
v6: - updates dirty rect handling (Ville)
Bspec: 68881, 71675, 73424
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
.../gpu/drm/i915/display/intel_atomic_plane.c | 3 +
drivers/gpu/drm/i915/display/intel_display.c | 3 +
drivers/gpu/drm/i915/display/intel_fbc.c | 85 +++++++++++++++++++
drivers/gpu/drm/i915/display/intel_fbc.h | 5 ++
4 files changed, 96 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 2278412200fd..041e1d9ef621 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -803,6 +803,9 @@ void intel_plane_update_noarm(struct intel_dsb *dsb,
trace_intel_plane_update_noarm(plane_state, crtc);
+ if (plane->fbc)
+ intel_fbc_dirty_rect_update_noarm(dsb, plane);
+
if (plane->update_noarm)
plane->update_noarm(dsb, plane, crtc_state, plane_state);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index cc51576353fe..dd801b9d9a52 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7783,6 +7783,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_atomic_prepare_plane_clear_colors(state);
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
+ intel_fbc_prepare_dirty_rect(state, crtc);
+
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
intel_atomic_dsb_finish(state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index d2917e017e7b..66a5ee10a649 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -88,6 +88,7 @@ struct intel_fbc_state {
u16 override_cfb_stride;
u16 interval;
s8 fence_id;
+ struct drm_rect dirty_rect;
};
struct intel_fbc {
@@ -527,6 +528,9 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc)
struct intel_display *display = fbc->display;
u32 dpfc_ctl;
+ if (HAS_FBC_DIRTY_RECT(display))
+ intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id), 0);
+
/* Disable compression */
dpfc_ctl = intel_de_read(display, ILK_DPFC_CONTROL(fbc->id));
if (dpfc_ctl & DPFC_CTL_EN) {
@@ -670,6 +674,10 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)
if (DISPLAY_VER(display) >= 20)
intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
+ if (HAS_FBC_DIRTY_RECT(display))
+ intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id),
+ FBC_DIRTY_RECT_EN);
+
intel_de_write(display, ILK_DPFC_CONTROL(fbc->id),
DPFC_CTL_EN | dpfc_ctl);
}
@@ -1214,6 +1222,83 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state)
return i8xx_fbc_tiling_valid(plane_state);
}
+static void
+intel_fbc_dirty_rect_update(struct intel_dsb *dsb, struct intel_fbc *fbc)
+{
+ struct intel_display *display = fbc->display;
+ struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect;
+
+ lockdep_assert_held(&fbc->lock);
+
+ intel_de_write_dsb(display, dsb, XE3_FBC_DIRTY_RECT(fbc->id),
+ FBC_DIRTY_RECT_START_LINE(fbc_dirty_rect->y1) |
+ FBC_DIRTY_RECT_END_LINE(fbc_dirty_rect->y2 - 1));
+}
+
+void
+intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane)
+{
+ struct intel_display *display = to_intel_display(plane);
+ struct intel_fbc *fbc = plane->fbc;
+
+ if (!HAS_FBC_DIRTY_RECT(display))
+ return;
+
+ mutex_lock(&fbc->lock);
+
+ if (fbc->state.plane == plane)
+ intel_fbc_dirty_rect_update(dsb, fbc);
+
+ mutex_unlock(&fbc->lock);
+}
+
+static void
+__intel_fbc_prepare_dirty_rect(struct intel_plane *plane,
+ struct intel_plane_state *plane_state)
+{
+ struct intel_fbc *fbc = plane->fbc;
+ struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect;
+ int width = drm_rect_width(&plane_state->uapi.src) >> 16;
+ const struct drm_rect *damage = &plane_state->damage;
+ int y_offset = plane_state->view.color_plane[0].y;
+
+ lockdep_assert_held(&fbc->lock);
+
+ if (drm_rect_visible(damage))
+ *fbc_dirty_rect = *damage;
+ else
+ /* dirty rect must cover at least one line */
+ *fbc_dirty_rect = DRM_RECT_INIT(0, y_offset, width, 1);
+}
+
+void
+intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct intel_display *display = to_intel_display(state);
+ struct intel_plane_state *plane_state;
+ struct intel_plane *plane;
+ int i;
+
+ if (!HAS_FBC_DIRTY_RECT(display))
+ return;
+
+ for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+ struct intel_fbc *fbc = plane->fbc;
+
+ if (!fbc || plane->pipe != crtc->pipe)
+ continue;
+
+ mutex_lock(&fbc->lock);
+
+ if (fbc->state.plane == plane)
+ __intel_fbc_prepare_dirty_rect(plane, plane_state);
+
+ mutex_unlock(&fbc->lock);
+ }
+}
+
static void intel_fbc_update_state(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h
index ceae55458e14..fe48d0276eec 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.h
+++ b/drivers/gpu/drm/i915/display/intel_fbc.h
@@ -14,6 +14,7 @@ struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
+struct intel_dsb;
struct intel_fbc;
struct intel_plane;
struct intel_plane_state;
@@ -48,5 +49,9 @@ void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display);
void intel_fbc_reset_underrun(struct intel_display *display);
void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
void intel_fbc_debugfs_register(struct intel_display *display);
+void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
+ struct intel_plane *plane);
#endif /* __INTEL_FBC_H__ */
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v8 7/7] drm/i915/fbc: disable FBC if PSR2 selective fetch is enabled
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
` (5 preceding siblings ...)
2025-02-13 13:25 ` [PATCH v8 6/7] drm/i915/fbc: dirty rect support for FBC Vinod Govindapillai
@ 2025-02-13 13:25 ` Vinod Govindapillai
6 siblings, 0 replies; 9+ messages in thread
From: Vinod Govindapillai @ 2025-02-13 13:25 UTC (permalink / raw)
To: intel-gfx, intel-xe
Cc: dri-devel, vinod.govindapillai, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
It is not recommended to have both FBC dirty rect and PSR2
selective fetch be enabled at the same time. Mark FBC as not
possible, if PSR2 selective fetch is enabled.
v2: fix the condition to disable FBC if PSR2 enabled (Jani)
v3: use HAS_FBC_DIRTY_RECT()
v4: Update to patch description
Bspec: 68881
Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
---
drivers/gpu/drm/i915/display/intel_fbc.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 66a5ee10a649..bd8ca6ef832a 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -1434,9 +1434,14 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
* Display 12+ is not supporting FBC with PSR2.
* Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002
+ *
+ * In Xe3, PSR2 selective fetch and FBC dirty rect feature cannot
+ * coexist. So if PSR2 selective fetch is supported then mark that
+ * FBC is not supported.
+ * TODO: Need a logic to decide between PSR2 and FBC Dirty rect
*/
- if (IS_DISPLAY_VER(display, 12, 14) && crtc_state->has_sel_update &&
- !crtc_state->has_panel_replay) {
+ if ((IS_DISPLAY_VER(display, 12, 14) || HAS_FBC_DIRTY_RECT(display)) &&
+ crtc_state->has_sel_update && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR2 enabled";
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v8 6/7] drm/i915/fbc: dirty rect support for FBC
2025-02-13 13:25 ` [PATCH v8 6/7] drm/i915/fbc: dirty rect support for FBC Vinod Govindapillai
@ 2025-02-13 13:51 ` Ville Syrjälä
0 siblings, 0 replies; 9+ messages in thread
From: Ville Syrjälä @ 2025-02-13 13:51 UTC (permalink / raw)
To: Vinod Govindapillai
Cc: intel-gfx, intel-xe, dri-devel, ville.syrjala,
santhosh.reddy.guddati, jani.saarinen
On Thu, Feb 13, 2025 at 03:25:57PM +0200, Vinod Govindapillai wrote:
> Dirty rectangle feature allows FBC to recompress a subsection
> of a frame. When this feature is enabled, display will read
> the scan lines between dirty rectangle start line and dirty
> rectangle end line in subsequent frames.
>
> Use the merged damage clip stored in the plane state to
> configure the FBC dirty rect areas.
>
> v2: - Move dirty rect handling to fbc state (Ville)
>
> v3: - Use intel_fbc_dirty_rect_update_noarm (Ville)
> - Split plane damage collection and dirty rect preparation
> - Handle case where dirty rect fall outside the visible region
>
> v4: - A state variable to check if we need to update dirty rect
> registers in case intel_fbc_can_flip_nuke() (Ville)
>
> v5: - No need to use a separate valid flag, updates to the
> conditions for prepare damage rect (Ville)
> - Usage of locks in fbc dirty rect related functions (Ville)
>
> v6: - updates dirty rect handling (Ville)
>
> Bspec: 68881, 71675, 73424
> Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
> ---
> .../gpu/drm/i915/display/intel_atomic_plane.c | 3 +
> drivers/gpu/drm/i915/display/intel_display.c | 3 +
> drivers/gpu/drm/i915/display/intel_fbc.c | 85 +++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_fbc.h | 5 ++
> 4 files changed, 96 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 2278412200fd..041e1d9ef621 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -803,6 +803,9 @@ void intel_plane_update_noarm(struct intel_dsb *dsb,
>
> trace_intel_plane_update_noarm(plane_state, crtc);
>
> + if (plane->fbc)
> + intel_fbc_dirty_rect_update_noarm(dsb, plane);
> +
> if (plane->update_noarm)
> plane->update_noarm(dsb, plane, crtc_state, plane_state);
> }
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index cc51576353fe..dd801b9d9a52 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7783,6 +7783,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>
> intel_atomic_prepare_plane_clear_colors(state);
>
> + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
> + intel_fbc_prepare_dirty_rect(state, crtc);
> +
> for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
> intel_atomic_dsb_finish(state, crtc);
>
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
> index d2917e017e7b..66a5ee10a649 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
> @@ -88,6 +88,7 @@ struct intel_fbc_state {
> u16 override_cfb_stride;
> u16 interval;
> s8 fence_id;
> + struct drm_rect dirty_rect;
> };
>
> struct intel_fbc {
> @@ -527,6 +528,9 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc)
> struct intel_display *display = fbc->display;
> u32 dpfc_ctl;
>
> + if (HAS_FBC_DIRTY_RECT(display))
> + intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id), 0);
> +
> /* Disable compression */
> dpfc_ctl = intel_de_read(display, ILK_DPFC_CONTROL(fbc->id));
> if (dpfc_ctl & DPFC_CTL_EN) {
> @@ -670,6 +674,10 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)
> if (DISPLAY_VER(display) >= 20)
> intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl);
>
> + if (HAS_FBC_DIRTY_RECT(display))
> + intel_de_write(display, XE3_FBC_DIRTY_CTL(fbc->id),
> + FBC_DIRTY_RECT_EN);
> +
> intel_de_write(display, ILK_DPFC_CONTROL(fbc->id),
> DPFC_CTL_EN | dpfc_ctl);
> }
> @@ -1214,6 +1222,83 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state)
> return i8xx_fbc_tiling_valid(plane_state);
> }
>
> +static void
> +intel_fbc_dirty_rect_update(struct intel_dsb *dsb, struct intel_fbc *fbc)
> +{
> + struct intel_display *display = fbc->display;
> + struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect;
can be const
> +
> + lockdep_assert_held(&fbc->lock);
> +
> + intel_de_write_dsb(display, dsb, XE3_FBC_DIRTY_RECT(fbc->id),
> + FBC_DIRTY_RECT_START_LINE(fbc_dirty_rect->y1) |
> + FBC_DIRTY_RECT_END_LINE(fbc_dirty_rect->y2 - 1));
> +}
> +
> +void
> +intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
> + struct intel_plane *plane)
> +{
> + struct intel_display *display = to_intel_display(plane);
> + struct intel_fbc *fbc = plane->fbc;
> +
> + if (!HAS_FBC_DIRTY_RECT(display))
> + return;
> +
> + mutex_lock(&fbc->lock);
> +
> + if (fbc->state.plane == plane)
> + intel_fbc_dirty_rect_update(dsb, fbc);
> +
> + mutex_unlock(&fbc->lock);
> +}
> +
> +static void
> +__intel_fbc_prepare_dirty_rect(struct intel_plane *plane,
plane doesn't need to be passed in explicitly since it can
be determined from the plane_state.
> + struct intel_plane_state *plane_state)
this can be const.
> +{
> + struct intel_fbc *fbc = plane->fbc;
> + struct drm_rect *fbc_dirty_rect = &fbc->state.dirty_rect;
> + int width = drm_rect_width(&plane_state->uapi.src) >> 16;
> + const struct drm_rect *damage = &plane_state->damage;
> + int y_offset = plane_state->view.color_plane[0].y;
> +
> + lockdep_assert_held(&fbc->lock);
> +
> + if (drm_rect_visible(damage))
> + *fbc_dirty_rect = *damage;
> + else
> + /* dirty rect must cover at least one line */
> + *fbc_dirty_rect = DRM_RECT_INIT(0, y_offset, width, 1);
> +}
> +
> +void
> +intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
> + struct intel_crtc *crtc)
Looks to me like we don't actully need the crtc here at all.
We anyway just end up looping through all the planes in the
state.
With those sorted the series is
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> +{
> + struct intel_display *display = to_intel_display(state);
> + struct intel_plane_state *plane_state;
> + struct intel_plane *plane;
> + int i;
> +
> + if (!HAS_FBC_DIRTY_RECT(display))
> + return;
> +
> + for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> + struct intel_fbc *fbc = plane->fbc;
> +
> + if (!fbc || plane->pipe != crtc->pipe)
> + continue;
> +
> + mutex_lock(&fbc->lock);
> +
> + if (fbc->state.plane == plane)
> + __intel_fbc_prepare_dirty_rect(plane, plane_state);
> +
> + mutex_unlock(&fbc->lock);
> + }
> +}
> +
> static void intel_fbc_update_state(struct intel_atomic_state *state,
> struct intel_crtc *crtc,
> struct intel_plane *plane)
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h b/drivers/gpu/drm/i915/display/intel_fbc.h
> index ceae55458e14..fe48d0276eec 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.h
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.h
> @@ -14,6 +14,7 @@ struct intel_atomic_state;
> struct intel_crtc;
> struct intel_crtc_state;
> struct intel_display;
> +struct intel_dsb;
> struct intel_fbc;
> struct intel_plane;
> struct intel_plane_state;
> @@ -48,5 +49,9 @@ void intel_fbc_handle_fifo_underrun_irq(struct intel_display *display);
> void intel_fbc_reset_underrun(struct intel_display *display);
> void intel_fbc_crtc_debugfs_add(struct intel_crtc *crtc);
> void intel_fbc_debugfs_register(struct intel_display *display);
> +void intel_fbc_prepare_dirty_rect(struct intel_atomic_state *state,
> + struct intel_crtc *crtc);
> +void intel_fbc_dirty_rect_update_noarm(struct intel_dsb *dsb,
> + struct intel_plane *plane);
>
> #endif /* __INTEL_FBC_H__ */
> --
> 2.43.0
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-02-13 13:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-13 13:25 [PATCH v8 0/7] drm/i915/fbc: FBC Dirty rect feature support Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 1/7] drm/damage-helper: add const qualifier in drm_atomic_helper_damage_merged() Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 2/7] drm/i915/display: update and store the plane damage clips Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 3/7] drm/i915/fbc: add register definitions for fbc dirty rect support Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 4/7] drm/i915/fbc: introduce HAS_FBC_DIRTY_RECT() for FBC " Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 5/7] drm/i915/fbc: avoid calling fbc activate if fbc is active Vinod Govindapillai
2025-02-13 13:25 ` [PATCH v8 6/7] drm/i915/fbc: dirty rect support for FBC Vinod Govindapillai
2025-02-13 13:51 ` Ville Syrjälä
2025-02-13 13:25 ` [PATCH v8 7/7] drm/i915/fbc: disable FBC if PSR2 selective fetch is enabled Vinod Govindapillai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).