[Intel-gfx] [PATCH 03/20] drm/i915/fbc: Nuke lots of crap from intel_fbc_state_cache
Kahola, Mika
mika.kahola at intel.com
Tue Nov 30 13:21:43 UTC 2021
> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces at lists.freedesktop.org> On Behalf Of Ville
> Syrjala
> Sent: Wednesday, November 24, 2021 1:37 PM
> To: intel-gfx at lists.freedesktop.org
> Subject: [Intel-gfx] [PATCH 03/20] drm/i915/fbc: Nuke lots of crap from
> intel_fbc_state_cache
>
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
> There's no need to store all this stuff in intel_fbc_state_cache.
> Just check it all against the plane/crtc states and store only what we need.
> Probably more should get nuked still, but this is a start.
>
> So what we'll do is:
> - each plane will check its own state and update its local
> no_fbc_reason
> - the per-plane no_fbc_reason (if any) then gets propagated
> to the cache->no_fbc_reason while doing the actual update
> - fbc->no_fbc_reason gets updated in the end with either
> the value from the cache or directly from frontbuffer
> tracking
>
> It's still a bit messy, but should hopefuly get cleaned up more in the future. At
> least now we can observe each plane's reasons for rejecting FBC now more
> consistently, and we don't have so mcuh redundant state store all over the
> place.
>
> v2: store no_fbc_reason per-plane instead of per-pipe
>
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Reviewed-by: Mika Kahola <mika.kahola at intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_display.c | 5 +-
> .../drm/i915/display/intel_display_types.h | 4 +-
> drivers/gpu/drm/i915/display/intel_fbc.c | 341 ++++++++----------
> drivers/gpu/drm/i915/display/intel_fbc.h | 3 +-
> drivers/gpu/drm/i915/i915_drv.h | 20 +-
> 5 files changed, 166 insertions(+), 207 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index b2d51cd79d6c..520a87c814a6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8039,7 +8039,6 @@ static int intel_atomic_check(struct drm_device *dev,
> if (ret)
> goto fail;
>
> - intel_fbc_choose_crtc(dev_priv, state);
> ret = intel_compute_global_watermarks(state);
> if (ret)
> goto fail;
> @@ -8071,6 +8070,10 @@ static int intel_atomic_check(struct drm_device
> *dev,
> if (ret)
> goto fail;
>
> + ret = intel_fbc_atomic_check(state);
> + if (ret)
> + goto fail;
> +
> for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> new_crtc_state, i) {
> if (new_crtc_state->uapi.async_flip) { diff --git
> a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index ea1e8a6e10b0..5df477dfb8cd 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -687,6 +687,8 @@ struct intel_plane_state {
>
> /* Clear Color Value */
> u64 ccval;
> +
> + const char *no_fbc_reason;
> };
>
> struct intel_initial_plane_config {
> @@ -1117,8 +1119,6 @@ struct intel_crtc_state {
>
> bool crc_enabled;
>
> - bool enable_fbc;
> -
> bool double_wide;
>
> int pbn;
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c
> b/drivers/gpu/drm/i915/display/intel_fbc.c
> index 083c0cab4847..8bde3681b96e 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
> @@ -43,6 +43,7 @@
> #include "i915_drv.h"
> #include "i915_trace.h"
> #include "i915_vgpu.h"
> +#include "intel_cdclk.h"
> #include "intel_de.h"
> #include "intel_display_types.h"
> #include "intel_fbc.h"
> @@ -58,20 +59,6 @@ struct intel_fbc_funcs {
> void (*set_false_color)(struct intel_fbc *fbc, bool enable); };
>
> -/*
> - * For SKL+, the plane source size used by the hardware is based on the value
> we
> - * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value
> - * we wrote to PIPESRC.
> - */
> -static void intel_fbc_get_plane_source_size(const struct intel_fbc_state_cache
> *cache,
> - int *width, int *height)
> -{
> - if (width)
> - *width = cache->plane.src_w;
> - if (height)
> - *height = cache->plane.src_h;
> -}
> -
> /* plane stride in pixels */
> static unsigned int intel_fbc_plane_stride(const struct intel_plane_state
> *plane_state) { @@ -796,9 +783,13 @@ void intel_fbc_cleanup(struct
> drm_i915_private *i915)
> mutex_unlock(&fbc->lock);
> }
>
> -static bool stride_is_valid(struct drm_i915_private *i915,
> - u64 modifier, unsigned int stride)
> +static bool stride_is_valid(const struct intel_plane_state
> +*plane_state)
> {
> + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> + unsigned int stride = intel_fbc_plane_stride(plane_state) *
> + fb->format->cpp[0];
> +
> /* This should have been caught earlier. */
> if (drm_WARN_ON_ONCE(&i915->drm, (stride & (64 - 1)) != 0))
> return false;
> @@ -815,7 +806,7 @@ static bool stride_is_valid(struct drm_i915_private
> *i915,
>
> /* Display WA #1105: skl,bxt,kbl,cfl,glk */
> if ((DISPLAY_VER(i915) == 9 || IS_GEMINILAKE(i915)) &&
> - modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
> + fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
> return false;
>
> if (stride > 16384)
> @@ -824,10 +815,12 @@ static bool stride_is_valid(struct drm_i915_private
> *i915,
> return true;
> }
>
> -static bool pixel_format_is_valid(struct drm_i915_private *i915,
> - u32 pixel_format)
> +static bool pixel_format_is_valid(const struct intel_plane_state
> +*plane_state)
> {
> - switch (pixel_format) {
> + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> +
> + switch (fb->format->format) {
> case DRM_FORMAT_XRGB8888:
> case DRM_FORMAT_XBGR8888:
> return true;
> @@ -845,10 +838,13 @@ static bool pixel_format_is_valid(struct
> drm_i915_private *i915,
> }
> }
>
> -static bool rotation_is_valid(struct drm_i915_private *i915,
> - u32 pixel_format, unsigned int rotation)
> +static bool rotation_is_valid(const struct intel_plane_state
> +*plane_state)
> {
> - if (DISPLAY_VER(i915) >= 9 && pixel_format == DRM_FORMAT_RGB565
> &&
> + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> + unsigned int rotation = plane_state->hw.rotation;
> +
> + if (DISPLAY_VER(i915) >= 9 && fb->format->format ==
> DRM_FORMAT_RGB565
> +&&
> drm_rotation_90_or_270(rotation))
> return false;
> else if (DISPLAY_VER(i915) <= 4 && !IS_G4X(i915) && @@ -864,10
> +860,9 @@ static bool rotation_is_valid(struct drm_i915_private *i915,
> * the X and Y offset registers. That's why we include the src x/y offsets
> * instead of just looking at the plane size.
> */
> -static bool intel_fbc_hw_tracking_covers_screen(struct intel_fbc *fbc,
> - struct intel_crtc *crtc)
> +static bool intel_fbc_hw_tracking_covers_screen(const struct
> +intel_plane_state *plane_state)
> {
> - struct drm_i915_private *i915 = fbc->i915;
> + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
> unsigned int effective_w, effective_h, max_w, max_h;
>
> if (DISPLAY_VER(i915) >= 10) {
> @@ -884,18 +879,20 @@ static bool
> intel_fbc_hw_tracking_covers_screen(struct intel_fbc *fbc,
> max_h = 1536;
> }
>
> - intel_fbc_get_plane_source_size(&fbc->state_cache, &effective_w,
> - &effective_h);
> - effective_w += fbc->state_cache.plane.adjusted_x;
> - effective_h += fbc->state_cache.plane.adjusted_y;
> + effective_w = plane_state->view.color_plane[0].x +
> + (drm_rect_width(&plane_state->uapi.src) >> 16);
> + effective_h = plane_state->view.color_plane[0].y +
> + (drm_rect_height(&plane_state->uapi.src) >> 16);
>
> return effective_w <= max_w && effective_h <= max_h; }
>
> -static bool tiling_is_valid(struct drm_i915_private *i915,
> - u64 modifier)
> +static bool tiling_is_valid(const struct intel_plane_state
> +*plane_state)
> {
> - switch (modifier) {
> + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> +
> + switch (fb->modifier) {
> case DRM_FORMAT_MOD_LINEAR:
> case I915_FORMAT_MOD_Y_TILED:
> case I915_FORMAT_MOD_Yf_TILED:
> @@ -916,15 +913,10 @@ static void intel_fbc_update_state_cache(struct
> intel_crtc *crtc,
> struct intel_fbc_state_cache *cache = &fbc->state_cache;
> struct drm_framebuffer *fb = plane_state->hw.fb;
>
> - cache->plane.visible = plane_state->uapi.visible;
> - if (!cache->plane.visible)
> + cache->no_fbc_reason = plane_state->no_fbc_reason;
> + if (cache->no_fbc_reason)
> return;
>
> - cache->crtc.mode_flags = crtc_state->hw.adjusted_mode.flags;
> - if (IS_HASWELL(i915) || IS_BROADWELL(i915))
> - cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate;
> -
> - cache->plane.rotation = plane_state->hw.rotation;
> /*
> * Src coordinates are already rotated by 270 degrees for
> * the 90/270 degree plane rotation cases (to match the @@ -932,10
> +924,6 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
> */
> cache->plane.src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
> cache->plane.src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
> - cache->plane.adjusted_x = plane_state->view.color_plane[0].x;
> - cache->plane.adjusted_y = plane_state->view.color_plane[0].y;
> -
> - cache->plane.pixel_blend_mode = plane_state->hw.pixel_blend_mode;
>
> cache->fb.format = fb->format;
> cache->fb.modifier = fb->modifier;
> @@ -954,8 +942,6 @@ static void intel_fbc_update_state_cache(struct
> intel_crtc *crtc,
> cache->fence_id = plane_state->ggtt_vma->fence->id;
> else
> cache->fence_id = -1;
> -
> - cache->psr2_active = crtc_state->has_psr2;
> }
>
> static bool intel_fbc_cfb_size_changed(struct intel_fbc *fbc) @@ -1007,6
> +993,110 @@ static bool intel_fbc_can_enable(struct intel_fbc *fbc)
> return true;
> }
>
> +static int intel_fbc_check_plane(struct intel_atomic_state *state,
> + struct intel_plane *plane)
> +{
> + struct drm_i915_private *i915 = to_i915(state->base.dev);
> + struct intel_plane_state *plane_state =
> + intel_atomic_get_new_plane_state(state, plane);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> + struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc);
> + const struct intel_crtc_state *crtc_state;
> + struct intel_fbc *fbc = plane->fbc;
> +
> + if (!fbc)
> + return 0;
> +
> + if (!plane_state->uapi.visible) {
> + plane_state->no_fbc_reason = "plane not visible";
> + return 0;
> + }
> +
> + crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> +
> + if (crtc_state->hw.adjusted_mode.flags &
> DRM_MODE_FLAG_INTERLACE) {
> + plane_state->no_fbc_reason = "interlaced mode not
> supported";
> + return 0;
> + }
> +
> + /*
> + * Display 12+ is not supporting FBC with PSR2.
> + * Recommendation is to keep this combination disabled
> + * Bspec: 50422 HSD: 14010260002
> + */
> + if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) {
> + plane_state->no_fbc_reason = "PSR2 enabled";
> + return false;
> + }
> +
> + if (!pixel_format_is_valid(plane_state)) {
> + plane_state->no_fbc_reason = "pixel format not supported";
> + return 0;
> + }
> +
> + if (!tiling_is_valid(plane_state)) {
> + plane_state->no_fbc_reason = "tiling not supported";
> + return 0;
> + }
> +
> + if (!rotation_is_valid(plane_state)) {
> + plane_state->no_fbc_reason = "rotation not supported";
> + return 0;
> + }
> +
> + if (!stride_is_valid(plane_state)) {
> + plane_state->no_fbc_reason = "stride not supported";
> + return 0;
> + }
> +
> + if (plane_state->hw.pixel_blend_mode !=
> DRM_MODE_BLEND_PIXEL_NONE &&
> + fb->format->has_alpha) {
> + plane_state->no_fbc_reason = "per-pixel alpha not supported";
> + return false;
> + }
> +
> + if (!intel_fbc_hw_tracking_covers_screen(plane_state)) {
> + plane_state->no_fbc_reason = "plane size too big";
> + return 0;
> + }
> +
> + /*
> + * Work around a problem on GEN9+ HW, where enabling FBC on a
> plane
> + * having a Y offset that isn't divisible by 4 causes FIFO underrun
> + * and screen flicker.
> + */
> + if (DISPLAY_VER(i915) >= 9 &&
> + plane_state->view.color_plane[0].y & 3) {
> + plane_state->no_fbc_reason = "plane start Y offset misaligned";
> + return false;
> + }
> +
> + /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
> + if (DISPLAY_VER(i915) >= 11 &&
> + (plane_state->view.color_plane[0].y +
> drm_rect_height(&plane_state->uapi.src)) & 3) {
> + plane_state->no_fbc_reason = "plane end Y offset misaligned";
> + return false;
> + }
> +
> + /* WaFbcExceedCdClockThreshold:hsw,bdw */
> + if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
> + const struct intel_cdclk_state *cdclk_state;
> +
> + cdclk_state = intel_atomic_get_cdclk_state(state);
> + if (IS_ERR(cdclk_state))
> + return PTR_ERR(cdclk_state);
> +
> + if (crtc_state->pixel_rate >= cdclk_state->logical.cdclk * 95 /
> 100) {
> + plane_state->no_fbc_reason = "pixel rate too high";
> + return 0;
> + }
> + }
> +
> + plane_state->no_fbc_reason = NULL;
> +
> + return 0;
> +}
> +
> static bool intel_fbc_can_activate(struct intel_crtc *crtc) {
> struct drm_i915_private *i915 = to_i915(crtc->base.dev); @@ -1016,8
> +1106,8 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
> if (!intel_fbc_can_enable(fbc))
> return false;
>
> - if (!cache->plane.visible) {
> - fbc->no_fbc_reason = "primary plane not visible";
> + if (cache->no_fbc_reason) {
> + fbc->no_fbc_reason = cache->no_fbc_reason;
> return false;
> }
>
> @@ -1029,16 +1119,6 @@ static bool intel_fbc_can_activate(struct intel_crtc
> *crtc)
> return false;
> }
>
> - if (cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) {
> - fbc->no_fbc_reason = "incompatible mode";
> - return false;
> - }
> -
> - if (!intel_fbc_hw_tracking_covers_screen(fbc, crtc)) {
> - fbc->no_fbc_reason = "mode too large for compression";
> - return false;
> - }
> -
> /* The use of a CPU fence is one of two ways to detect writes by the
> * CPU to the scanout and trigger updates to the FBC.
> *
> @@ -1061,42 +1141,8 @@ static bool intel_fbc_can_activate(struct intel_crtc
> *crtc)
> return false;
> }
>
> - if (!pixel_format_is_valid(i915, cache->fb.format->format)) {
> - fbc->no_fbc_reason = "pixel format is invalid";
> - return false;
> - }
> -
> - if (!rotation_is_valid(i915, cache->fb.format->format,
> - cache->plane.rotation)) {
> - fbc->no_fbc_reason = "rotation unsupported";
> - return false;
> - }
> -
> - if (!tiling_is_valid(i915, cache->fb.modifier)) {
> - fbc->no_fbc_reason = "tiling unsupported";
> - return false;
> - }
> -
> - if (!stride_is_valid(i915, cache->fb.modifier,
> - cache->fb.stride * cache->fb.format->cpp[0])) {
> - fbc->no_fbc_reason = "framebuffer stride not supported";
> - return false;
> - }
> -
> - if (cache->plane.pixel_blend_mode !=
> DRM_MODE_BLEND_PIXEL_NONE &&
> - cache->fb.format->has_alpha) {
> - fbc->no_fbc_reason = "per-pixel alpha blending is incompatible
> with FBC";
> - return false;
> - }
> -
> - /* WaFbcExceedCdClockThreshold:hsw,bdw */
> - if ((IS_HASWELL(i915) || IS_BROADWELL(i915)) &&
> - cache->crtc.hsw_bdw_pixel_rate >= i915->cdclk.hw.cdclk * 95 / 100) {
> - fbc->no_fbc_reason = "pixel rate is too big";
> - return false;
> - }
> -
> - /* It is possible for the required CFB size change without a
> + /*
> + * It is possible for the required CFB size change without a
> * crtc->disable + crtc->enable since it is possible to change the
> * stride without triggering a full modeset. Since we try to
> * over-allocate the CFB, there's a chance we may keep FBC enabled
> even @@ -1105,40 +1151,13 @@ static bool intel_fbc_can_activate(struct
> intel_crtc *crtc)
> * for a frame, free the stolen node, then try to reenable FBC in case
> * we didn't get any invalidate/deactivate calls, but this would require
> * a lot of tracking just for a specific case. If we conclude it's an
> - * important case, we can implement it later. */
> + * important case, we can implement it later.
> + */
> if (intel_fbc_cfb_size_changed(fbc)) {
> fbc->no_fbc_reason = "CFB requirements changed";
> return false;
> }
>
> - /*
> - * Work around a problem on GEN9+ HW, where enabling FBC on a
> plane
> - * having a Y offset that isn't divisible by 4 causes FIFO underrun
> - * and screen flicker.
> - */
> - if (DISPLAY_VER(i915) >= 9 &&
> - (fbc->state_cache.plane.adjusted_y & 3)) {
> - fbc->no_fbc_reason = "plane Y offset is misaligned";
> - return false;
> - }
> -
> - /* Wa_22010751166: icl, ehl, tgl, dg1, rkl */
> - if (DISPLAY_VER(i915) >= 11 &&
> - (cache->plane.src_h + cache->plane.adjusted_y) % 4) {
> - fbc->no_fbc_reason = "plane height + offset is non-modulo of
> 4";
> - return false;
> - }
> -
> - /*
> - * Display 12+ is not supporting FBC with PSR2.
> - * Recommendation is to keep this combination disabled
> - * Bspec: 50422 HSD: 14010260002
> - */
> - if (fbc->state_cache.psr2_active && DISPLAY_VER(i915) >= 12) {
> - fbc->no_fbc_reason = "not supported with PSR2";
> - return false;
> - }
> -
> return true;
> }
>
> @@ -1157,8 +1176,6 @@ static void intel_fbc_get_reg_params(struct intel_fbc
> *fbc,
> params->fence_y_offset = cache->fence_y_offset;
>
> params->interval = cache->interval;
> -
> - params->crtc.pipe = crtc->pipe;
> params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)-
> >i9xx_plane;
>
> params->fb.format = cache->fb.format;
> @@ -1168,8 +1185,6 @@ static void intel_fbc_get_reg_params(struct intel_fbc
> *fbc,
> params->cfb_stride = intel_fbc_cfb_stride(fbc, cache);
> params->cfb_size = intel_fbc_cfb_size(fbc, cache);
> params->override_cfb_stride = intel_fbc_override_cfb_stride(fbc,
> cache);
> -
> - params->plane_visible = cache->plane.visible;
> }
>
> static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state)
> @@ -1183,9 +1198,6 @@ static bool intel_fbc_can_flip_nuke(const struct
> intel_crtc_state *crtc_state)
> if (drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
> return false;
>
> - if (!params->plane_visible)
> - return false;
> -
> if (!intel_fbc_can_activate(crtc))
> return false;
>
> @@ -1381,63 +1393,21 @@ void intel_fbc_flush(struct drm_i915_private *i915,
> mutex_unlock(&fbc->lock);
> }
>
> -/**
> - * intel_fbc_choose_crtc - select a CRTC to enable FBC on
> - * @i915: i915 device instance
> - * @state: the atomic state structure
> - *
> - * This function looks at the proposed state for CRTCs and planes, then chooses
> - * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to
> - * true.
> - *
> - * Later, intel_fbc_enable is going to look for state->enable_fbc and then
> maybe
> - * enable FBC for the chosen CRTC. If it does, it will set i915->fbc.crtc.
> - */
> -void intel_fbc_choose_crtc(struct drm_i915_private *i915,
> - struct intel_atomic_state *state)
> +int intel_fbc_atomic_check(struct intel_atomic_state *state)
> {
> - struct intel_fbc *fbc = &i915->fbc;
> - struct intel_plane *plane;
> struct intel_plane_state *plane_state;
> - bool crtc_chosen = false;
> + struct intel_plane *plane;
> int i;
>
> - mutex_lock(&fbc->lock);
> -
> - /* Does this atomic commit involve the CRTC currently tied to FBC? */
> - if (fbc->crtc &&
> - !intel_atomic_get_new_crtc_state(state, fbc->crtc))
> - goto out;
> -
> - if (!intel_fbc_can_enable(fbc))
> - goto out;
> -
> - /* Simply choose the first CRTC that is compatible and has a visible
> - * plane. We could go for fancier schemes such as checking the plane
> - * size, but this would just affect the few platforms that don't tie FBC
> - * to pipe or plane A. */
> for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> - struct intel_crtc_state *crtc_state;
> - struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc);
> + int ret;
>
> - if (plane->fbc != fbc)
> - continue;
> -
> - if (!plane_state->uapi.visible)
> - continue;
> -
> - crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> -
> - crtc_state->enable_fbc = true;
> - crtc_chosen = true;
> - break;
> + ret = intel_fbc_check_plane(state, plane);
> + if (ret)
> + return ret;
> }
>
> - if (!crtc_chosen)
> - fbc->no_fbc_reason = "no suitable CRTC for FBC";
> -
> -out:
> - mutex_unlock(&fbc->lock);
> + return 0;
> }
>
> /**
> @@ -1487,12 +1457,10 @@ static void intel_fbc_enable(struct
> intel_atomic_state *state,
>
> intel_fbc_update_state_cache(crtc, crtc_state, plane_state);
>
> - /* FIXME crtc_state->enable_fbc lies :( */
> - if (!cache->plane.visible)
> + if (cache->no_fbc_reason)
> goto out;
>
> if (intel_fbc_alloc_cfb(fbc, intel_fbc_cfb_size(fbc, cache), min_limit)) {
> - cache->plane.visible = false;
> fbc->no_fbc_reason = "not enough stolen memory";
> goto out;
> }
> @@ -1541,10 +1509,17 @@ void intel_fbc_disable(struct intel_crtc *crtc) void
> intel_fbc_update(struct intel_atomic_state *state,
> struct intel_crtc *crtc)
> {
> + struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> const struct intel_crtc_state *crtc_state =
> intel_atomic_get_new_crtc_state(state, crtc);
> + const struct intel_plane_state *plane_state =
> + intel_atomic_get_new_plane_state(state, plane);
> + struct intel_fbc *fbc = plane->fbc;
>
> - if (crtc_state->update_pipe && !crtc_state->enable_fbc)
> + if (!fbc || !plane_state)
> + return;
> +
> + if (crtc_state->update_pipe && plane_state->no_fbc_reason)
> intel_fbc_disable(crtc);
> else
> intel_fbc_enable(state, crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.h
> b/drivers/gpu/drm/i915/display/intel_fbc.h
> index ce48a22c5e9e..74492e05a1c9 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.h
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.h
> @@ -17,8 +17,7 @@ struct intel_crtc_state; struct intel_fbc; struct
> intel_plane_state;
>
> -void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
> - struct intel_atomic_state *state);
> +int intel_fbc_atomic_check(struct intel_atomic_state *state);
> bool intel_fbc_is_active(struct intel_fbc *fbc); bool
> intel_fbc_is_compressing(struct intel_fbc *fbc); bool
> intel_fbc_pre_update(struct intel_atomic_state *state, diff --git
> a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index
> 1bfadd9127fc..d79aa827d937 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -434,26 +434,11 @@ struct intel_fbc {
> * these problems.
> */
> struct intel_fbc_state_cache {
> - struct {
> - unsigned int mode_flags;
> - u32 hsw_bdw_pixel_rate;
> - } crtc;
> + const char *no_fbc_reason;
>
> struct {
> - unsigned int rotation;
> int src_w;
> int src_h;
> - bool visible;
> - /*
> - * Display surface base address adjustement for
> - * pageflips. Note that on gen4+ this only adjusts up
> - * to a tile, offsets within a tile are handled in
> - * the hw itself (with the TILEOFF register).
> - */
> - int adjusted_x;
> - int adjusted_y;
> -
> - u16 pixel_blend_mode;
> } plane;
>
> struct {
> @@ -465,7 +450,6 @@ struct intel_fbc {
> unsigned int fence_y_offset;
> u16 interval;
> s8 fence_id;
> - bool psr2_active;
> } state_cache;
>
> /*
> @@ -477,7 +461,6 @@ struct intel_fbc {
> */
> struct intel_fbc_reg_params {
> struct {
> - enum pipe pipe;
> enum i9xx_plane_id i9xx_plane;
> } crtc;
>
> @@ -493,7 +476,6 @@ struct intel_fbc {
> u16 override_cfb_stride;
> u16 interval;
> s8 fence_id;
> - bool plane_visible;
> } params;
>
> const char *no_fbc_reason;
> --
> 2.32.0
More information about the Intel-gfx
mailing list