* [PATCH 00/18] Yet another FBC series
@ 2015-10-20 13:49 Paulo Zanoni
2015-10-20 13:49 ` [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string Paulo Zanoni
` (18 more replies)
0 siblings, 19 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
Hello
This series has two main goals:
- Simplify FBC handling so we don't recompute state or disable+reenable when
it's not necessary.
- Solve the CFB race we have that make it possible for the hardware to use the
CFB even after we free its drm_mm node.
Of course we can always do more and more code reworks, but this series kills the
last real bugs I can see on HSW+, so it will be time to consider enabling FBC on
these platforms after we merge the series.
Thanks,
Paulo
Paulo Zanoni (18):
drm/i915: change no_fbc_reason from enum to string
drm/i915: don't stop+start FBC at every flip
drm/i915: only nuke FBC when a drawing operation triggers a flush
drm/i915: extract crtc_is_valid() on the FBC code
drm/i915: set dev_priv->fbc.crtc before scheduling the enable work
drm/i915: use struct intel_crtc *crtc at __intel_fbc_update()
drm/i915: fix the __intel_fbc_update() comments
drm/i915: pass the crtc as an argument to intel_fbc_update()
drm/i915: don't disable_fbc() if FBC is already disabled
drm/i915: introduce is_active/activate/deactivate to the FBC
terminology
drm/i915: refactor FBC deactivation at init
drm/i915: introduce intel_fbc_{enable,disable}
drm/i915: remove too-frequent FBC debug message
drm/i915: fix the CFB size check
drm/i915: alloc/free the FBC CFB during enable/disable
drm/i915: move adjusted_mode checks from fbc_update to fbc_enable
drm/i915: move clock frequency checks from fbc_update to fbc_enable
drm/i915: check for FBC planes in the same place as the pipes
drivers/gpu/drm/i915/i915_debugfs.c | 4 +-
drivers/gpu/drm/i915/i915_drv.h | 32 +-
drivers/gpu/drm/i915/i915_reg.h | 3 +
drivers/gpu/drm/i915/intel_display.c | 25 +-
drivers/gpu/drm/i915/intel_drv.h | 9 +-
drivers/gpu/drm/i915/intel_fbc.c | 715 ++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_frontbuffer.c | 1 +
drivers/gpu/drm/i915/intel_pm.c | 2 +-
8 files changed, 447 insertions(+), 344 deletions(-)
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-21 6:52 ` Daniel Vetter
2015-10-20 13:49 ` [PATCH 02/18] drm/i915: don't stop+start FBC at every flip Paulo Zanoni
` (17 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
I wanted to add yet another check to intel_fbc_update() and realized
I would need to create yet another enum no_fbc_reason case. So I
remembered this patch series that Damien wrote a long time ago and
nobody ever reviewed, so I decided to reimplement it since the code
changed a lot since then.
Credits-to: Damien Lespiau <damien.lespiau@intel.com>
Cc: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 19 +--------
drivers/gpu/drm/i915/intel_drv.h | 1 -
drivers/gpu/drm/i915/intel_fbc.c | 77 +++++++++----------------------------
4 files changed, 20 insertions(+), 79 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index a3b22bd..6ac4ba3 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1640,7 +1640,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
seq_puts(m, "FBC enabled\n");
else
seq_printf(m, "FBC disabled: %s\n",
- intel_no_fbc_reason_str(dev_priv->fbc.no_fbc_reason));
+ dev_priv->fbc.no_fbc_reason);
if (INTEL_INFO(dev_priv)->gen >= 7)
seq_printf(m, "Compressing: %s\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8afda45..c334525 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -925,24 +925,7 @@ struct i915_fbc {
struct drm_framebuffer *fb;
} *fbc_work;
- enum no_fbc_reason {
- FBC_OK, /* FBC is enabled */
- FBC_UNSUPPORTED, /* FBC is not supported by this chipset */
- FBC_NO_OUTPUT, /* no outputs enabled to compress */
- FBC_STOLEN_TOO_SMALL, /* not enough space for buffers */
- FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */
- FBC_MODE_TOO_LARGE, /* mode too large for compression */
- FBC_BAD_PLANE, /* fbc not supported on plane */
- FBC_NOT_TILED, /* buffer not tiled */
- FBC_MULTIPLE_PIPES, /* more than one pipe active */
- FBC_MODULE_PARAM,
- FBC_CHIP_DEFAULT, /* disabled by default on this chip */
- FBC_ROTATION, /* rotation is not supported */
- FBC_IN_DBG_MASTER, /* kernel debugger is active */
- FBC_BAD_STRIDE, /* stride is not supported */
- FBC_PIXEL_RATE, /* pixel rate is too big */
- FBC_PIXEL_FORMAT /* pixel format is invalid */
- } no_fbc_reason;
+ const char *no_fbc_reason;
bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
void (*enable_fbc)(struct intel_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 27dccf3..dc55e4c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1287,7 +1287,6 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
enum fb_op_origin origin);
void intel_fbc_flush(struct drm_i915_private *dev_priv,
unsigned int frontbuffer_bits, enum fb_op_origin origin);
-const char *intel_no_fbc_reason_str(enum no_fbc_reason reason);
void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
/* intel_hdmi.c */
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index cf47352..d9d7e54 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -471,55 +471,14 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc)
mutex_unlock(&dev_priv->fbc.lock);
}
-const char *intel_no_fbc_reason_str(enum no_fbc_reason reason)
-{
- switch (reason) {
- case FBC_OK:
- return "FBC enabled but currently disabled in hardware";
- case FBC_UNSUPPORTED:
- return "unsupported by this chipset";
- case FBC_NO_OUTPUT:
- return "no output";
- case FBC_STOLEN_TOO_SMALL:
- return "not enough stolen memory";
- case FBC_UNSUPPORTED_MODE:
- return "mode incompatible with compression";
- case FBC_MODE_TOO_LARGE:
- return "mode too large for compression";
- case FBC_BAD_PLANE:
- return "FBC unsupported on plane";
- case FBC_NOT_TILED:
- return "framebuffer not tiled or fenced";
- case FBC_MULTIPLE_PIPES:
- return "more than one pipe active";
- case FBC_MODULE_PARAM:
- return "disabled per module param";
- case FBC_CHIP_DEFAULT:
- return "disabled per chip default";
- case FBC_ROTATION:
- return "rotation unsupported";
- case FBC_IN_DBG_MASTER:
- return "Kernel debugger is active";
- case FBC_BAD_STRIDE:
- return "framebuffer stride not supported";
- case FBC_PIXEL_RATE:
- return "pixel rate is too big";
- case FBC_PIXEL_FORMAT:
- return "pixel format is invalid";
- default:
- MISSING_CASE(reason);
- return "unknown reason";
- }
-}
-
static void set_no_fbc_reason(struct drm_i915_private *dev_priv,
- enum no_fbc_reason reason)
+ const char *reason)
{
if (dev_priv->fbc.no_fbc_reason == reason)
return;
dev_priv->fbc.no_fbc_reason = reason;
- DRM_DEBUG_KMS("Disabling FBC: %s\n", intel_no_fbc_reason_str(reason));
+ DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
}
static struct drm_crtc *intel_fbc_find_crtc(struct drm_i915_private *dev_priv)
@@ -862,12 +821,12 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
i915.enable_fbc = 0;
if (i915.enable_fbc < 0) {
- set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT);
+ set_no_fbc_reason(dev_priv, "disabled per chip default");
goto out_disable;
}
if (!i915.enable_fbc) {
- set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM);
+ set_no_fbc_reason(dev_priv, "disabled per module param");
goto out_disable;
}
@@ -882,12 +841,12 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
*/
crtc = intel_fbc_find_crtc(dev_priv);
if (!crtc) {
- set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT);
+ set_no_fbc_reason(dev_priv, "no output");
goto out_disable;
}
if (!multiple_pipes_ok(dev_priv)) {
- set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES);
+ set_no_fbc_reason(dev_priv, "more than one pipe active");
goto out_disable;
}
@@ -898,18 +857,18 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
(adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
- set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE);
+ set_no_fbc_reason(dev_priv, "incompatible mode");
goto out_disable;
}
if (!intel_fbc_hw_tracking_covers_screen(intel_crtc)) {
- set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE);
+ set_no_fbc_reason(dev_priv, "mode too large for compression");
goto out_disable;
}
if ((INTEL_INFO(dev_priv)->gen < 4 || HAS_DDI(dev_priv)) &&
intel_crtc->plane != PLANE_A) {
- set_no_fbc_reason(dev_priv, FBC_BAD_PLANE);
+ set_no_fbc_reason(dev_priv, "FBC unsupported on plane");
goto out_disable;
}
@@ -918,28 +877,28 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
*/
if (obj->tiling_mode != I915_TILING_X ||
obj->fence_reg == I915_FENCE_REG_NONE) {
- set_no_fbc_reason(dev_priv, FBC_NOT_TILED);
+ set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced");
goto out_disable;
}
if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) &&
crtc->primary->state->rotation != BIT(DRM_ROTATE_0)) {
- set_no_fbc_reason(dev_priv, FBC_ROTATION);
+ set_no_fbc_reason(dev_priv, "rotation unsupported");
goto out_disable;
}
if (!stride_is_valid(dev_priv, fb->pitches[0])) {
- set_no_fbc_reason(dev_priv, FBC_BAD_STRIDE);
+ set_no_fbc_reason(dev_priv, "framebuffer stride not supported");
goto out_disable;
}
if (!pixel_format_is_valid(fb)) {
- set_no_fbc_reason(dev_priv, FBC_PIXEL_FORMAT);
+ set_no_fbc_reason(dev_priv, "pixel format is invalid");
goto out_disable;
}
/* If the kernel debugger is active, always disable compression */
if (in_dbg_master()) {
- set_no_fbc_reason(dev_priv, FBC_IN_DBG_MASTER);
+ set_no_fbc_reason(dev_priv, "Kernel debugger is active");
goto out_disable;
}
@@ -947,12 +906,12 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
ilk_pipe_pixel_rate(intel_crtc->config) >=
dev_priv->cdclk_freq * 95 / 100) {
- set_no_fbc_reason(dev_priv, FBC_PIXEL_RATE);
+ set_no_fbc_reason(dev_priv, "pixel rate is too big");
goto out_disable;
}
if (intel_fbc_setup_cfb(intel_crtc)) {
- set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL);
+ set_no_fbc_reason(dev_priv, "not enough stolen memory");
goto out_disable;
}
@@ -995,7 +954,7 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
}
intel_fbc_schedule_enable(intel_crtc);
- dev_priv->fbc.no_fbc_reason = FBC_OK;
+ dev_priv->fbc.no_fbc_reason = "FBC enabled (not necessarily active)\n";
return;
out_disable:
@@ -1088,7 +1047,7 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
if (!HAS_FBC(dev_priv)) {
dev_priv->fbc.enabled = false;
- dev_priv->fbc.no_fbc_reason = FBC_UNSUPPORTED;
+ dev_priv->fbc.no_fbc_reason = "unsupported by this chipset";
return;
}
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 02/18] drm/i915: don't stop+start FBC at every flip
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
2015-10-20 13:49 ` [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-21 7:04 ` Daniel Vetter
2015-10-20 13:49 ` [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush Paulo Zanoni
` (16 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
The hardware already takes care of disabling and recompressing FBC
when we do a page flip, so all we need to do is to update the fence
registers and move on.
One of the important things to notice is that on the pre-gen6
platforms the fence is programmed on the FBC control register and the
documentation says we can't update the control register while FBC is
enabled. This would basically mean we'd have to to disable+enable FBC
at every flip in order to make sure the hardware tracking still works,
which doesn't seem to make too much sense. So I sent an email to the
hardware team requesting some clarification. The information I got was
this:
"I don't think any hardware is latching on to 0x100100, 0x100104, or
the old fence number in FBC_CTL. Instructions against changing on the
fly would be to simplify testing and ensure you don't miss any
invalidation that happened right at that time."
So I guess we're fine for flips. But I can't really say I tested FBC
on these ancient platforms - nor that I'll ever propose enabling FBC
by default on them exactly because of problems like these.
Testcase: igt/kms_frontbuffer_tracking/fbc*-fliptrack
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_reg.h | 3 +
drivers/gpu/drm/i915/intel_display.c | 1 -
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_fbc.c | 98 +++++++++++++++++++++++++++++++-
drivers/gpu/drm/i915/intel_frontbuffer.c | 1 +
6 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c334525..f04f56f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -930,6 +930,7 @@ struct i915_fbc {
bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
void (*enable_fbc)(struct intel_crtc *crtc);
void (*disable_fbc)(struct drm_i915_private *dev_priv);
+ void (*flip_prepare)(struct drm_i915_private *dev_priv);
};
/**
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9ebf032..3620b59 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2028,6 +2028,7 @@ enum skl_disp_power_wells {
#define FBC_CTL_C3_IDLE (1<<13)
#define FBC_CTL_STRIDE_SHIFT (5)
#define FBC_CTL_FENCENO_SHIFT (0)
+#define FBC_CTL_FENCENO_MASK 0xF
#define FBC_COMMAND 0x0320c
#define FBC_CMD_COMPRESS (1<<0)
#define FBC_STATUS 0x03210
@@ -2064,6 +2065,7 @@ enum skl_disp_power_wells {
#define DPFC_CTL_LIMIT_1X (0<<6)
#define DPFC_CTL_LIMIT_2X (1<<6)
#define DPFC_CTL_LIMIT_4X (2<<6)
+#define DPFC_CTL_FENCE_MASK 0xF
#define DPFC_RECOMP_CTL 0x320c
#define DPFC_RECOMP_STALL_EN (1<<27)
#define DPFC_RECOMP_STALL_WM_SHIFT (16)
@@ -2086,6 +2088,7 @@ enum skl_disp_power_wells {
#define FBC_CTL_FALSE_COLOR (1<<10)
/* The bit 28-8 is reserved */
#define DPFC_RESERVED (0x1FFFFF00)
+#define ILK_DPFC_FENCE_MASK 0xF
#define ILK_DPFC_RECOMP_CTL 0x4320c
#define ILK_DPFC_STATUS 0x43210
#define ILK_DPFC_FENCE_YOFF 0x43218
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1fc1d24..e83a428 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11470,7 +11470,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
to_intel_plane(primary)->frontbuffer_bit);
mutex_unlock(&dev->struct_mutex);
- intel_fbc_disable_crtc(intel_crtc);
intel_frontbuffer_flip_prepare(dev,
to_intel_plane(primary)->frontbuffer_bit);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index dc55e4c..1e08c8a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1287,6 +1287,8 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
enum fb_op_origin origin);
void intel_fbc_flush(struct drm_i915_private *dev_priv,
unsigned int frontbuffer_bits, enum fb_op_origin origin);
+void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
+ unsigned int frontbuffer_bits);
void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
/* intel_hdmi.c */
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index d9d7e54..9477379 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -82,6 +82,22 @@ static void i8xx_fbc_disable(struct drm_i915_private *dev_priv)
DRM_DEBUG_KMS("disabled FBC\n");
}
+static void i8xx_fbc_flip_prepare(struct drm_i915_private *dev_priv)
+{
+ struct intel_crtc *crtc = dev_priv->fbc.crtc;
+ struct drm_framebuffer *fb = crtc->base.primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ uint32_t val;
+
+ /* Although the documentation suggests we can't change DPFC_CONTROL
+ * while compression is enabled, the hardware guys said that updating
+ * the fence register bits during a flip is fine. */
+ val = I915_READ(FBC_CONTROL);
+ val &= ~FBC_CTL_FENCENO_MASK;
+ val |= obj->fence_reg;
+ I915_WRITE(FBC_CONTROL, val);
+}
+
static void i8xx_fbc_enable(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
@@ -161,6 +177,22 @@ static void g4x_fbc_enable(struct intel_crtc *crtc)
DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
}
+static void g4x_fbc_flip_prepare(struct drm_i915_private *dev_priv)
+{
+ struct intel_crtc *crtc = dev_priv->fbc.crtc;
+ struct drm_framebuffer *fb = crtc->base.primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ uint32_t val;
+
+ /* Although the documentation suggests we can't change DPFC_CONTROL
+ * while compression is enabled, the hardware guys said that updating
+ * the fence register bits during a flip is fine. */
+ val = I915_READ(DPFC_CONTROL);
+ val &= ~DPFC_CTL_FENCE_MASK;
+ val |= obj->fence_reg;
+ I915_WRITE(DPFC_CONTROL, val);
+}
+
static void g4x_fbc_disable(struct drm_i915_private *dev_priv)
{
u32 dpfc_ctl;
@@ -236,6 +268,31 @@ static void ilk_fbc_enable(struct intel_crtc *crtc)
DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
}
+static void ilk_fbc_flip_prepare(struct drm_i915_private *dev_priv)
+{
+ struct intel_crtc *crtc = dev_priv->fbc.crtc;
+ struct drm_framebuffer *fb = crtc->base.primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ uint32_t val;
+
+ /* Although the documentation suggests we can't change DPFC_CONTROL
+ * while compression is enabled, the hardware guys said that updating
+ * the fence register bits during a flip is fine. */
+ val = I915_READ(ILK_DPFC_CONTROL);
+ val &= ~ILK_DPFC_FENCE_MASK;
+ val |= obj->fence_reg;
+ I915_WRITE(ILK_DPFC_CONTROL, val);
+}
+
+static void snb_fbc_flip_prepare(struct drm_i915_private *dev_priv)
+{
+ struct intel_crtc *crtc = dev_priv->fbc.crtc;
+ struct drm_framebuffer *fb = crtc->base.primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+
+ I915_WRITE(SNB_DPFC_CTL_SA, SNB_CPU_FENCE_ENABLE | obj->fence_reg);
+}
+
static void ilk_fbc_disable(struct drm_i915_private *dev_priv)
{
u32 dpfc_ctl;
@@ -1020,14 +1077,44 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
if (origin == ORIGIN_GTT)
return;
+ if (origin == ORIGIN_FLIP && dev_priv->fbc.enabled)
+ return;
mutex_lock(&dev_priv->fbc.lock);
dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
if (!dev_priv->fbc.busy_bits) {
- __intel_fbc_disable(dev_priv);
- __intel_fbc_update(dev_priv);
+ if (origin == ORIGIN_FLIP) {
+ __intel_fbc_update(dev_priv);
+ } else {
+ __intel_fbc_disable(dev_priv);
+ __intel_fbc_update(dev_priv);
+ }
+ }
+
+ mutex_unlock(&dev_priv->fbc.lock);
+}
+
+void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
+ unsigned int frontbuffer_bits)
+{
+ unsigned int fbc_bits;
+
+ if (!fbc_supported(dev_priv))
+ return;
+
+ mutex_lock(&dev_priv->fbc.lock);
+
+ if (dev_priv->fbc.enabled) {
+ fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
+ if (fbc_bits & frontbuffer_bits)
+ dev_priv->fbc.flip_prepare(dev_priv);
+ } else if (dev_priv->fbc.fbc_work) {
+ fbc_bits = INTEL_FRONTBUFFER_PRIMARY(
+ dev_priv->fbc.fbc_work->crtc->pipe);
+ if (fbc_bits & frontbuffer_bits)
+ __intel_fbc_disable(dev_priv);
}
mutex_unlock(&dev_priv->fbc.lock);
@@ -1063,18 +1150,25 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
dev_priv->fbc.enable_fbc = gen7_fbc_enable;
dev_priv->fbc.disable_fbc = ilk_fbc_disable;
+ dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
} else if (INTEL_INFO(dev_priv)->gen >= 5) {
dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
dev_priv->fbc.enable_fbc = ilk_fbc_enable;
dev_priv->fbc.disable_fbc = ilk_fbc_disable;
+ if (INTEL_INFO(dev_priv)->gen == 5)
+ dev_priv->fbc.flip_prepare = ilk_fbc_flip_prepare;
+ else
+ dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
} else if (IS_GM45(dev_priv)) {
dev_priv->fbc.fbc_enabled = g4x_fbc_enabled;
dev_priv->fbc.enable_fbc = g4x_fbc_enable;
dev_priv->fbc.disable_fbc = g4x_fbc_disable;
+ dev_priv->fbc.flip_prepare = g4x_fbc_flip_prepare;
} else {
dev_priv->fbc.fbc_enabled = i8xx_fbc_enabled;
dev_priv->fbc.enable_fbc = i8xx_fbc_enable;
dev_priv->fbc.disable_fbc = i8xx_fbc_disable;
+ dev_priv->fbc.flip_prepare = i8xx_fbc_flip_prepare;
/* This value was pulled out of someone's hat */
I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
index ac85357..31a1ad3 100644
--- a/drivers/gpu/drm/i915/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
@@ -192,6 +192,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,
mutex_unlock(&dev_priv->fb_tracking.lock);
intel_psr_single_frame_update(dev, frontbuffer_bits);
+ intel_fbc_flip_prepare(dev_priv, frontbuffer_bits);
}
/**
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
2015-10-20 13:49 ` [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string Paulo Zanoni
2015-10-20 13:49 ` [PATCH 02/18] drm/i915: don't stop+start FBC at every flip Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 15:59 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code Paulo Zanoni
` (15 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
There's no need to stop and restart FBC: a nuke should be fine.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 9477379..b9cfd16 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -1088,8 +1088,10 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
if (origin == ORIGIN_FLIP) {
__intel_fbc_update(dev_priv);
} else {
- __intel_fbc_disable(dev_priv);
- __intel_fbc_update(dev_priv);
+ if (dev_priv->fbc.enabled)
+ intel_fbc_nuke(dev_priv);
+ else
+ __intel_fbc_update(dev_priv);
}
}
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (2 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 15:52 ` Chris Wilson
2015-10-22 7:52 ` Maarten Lankhorst
2015-10-20 13:49 ` [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work Paulo Zanoni
` (14 subsequent siblings)
18 siblings, 2 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
We're going to kill intel_fbc_find_crtc(), that's why a big part of
the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index b9cfd16..1162787 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct drm_i915_private *dev_priv,
DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
}
+static bool crtc_is_valid(struct intel_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ enum pipe pipe = crtc->pipe;
+
+ if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) &&
+ pipe != PIPE_A)
+ return false;
+
+ return intel_crtc_active(&crtc->base) &&
+ to_intel_plane_state(crtc->base.primary->state)->visible &&
+ crtc->base.primary->fb != NULL;
+}
+
static struct drm_crtc *intel_fbc_find_crtc(struct drm_i915_private *dev_priv)
{
struct drm_crtc *crtc = NULL, *tmp_crtc;
enum pipe pipe;
- bool pipe_a_only = false;
-
- if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)
- pipe_a_only = true;
for_each_pipe(dev_priv, pipe) {
tmp_crtc = dev_priv->pipe_to_crtc_mapping[pipe];
- if (intel_crtc_active(tmp_crtc) &&
- to_intel_plane_state(tmp_crtc->primary->state)->visible)
+ if (crtc_is_valid(to_intel_crtc(tmp_crtc)))
crtc = tmp_crtc;
-
- if (pipe_a_only)
- break;
}
- if (!crtc || crtc->primary->fb == NULL)
+ if (!crtc)
return NULL;
return crtc;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (3 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 16:03 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 06/18] drm/i915: use struct intel_crtc *crtc at __intel_fbc_update() Paulo Zanoni
` (13 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
This thing where we need to get the crtc either from the work
structure or the fbc structure itself is confusing and unnecessary.
Set fbc.crtc right when scheduling the enable work so we can always
use it.
Besides the immediate advantages, this is also going to make one of
the next commits much simpler.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 -
drivers/gpu/drm/i915/intel_fbc.c | 25 ++++++++++---------------
2 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f04f56f..2cb7a05 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -921,7 +921,6 @@ struct i915_fbc {
struct intel_fbc_work {
struct delayed_work work;
- struct intel_crtc *crtc;
struct drm_framebuffer *fb;
} *fbc_work;
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 1162787..dd66649 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -385,14 +385,13 @@ bool intel_fbc_enabled(struct drm_i915_private *dev_priv)
return dev_priv->fbc.enabled;
}
-static void intel_fbc_enable(struct intel_crtc *crtc,
- const struct drm_framebuffer *fb)
+static void intel_fbc_enable(const struct drm_framebuffer *fb)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = fb->dev->dev_private;
+ struct intel_crtc *crtc = dev_priv->fbc.crtc;
dev_priv->fbc.enable_fbc(crtc);
- dev_priv->fbc.crtc = crtc;
dev_priv->fbc.fb_id = fb->base.id;
dev_priv->fbc.y = crtc->base.y;
}
@@ -402,8 +401,8 @@ static void intel_fbc_work_fn(struct work_struct *__work)
struct intel_fbc_work *work =
container_of(to_delayed_work(__work),
struct intel_fbc_work, work);
- struct drm_i915_private *dev_priv = work->crtc->base.dev->dev_private;
- struct drm_framebuffer *crtc_fb = work->crtc->base.primary->fb;
+ struct drm_i915_private *dev_priv = work->fb->dev->dev_private;
+ struct drm_framebuffer *crtc_fb = dev_priv->fbc.crtc->base.primary->fb;
mutex_lock(&dev_priv->fbc.lock);
if (work == dev_priv->fbc.fbc_work) {
@@ -411,7 +410,7 @@ static void intel_fbc_work_fn(struct work_struct *__work)
* the prior work.
*/
if (crtc_fb == work->fb)
- intel_fbc_enable(work->crtc, work->fb);
+ intel_fbc_enable(work->fb);
dev_priv->fbc.fbc_work = NULL;
}
@@ -453,15 +452,15 @@ static void intel_fbc_schedule_enable(struct intel_crtc *crtc)
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
intel_fbc_cancel_work(dev_priv);
+ dev_priv->fbc.crtc = crtc;
work = kzalloc(sizeof(*work), GFP_KERNEL);
if (work == NULL) {
DRM_ERROR("Failed to allocate FBC work structure\n");
- intel_fbc_enable(crtc, crtc->base.primary->fb);
+ intel_fbc_enable(crtc->base.primary->fb);
return;
}
- work->crtc = crtc;
work->fb = crtc->base.primary->fb;
INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn);
@@ -1059,11 +1058,8 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
mutex_lock(&dev_priv->fbc.lock);
- if (dev_priv->fbc.enabled)
+ if (dev_priv->fbc.enabled || dev_priv->fbc.fbc_work)
fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
- else if (dev_priv->fbc.fbc_work)
- fbc_bits = INTEL_FRONTBUFFER_PRIMARY(
- dev_priv->fbc.fbc_work->crtc->pipe);
else
fbc_bits = dev_priv->fbc.possible_framebuffer_bits;
@@ -1119,8 +1115,7 @@ void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
if (fbc_bits & frontbuffer_bits)
dev_priv->fbc.flip_prepare(dev_priv);
} else if (dev_priv->fbc.fbc_work) {
- fbc_bits = INTEL_FRONTBUFFER_PRIMARY(
- dev_priv->fbc.fbc_work->crtc->pipe);
+ fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
if (fbc_bits & frontbuffer_bits)
__intel_fbc_disable(dev_priv);
}
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 06/18] drm/i915: use struct intel_crtc *crtc at __intel_fbc_update()
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (4 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 13:49 ` [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments Paulo Zanoni
` (12 subsequent siblings)
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
This change was part of the commit that makes intel_fbc_update()
receive an intel_crtc as argument instead of dev_priv, but since it
was polluting the diff with too many chunks I decided to move it to
its own commit.
It seems that our developers are favoring having this instead of the
old combination drm_crtc *crtc + intel_crtc *intel_crtc, and on the
mentioned commit we'll get rid of the drm_crtc variable, so let's do
an intermediate commit with the rename, so on the next commit we'll
have just struct intel_crtc *crtc.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index dd66649..e856304 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -870,8 +870,8 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
*/
static void __intel_fbc_update(struct drm_i915_private *dev_priv)
{
- struct drm_crtc *crtc = NULL;
- struct intel_crtc *intel_crtc;
+ struct drm_crtc *drm_crtc = NULL;
+ struct intel_crtc *crtc;
struct drm_framebuffer *fb;
struct drm_i915_gem_object *obj;
const struct drm_display_mode *adjusted_mode;
@@ -901,8 +901,8 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
* - new fb is too large to fit in compressed buffer
* - going to an unsupported config (interlace, pixel multiply, etc.)
*/
- crtc = intel_fbc_find_crtc(dev_priv);
- if (!crtc) {
+ drm_crtc = intel_fbc_find_crtc(dev_priv);
+ if (!drm_crtc) {
set_no_fbc_reason(dev_priv, "no output");
goto out_disable;
}
@@ -912,10 +912,10 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
goto out_disable;
}
- intel_crtc = to_intel_crtc(crtc);
- fb = crtc->primary->fb;
+ crtc = to_intel_crtc(drm_crtc);
+ fb = crtc->base.primary->fb;
obj = intel_fb_obj(fb);
- adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+ adjusted_mode = &crtc->config->base.adjusted_mode;
if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
(adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
@@ -923,13 +923,13 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
goto out_disable;
}
- if (!intel_fbc_hw_tracking_covers_screen(intel_crtc)) {
+ if (!intel_fbc_hw_tracking_covers_screen(crtc)) {
set_no_fbc_reason(dev_priv, "mode too large for compression");
goto out_disable;
}
if ((INTEL_INFO(dev_priv)->gen < 4 || HAS_DDI(dev_priv)) &&
- intel_crtc->plane != PLANE_A) {
+ crtc->plane != PLANE_A) {
set_no_fbc_reason(dev_priv, "FBC unsupported on plane");
goto out_disable;
}
@@ -943,7 +943,7 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
goto out_disable;
}
if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) &&
- crtc->primary->state->rotation != BIT(DRM_ROTATE_0)) {
+ crtc->base.primary->state->rotation != BIT(DRM_ROTATE_0)) {
set_no_fbc_reason(dev_priv, "rotation unsupported");
goto out_disable;
}
@@ -966,13 +966,13 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
/* WaFbcExceedCdClockThreshold:hsw,bdw */
if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
- ilk_pipe_pixel_rate(intel_crtc->config) >=
+ ilk_pipe_pixel_rate(crtc->config) >=
dev_priv->cdclk_freq * 95 / 100) {
set_no_fbc_reason(dev_priv, "pixel rate is too big");
goto out_disable;
}
- if (intel_fbc_setup_cfb(intel_crtc)) {
+ if (intel_fbc_setup_cfb(crtc)) {
set_no_fbc_reason(dev_priv, "not enough stolen memory");
goto out_disable;
}
@@ -982,9 +982,9 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
* cannot be unpinned (and have its GTT offset and fence revoked)
* without first being decoupled from the scanout and FBC disabled.
*/
- if (dev_priv->fbc.crtc == intel_crtc &&
+ if (dev_priv->fbc.crtc == crtc &&
dev_priv->fbc.fb_id == fb->base.id &&
- dev_priv->fbc.y == crtc->y)
+ dev_priv->fbc.y == crtc->base.y)
return;
if (intel_fbc_enabled(dev_priv)) {
@@ -1015,7 +1015,7 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
__intel_fbc_disable(dev_priv);
}
- intel_fbc_schedule_enable(intel_crtc);
+ intel_fbc_schedule_enable(crtc);
dev_priv->fbc.no_fbc_reason = "FBC enabled (not necessarily active)\n";
return;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (5 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 06/18] drm/i915: use struct intel_crtc *crtc at __intel_fbc_update() Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-21 12:37 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 08/18] drm/i915: pass the crtc as an argument to intel_fbc_update() Paulo Zanoni
` (11 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
Don't try to list in comments the cases where we should enable or
disable FBC: it varies a lot with the hardware generations and the
code should be the documentation. Also notice that there's already a
huge gap between the comments and what's in the code.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 26 ++------------------------
1 file changed, 2 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index e856304..5fa4ce4 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -853,20 +853,8 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
* __intel_fbc_update - enable/disable FBC as needed, unlocked
* @dev_priv: i915 device instance
*
- * Set up the framebuffer compression hardware at mode set time. We
- * enable it if possible:
- * - plane A only (on pre-965)
- * - no pixel mulitply/line duplication
- * - no alpha buffer discard
- * - no dual wide
- * - framebuffer <= max_hdisplay in width, max_vdisplay in height
- *
- * We can't assume that any compression will take place (worst case),
- * so the compressed buffer has to be the same size as the uncompressed
- * one. It also must reside (along with the line length buffer) in
- * stolen memory.
- *
- * We need to enable/disable FBC on a global basis.
+ * This function completely reevaluates the status of FBC, then enables,
+ * disables or maintains it on the same state.
*/
static void __intel_fbc_update(struct drm_i915_private *dev_priv)
{
@@ -878,7 +866,6 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
- /* disable framebuffer compression in vGPU */
if (intel_vgpu_active(dev_priv->dev))
i915.enable_fbc = 0;
@@ -892,15 +879,6 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
goto out_disable;
}
- /*
- * If FBC is already on, we just have to verify that we can
- * keep it that way...
- * Need to disable if:
- * - more than one pipe is active
- * - changing FBC params (stride, fence, mode)
- * - new fb is too large to fit in compressed buffer
- * - going to an unsupported config (interlace, pixel multiply, etc.)
- */
drm_crtc = intel_fbc_find_crtc(dev_priv);
if (!drm_crtc) {
set_no_fbc_reason(dev_priv, "no output");
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 08/18] drm/i915: pass the crtc as an argument to intel_fbc_update()
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (6 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 13:49 ` [PATCH 09/18] drm/i915: don't disable_fbc() if FBC is already disabled Paulo Zanoni
` (10 subsequent siblings)
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
There's no need to reevaluate the status of every single crtc when a
single crtc changes its state.
With this, we're cutting the case where due to a change in pipe B,
intel_fbc_update() is called, then intel_fbc_find_crtc() concludes FBC
should be enabled on pipe A, then it completely rechecks the state of
pipe A only to conclude FBC should remain enabled on pipe A. If any
change on pipe A triggers a need to recompute whether FBC is valid on
pipe A, then at some point someone is going to call
intel_fbc_update(PIPE_A).
The addition of intel_fbc_deactivate() is necessary so we keep track
of the previously selected CRTC when we do invalidate/flush. We're
also going to continue the enable/disable/activate/deactivate concept
in the next patches.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 3 +-
drivers/gpu/drm/i915/intel_drv.h | 2 +-
drivers/gpu/drm/i915/intel_fbc.c | 70 ++++++++++++++++--------------------
3 files changed, 32 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e83a428..3050bfe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4778,7 +4778,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
{
struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_plane *plane;
if (atomic->wait_vblank)
@@ -4793,7 +4792,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
intel_update_watermarks(&crtc->base);
if (atomic->update_fbc)
- intel_fbc_update(dev_priv);
+ intel_fbc_update(crtc);
if (atomic->post_enable_primary)
intel_post_enable_primary(&crtc->base);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1e08c8a..27c8403 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1278,7 +1278,7 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
/* intel_fbc.c */
bool intel_fbc_enabled(struct drm_i915_private *dev_priv);
-void intel_fbc_update(struct drm_i915_private *dev_priv);
+void intel_fbc_update(struct intel_crtc *crtc);
void intel_fbc_init(struct drm_i915_private *dev_priv);
void intel_fbc_disable(struct drm_i915_private *dev_priv);
void intel_fbc_disable_crtc(struct intel_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 5fa4ce4..2a55c1b 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -482,13 +482,18 @@ static void intel_fbc_schedule_enable(struct intel_crtc *crtc)
schedule_delayed_work(&work->work, msecs_to_jiffies(50));
}
-static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
+static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
{
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
intel_fbc_cancel_work(dev_priv);
dev_priv->fbc.disable_fbc(dev_priv);
+}
+
+static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
+{
+ intel_fbc_deactivate(dev_priv);
dev_priv->fbc.crtc = NULL;
}
@@ -551,24 +556,6 @@ static bool crtc_is_valid(struct intel_crtc *crtc)
crtc->base.primary->fb != NULL;
}
-static struct drm_crtc *intel_fbc_find_crtc(struct drm_i915_private *dev_priv)
-{
- struct drm_crtc *crtc = NULL, *tmp_crtc;
- enum pipe pipe;
-
- for_each_pipe(dev_priv, pipe) {
- tmp_crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-
- if (crtc_is_valid(to_intel_crtc(tmp_crtc)))
- crtc = tmp_crtc;
- }
-
- if (!crtc)
- return NULL;
-
- return crtc;
-}
-
static bool multiple_pipes_ok(struct drm_i915_private *dev_priv)
{
enum pipe pipe;
@@ -851,21 +838,28 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
/**
* __intel_fbc_update - enable/disable FBC as needed, unlocked
- * @dev_priv: i915 device instance
+ * @crtc: the CRTC that triggered the update
*
* This function completely reevaluates the status of FBC, then enables,
* disables or maintains it on the same state.
*/
-static void __intel_fbc_update(struct drm_i915_private *dev_priv)
+static void __intel_fbc_update(struct intel_crtc *crtc)
{
- struct drm_crtc *drm_crtc = NULL;
- struct intel_crtc *crtc;
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_framebuffer *fb;
struct drm_i915_gem_object *obj;
const struct drm_display_mode *adjusted_mode;
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
+ if (!multiple_pipes_ok(dev_priv)) {
+ set_no_fbc_reason(dev_priv, "more than one pipe active");
+ goto out_disable;
+ }
+
+ if (dev_priv->fbc.crtc != NULL && dev_priv->fbc.crtc != crtc)
+ return;
+
if (intel_vgpu_active(dev_priv->dev))
i915.enable_fbc = 0;
@@ -879,18 +873,11 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
goto out_disable;
}
- drm_crtc = intel_fbc_find_crtc(dev_priv);
- if (!drm_crtc) {
+ if (!crtc_is_valid(crtc)) {
set_no_fbc_reason(dev_priv, "no output");
goto out_disable;
}
- if (!multiple_pipes_ok(dev_priv)) {
- set_no_fbc_reason(dev_priv, "more than one pipe active");
- goto out_disable;
- }
-
- crtc = to_intel_crtc(drm_crtc);
fb = crtc->base.primary->fb;
obj = intel_fb_obj(fb);
adjusted_mode = &crtc->config->base.adjusted_mode;
@@ -962,7 +949,8 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
*/
if (dev_priv->fbc.crtc == crtc &&
dev_priv->fbc.fb_id == fb->base.id &&
- dev_priv->fbc.y == crtc->base.y)
+ dev_priv->fbc.y == crtc->base.y &&
+ dev_priv->fbc.enabled)
return;
if (intel_fbc_enabled(dev_priv)) {
@@ -1008,17 +996,19 @@ out_disable:
/*
* intel_fbc_update - enable/disable FBC as needed
- * @dev_priv: i915 device instance
+ * @crtc: the CRTC that triggered the update
*
* This function reevaluates the overall state and enables or disables FBC.
*/
-void intel_fbc_update(struct drm_i915_private *dev_priv)
+void intel_fbc_update(struct intel_crtc *crtc)
{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
if (!fbc_supported(dev_priv))
return;
mutex_lock(&dev_priv->fbc.lock);
- __intel_fbc_update(dev_priv);
+ __intel_fbc_update(crtc);
mutex_unlock(&dev_priv->fbc.lock);
}
@@ -1044,7 +1034,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits);
if (dev_priv->fbc.busy_bits)
- __intel_fbc_disable(dev_priv);
+ intel_fbc_deactivate(dev_priv);
mutex_unlock(&dev_priv->fbc.lock);
}
@@ -1064,14 +1054,14 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
- if (!dev_priv->fbc.busy_bits) {
+ if (!dev_priv->fbc.busy_bits && dev_priv->fbc.crtc) {
if (origin == ORIGIN_FLIP) {
- __intel_fbc_update(dev_priv);
+ __intel_fbc_update(dev_priv->fbc.crtc);
} else {
if (dev_priv->fbc.enabled)
intel_fbc_nuke(dev_priv);
else
- __intel_fbc_update(dev_priv);
+ __intel_fbc_update(dev_priv->fbc.crtc);
}
}
@@ -1095,7 +1085,7 @@ void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
} else if (dev_priv->fbc.fbc_work) {
fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
if (fbc_bits & frontbuffer_bits)
- __intel_fbc_disable(dev_priv);
+ intel_fbc_deactivate(dev_priv);
}
mutex_unlock(&dev_priv->fbc.lock);
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 09/18] drm/i915: don't disable_fbc() if FBC is already disabled
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (7 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 08/18] drm/i915: pass the crtc as an argument to intel_fbc_update() Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 13:49 ` [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology Paulo Zanoni
` (9 subsequent siblings)
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
If FBC is disabled we will still call intel_fbc_invalidate(), and as a
result we may call intel_fbc_deactivate(), which will try to touch
registers.
I'm pretty sure I saw this happen on a runtime suspended device, and
I'm almost sure I was running igt/pm_rpm. It produced the "you touched
registers while the device is suspended" WARNs. But this was some time
ago and I can't remember exactly which conditions were necessary to
reproduce the problem.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 2a55c1b..a114ee3 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -488,7 +488,8 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
intel_fbc_cancel_work(dev_priv);
- dev_priv->fbc.disable_fbc(dev_priv);
+ if (dev_priv->fbc.enabled)
+ dev_priv->fbc.disable_fbc(dev_priv);
}
static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (8 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 09/18] drm/i915: don't disable_fbc() if FBC is already disabled Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-21 12:34 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 11/18] drm/i915: refactor FBC deactivation at init Paulo Zanoni
` (8 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
The long term goal is to have enable/disable as the higher level
functions and activate/deactivate as the lower level functions, just
like we do for PSR and for the CRTC. Let's start this by renaming the
functions that touch the hardware state and their wrappers.
The conversion to the full correct terminology is not complete yet, so
there is still some confusion that will be solved in the next patches.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 10 ++-
drivers/gpu/drm/i915/intel_display.c | 4 +-
drivers/gpu/drm/i915/intel_drv.h | 2 +-
drivers/gpu/drm/i915/intel_fbc.c | 116 +++++++++++++++++------------------
drivers/gpu/drm/i915/intel_pm.c | 2 +-
6 files changed, 67 insertions(+), 69 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 6ac4ba3..3386493 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1636,7 +1636,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
intel_runtime_pm_get(dev_priv);
mutex_lock(&dev_priv->fbc.lock);
- if (intel_fbc_enabled(dev_priv))
+ if (intel_fbc_is_active(dev_priv))
seq_puts(m, "FBC enabled\n");
else
seq_printf(m, "FBC disabled: %s\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2cb7a05..9c9035a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -915,9 +915,7 @@ struct i915_fbc {
bool false_color;
- /* Tracks whether the HW is actually enabled, not whether the feature is
- * possible. */
- bool enabled;
+ bool active;
struct intel_fbc_work {
struct delayed_work work;
@@ -926,9 +924,9 @@ struct i915_fbc {
const char *no_fbc_reason;
- bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
- void (*enable_fbc)(struct intel_crtc *crtc);
- void (*disable_fbc)(struct drm_i915_private *dev_priv);
+ bool (*is_active)(struct drm_i915_private *dev_priv);
+ void (*activate)(struct intel_crtc *crtc);
+ void (*deactivate)(struct drm_i915_private *dev_priv);
void (*flip_prepare)(struct drm_i915_private *dev_priv);
};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3050bfe..fcaf865 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3173,8 +3173,8 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (dev_priv->fbc.disable_fbc)
- dev_priv->fbc.disable_fbc(dev_priv);
+ if (dev_priv->fbc.deactivate)
+ dev_priv->fbc.deactivate(dev_priv);
dev_priv->display.update_primary_plane(crtc, fb, x, y);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 27c8403..7203087 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1277,7 +1277,7 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
#endif
/* intel_fbc.c */
-bool intel_fbc_enabled(struct drm_i915_private *dev_priv);
+bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
void intel_fbc_update(struct intel_crtc *crtc);
void intel_fbc_init(struct drm_i915_private *dev_priv);
void intel_fbc_disable(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index a114ee3..29becf7 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -43,7 +43,7 @@
static inline bool fbc_supported(struct drm_i915_private *dev_priv)
{
- return dev_priv->fbc.enable_fbc != NULL;
+ return dev_priv->fbc.activate != NULL;
}
/*
@@ -59,11 +59,11 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)
return crtc->base.y - crtc->adjusted_y;
}
-static void i8xx_fbc_disable(struct drm_i915_private *dev_priv)
+static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
{
u32 fbc_ctl;
- dev_priv->fbc.enabled = false;
+ dev_priv->fbc.active = false;
/* Disable compression */
fbc_ctl = I915_READ(FBC_CONTROL);
@@ -79,7 +79,7 @@ static void i8xx_fbc_disable(struct drm_i915_private *dev_priv)
return;
}
- DRM_DEBUG_KMS("disabled FBC\n");
+ DRM_DEBUG_KMS("deactivated FBC\n");
}
static void i8xx_fbc_flip_prepare(struct drm_i915_private *dev_priv)
@@ -98,7 +98,7 @@ static void i8xx_fbc_flip_prepare(struct drm_i915_private *dev_priv)
I915_WRITE(FBC_CONTROL, val);
}
-static void i8xx_fbc_enable(struct intel_crtc *crtc)
+static void i8xx_fbc_activate(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_framebuffer *fb = crtc->base.primary->fb;
@@ -107,7 +107,7 @@ static void i8xx_fbc_enable(struct intel_crtc *crtc)
int i;
u32 fbc_ctl;
- dev_priv->fbc.enabled = true;
+ dev_priv->fbc.active = true;
/* Note: fbc.threshold == 1 for i8xx */
cfb_pitch = dev_priv->fbc.uncompressed_size / FBC_LL_SIZE;
@@ -144,23 +144,23 @@ static void i8xx_fbc_enable(struct intel_crtc *crtc)
fbc_ctl |= obj->fence_reg;
I915_WRITE(FBC_CONTROL, fbc_ctl);
- DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c\n",
+ DRM_DEBUG_KMS("activated FBC, pitch %d, yoff %d, plane %c\n",
cfb_pitch, crtc->base.y, plane_name(crtc->plane));
}
-static bool i8xx_fbc_enabled(struct drm_i915_private *dev_priv)
+static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv)
{
return I915_READ(FBC_CONTROL) & FBC_CTL_EN;
}
-static void g4x_fbc_enable(struct intel_crtc *crtc)
+static void g4x_fbc_activate(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_framebuffer *fb = crtc->base.primary->fb;
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
u32 dpfc_ctl;
- dev_priv->fbc.enabled = true;
+ dev_priv->fbc.active = true;
dpfc_ctl = DPFC_CTL_PLANE(crtc->plane) | DPFC_SR_EN;
if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
@@ -174,7 +174,7 @@ static void g4x_fbc_enable(struct intel_crtc *crtc)
/* enable it... */
I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
- DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
+ DRM_DEBUG_KMS("activated fbc on plane %c\n", plane_name(crtc->plane));
}
static void g4x_fbc_flip_prepare(struct drm_i915_private *dev_priv)
@@ -193,11 +193,11 @@ static void g4x_fbc_flip_prepare(struct drm_i915_private *dev_priv)
I915_WRITE(DPFC_CONTROL, val);
}
-static void g4x_fbc_disable(struct drm_i915_private *dev_priv)
+static void g4x_fbc_deactivate(struct drm_i915_private *dev_priv)
{
u32 dpfc_ctl;
- dev_priv->fbc.enabled = false;
+ dev_priv->fbc.active = false;
/* Disable compression */
dpfc_ctl = I915_READ(DPFC_CONTROL);
@@ -205,11 +205,11 @@ static void g4x_fbc_disable(struct drm_i915_private *dev_priv)
dpfc_ctl &= ~DPFC_CTL_EN;
I915_WRITE(DPFC_CONTROL, dpfc_ctl);
- DRM_DEBUG_KMS("disabled FBC\n");
+ DRM_DEBUG_KMS("deactivated FBC\n");
}
}
-static bool g4x_fbc_enabled(struct drm_i915_private *dev_priv)
+static bool g4x_fbc_is_active(struct drm_i915_private *dev_priv)
{
return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
}
@@ -220,7 +220,7 @@ static void intel_fbc_nuke(struct drm_i915_private *dev_priv)
POSTING_READ(MSG_FBC_REND_STATE);
}
-static void ilk_fbc_enable(struct intel_crtc *crtc)
+static void ilk_fbc_activate(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_framebuffer *fb = crtc->base.primary->fb;
@@ -229,7 +229,7 @@ static void ilk_fbc_enable(struct intel_crtc *crtc)
int threshold = dev_priv->fbc.threshold;
unsigned int y_offset;
- dev_priv->fbc.enabled = true;
+ dev_priv->fbc.active = true;
dpfc_ctl = DPFC_CTL_PLANE(crtc->plane);
if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
@@ -265,7 +265,7 @@ static void ilk_fbc_enable(struct intel_crtc *crtc)
intel_fbc_nuke(dev_priv);
- DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
+ DRM_DEBUG_KMS("activated fbc on plane %c\n", plane_name(crtc->plane));
}
static void ilk_fbc_flip_prepare(struct drm_i915_private *dev_priv)
@@ -293,11 +293,11 @@ static void snb_fbc_flip_prepare(struct drm_i915_private *dev_priv)
I915_WRITE(SNB_DPFC_CTL_SA, SNB_CPU_FENCE_ENABLE | obj->fence_reg);
}
-static void ilk_fbc_disable(struct drm_i915_private *dev_priv)
+static void ilk_fbc_deactivate(struct drm_i915_private *dev_priv)
{
u32 dpfc_ctl;
- dev_priv->fbc.enabled = false;
+ dev_priv->fbc.active = false;
/* Disable compression */
dpfc_ctl = I915_READ(ILK_DPFC_CONTROL);
@@ -305,16 +305,16 @@ static void ilk_fbc_disable(struct drm_i915_private *dev_priv)
dpfc_ctl &= ~DPFC_CTL_EN;
I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
- DRM_DEBUG_KMS("disabled FBC\n");
+ DRM_DEBUG_KMS("deactivated FBC\n");
}
}
-static bool ilk_fbc_enabled(struct drm_i915_private *dev_priv)
+static bool ilk_fbc_is_active(struct drm_i915_private *dev_priv)
{
return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
}
-static void gen7_fbc_enable(struct intel_crtc *crtc)
+static void gen7_fbc_activate(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_framebuffer *fb = crtc->base.primary->fb;
@@ -322,7 +322,7 @@ static void gen7_fbc_enable(struct intel_crtc *crtc)
u32 dpfc_ctl;
int threshold = dev_priv->fbc.threshold;
- dev_priv->fbc.enabled = true;
+ dev_priv->fbc.active = true;
dpfc_ctl = 0;
if (IS_IVYBRIDGE(dev_priv))
@@ -369,28 +369,28 @@ static void gen7_fbc_enable(struct intel_crtc *crtc)
intel_fbc_nuke(dev_priv);
- DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
+ DRM_DEBUG_KMS("activated fbc on plane %c\n", plane_name(crtc->plane));
}
/**
- * intel_fbc_enabled - Is FBC enabled?
+ * intel_fbc_is_active - Is FBC active?
* @dev_priv: i915 device instance
*
* This function is used to verify the current state of FBC.
* FIXME: This should be tracked in the plane config eventually
* instead of queried at runtime for most callers.
*/
-bool intel_fbc_enabled(struct drm_i915_private *dev_priv)
+bool intel_fbc_is_active(struct drm_i915_private *dev_priv)
{
- return dev_priv->fbc.enabled;
+ return dev_priv->fbc.active;
}
-static void intel_fbc_enable(const struct drm_framebuffer *fb)
+static void intel_fbc_activate(const struct drm_framebuffer *fb)
{
struct drm_i915_private *dev_priv = fb->dev->dev_private;
struct intel_crtc *crtc = dev_priv->fbc.crtc;
- dev_priv->fbc.enable_fbc(crtc);
+ dev_priv->fbc.activate(crtc);
dev_priv->fbc.fb_id = fb->base.id;
dev_priv->fbc.y = crtc->base.y;
@@ -410,7 +410,7 @@ static void intel_fbc_work_fn(struct work_struct *__work)
* the prior work.
*/
if (crtc_fb == work->fb)
- intel_fbc_enable(work->fb);
+ intel_fbc_activate(work->fb);
dev_priv->fbc.fbc_work = NULL;
}
@@ -426,7 +426,7 @@ static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv)
if (dev_priv->fbc.fbc_work == NULL)
return;
- DRM_DEBUG_KMS("cancelling pending FBC enable\n");
+ DRM_DEBUG_KMS("cancelling pending FBC activation\n");
/* Synchronisation is provided by struct_mutex and checking of
* dev_priv->fbc.fbc_work, so we can perform the cancellation
@@ -444,7 +444,7 @@ static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv)
dev_priv->fbc.fbc_work = NULL;
}
-static void intel_fbc_schedule_enable(struct intel_crtc *crtc)
+static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
{
struct intel_fbc_work *work;
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
@@ -457,7 +457,7 @@ static void intel_fbc_schedule_enable(struct intel_crtc *crtc)
work = kzalloc(sizeof(*work), GFP_KERNEL);
if (work == NULL) {
DRM_ERROR("Failed to allocate FBC work structure\n");
- intel_fbc_enable(crtc->base.primary->fb);
+ intel_fbc_activate(crtc->base.primary->fb);
return;
}
@@ -488,8 +488,8 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
intel_fbc_cancel_work(dev_priv);
- if (dev_priv->fbc.enabled)
- dev_priv->fbc.disable_fbc(dev_priv);
+ if (dev_priv->fbc.active)
+ dev_priv->fbc.deactivate(dev_priv);
}
static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
@@ -951,10 +951,10 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
if (dev_priv->fbc.crtc == crtc &&
dev_priv->fbc.fb_id == fb->base.id &&
dev_priv->fbc.y == crtc->base.y &&
- dev_priv->fbc.enabled)
+ dev_priv->fbc.active)
return;
- if (intel_fbc_enabled(dev_priv)) {
+ if (intel_fbc_is_active(dev_priv)) {
/* We update FBC along two paths, after changing fb/crtc
* configuration (modeswitching) and after page-flipping
* finishes. For the latter, we know that not only did
@@ -982,13 +982,13 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
__intel_fbc_disable(dev_priv);
}
- intel_fbc_schedule_enable(crtc);
+ intel_fbc_schedule_activation(crtc);
dev_priv->fbc.no_fbc_reason = "FBC enabled (not necessarily active)\n";
return;
out_disable:
/* Multiple disables should be harmless */
- if (intel_fbc_enabled(dev_priv)) {
+ if (intel_fbc_is_active(dev_priv)) {
DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
__intel_fbc_disable(dev_priv);
}
@@ -1027,7 +1027,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
mutex_lock(&dev_priv->fbc.lock);
- if (dev_priv->fbc.enabled || dev_priv->fbc.fbc_work)
+ if (dev_priv->fbc.active || dev_priv->fbc.fbc_work)
fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
else
fbc_bits = dev_priv->fbc.possible_framebuffer_bits;
@@ -1048,7 +1048,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
if (origin == ORIGIN_GTT)
return;
- if (origin == ORIGIN_FLIP && dev_priv->fbc.enabled)
+ if (origin == ORIGIN_FLIP && dev_priv->fbc.active)
return;
mutex_lock(&dev_priv->fbc.lock);
@@ -1059,7 +1059,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
if (origin == ORIGIN_FLIP) {
__intel_fbc_update(dev_priv->fbc.crtc);
} else {
- if (dev_priv->fbc.enabled)
+ if (dev_priv->fbc.active)
intel_fbc_nuke(dev_priv);
else
__intel_fbc_update(dev_priv->fbc.crtc);
@@ -1079,7 +1079,7 @@ void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
mutex_lock(&dev_priv->fbc.lock);
- if (dev_priv->fbc.enabled) {
+ if (dev_priv->fbc.active) {
fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
if (fbc_bits & frontbuffer_bits)
dev_priv->fbc.flip_prepare(dev_priv);
@@ -1105,7 +1105,7 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
mutex_init(&dev_priv->fbc.lock);
if (!HAS_FBC(dev_priv)) {
- dev_priv->fbc.enabled = false;
+ dev_priv->fbc.active = false;
dev_priv->fbc.no_fbc_reason = "unsupported by this chipset";
return;
}
@@ -1119,32 +1119,32 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
}
if (INTEL_INFO(dev_priv)->gen >= 7) {
- dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
- dev_priv->fbc.enable_fbc = gen7_fbc_enable;
- dev_priv->fbc.disable_fbc = ilk_fbc_disable;
+ dev_priv->fbc.is_active = ilk_fbc_is_active;
+ dev_priv->fbc.activate = gen7_fbc_activate;
+ dev_priv->fbc.deactivate = ilk_fbc_deactivate;
dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
} else if (INTEL_INFO(dev_priv)->gen >= 5) {
- dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
- dev_priv->fbc.enable_fbc = ilk_fbc_enable;
- dev_priv->fbc.disable_fbc = ilk_fbc_disable;
+ dev_priv->fbc.is_active = ilk_fbc_is_active;
+ dev_priv->fbc.activate = ilk_fbc_activate;
+ dev_priv->fbc.deactivate = ilk_fbc_deactivate;
if (INTEL_INFO(dev_priv)->gen == 5)
dev_priv->fbc.flip_prepare = ilk_fbc_flip_prepare;
else
dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
} else if (IS_GM45(dev_priv)) {
- dev_priv->fbc.fbc_enabled = g4x_fbc_enabled;
- dev_priv->fbc.enable_fbc = g4x_fbc_enable;
- dev_priv->fbc.disable_fbc = g4x_fbc_disable;
+ dev_priv->fbc.is_active = g4x_fbc_is_active;
+ dev_priv->fbc.activate = g4x_fbc_activate;
+ dev_priv->fbc.deactivate = g4x_fbc_deactivate;
dev_priv->fbc.flip_prepare = g4x_fbc_flip_prepare;
} else {
- dev_priv->fbc.fbc_enabled = i8xx_fbc_enabled;
- dev_priv->fbc.enable_fbc = i8xx_fbc_enable;
- dev_priv->fbc.disable_fbc = i8xx_fbc_disable;
+ dev_priv->fbc.is_active = i8xx_fbc_is_active;
+ dev_priv->fbc.activate = i8xx_fbc_activate;
+ dev_priv->fbc.deactivate = i8xx_fbc_deactivate;
dev_priv->fbc.flip_prepare = i8xx_fbc_flip_prepare;
/* This value was pulled out of someone's hat */
I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
}
- dev_priv->fbc.enabled = dev_priv->fbc.fbc_enabled(dev_priv);
+ dev_priv->fbc.active = dev_priv->fbc.is_active(dev_priv);
}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index df22b9c..c5dec04 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2442,7 +2442,7 @@ static void ilk_wm_merge(struct drm_device *dev,
* enabled sometime later.
*/
if (IS_GEN5(dev) && !merged->fbc_wm_enabled &&
- intel_fbc_enabled(dev_priv)) {
+ intel_fbc_is_active(dev_priv)) {
for (level = 2; level <= max_level; level++) {
struct intel_wm_level *wm = &merged->wm[level];
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 11/18] drm/i915: refactor FBC deactivation at init
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (9 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-21 12:59 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 12/18] drm/i915: introduce intel_fbc_{enable, disable} Paulo Zanoni
` (7 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
Make sure we deactivate FBC at intel_fbc_init(), so we can remove the
call from intel_display.c.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 3 ---
drivers/gpu/drm/i915/intel_fbc.c | 5 +++--
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fcaf865..7acdc77 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14839,9 +14839,6 @@ void intel_modeset_init(struct drm_device *dev)
i915_disable_vga(dev);
intel_setup_outputs(dev);
- /* Just in case the BIOS is doing something questionable. */
- intel_fbc_disable(dev_priv);
-
drm_modeset_lock_all(dev);
intel_modeset_setup_hw_state(dev);
drm_modeset_unlock_all(dev);
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 29becf7..15f74e2 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -1103,9 +1103,9 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
enum pipe pipe;
mutex_init(&dev_priv->fbc.lock);
+ dev_priv->fbc.active = false;
if (!HAS_FBC(dev_priv)) {
- dev_priv->fbc.active = false;
dev_priv->fbc.no_fbc_reason = "unsupported by this chipset";
return;
}
@@ -1146,5 +1146,6 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
}
- dev_priv->fbc.active = dev_priv->fbc.is_active(dev_priv);
+ if (dev_priv->fbc.is_active(dev_priv))
+ dev_priv->fbc.deactivate(dev_priv);
}
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 12/18] drm/i915: introduce intel_fbc_{enable, disable}
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (10 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 11/18] drm/i915: refactor FBC deactivation at init Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-20 15:55 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 13/18] drm/i915: remove too-frequent FBC debug message Paulo Zanoni
` (6 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
These are the functions that lock/unlock FBC to/from a CRTC without
changing the hardware state. The goal is to run once per modeset. For
now the functions don't really do much, but we'll still move more
stuff there, such as the stolen memory allocations.
With this, activate/deactivate will just start/stop FBC without
changing its associated pipe. This is the same naming scheme we use in
other features, such as PSR.
This will also help in case we decide to move FBC to pipe_config or
something else later.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 14 ++-
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_fbc.c | 202 ++++++++++++++++++++++++-----------
4 files changed, 158 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9c9035a..8755808 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -915,6 +915,7 @@ struct i915_fbc {
bool false_color;
+ bool enabled;
bool active;
struct intel_fbc_work {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7acdc77..cb008d1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4814,7 +4814,7 @@ static void intel_pre_plane_update(struct intel_crtc *crtc)
intel_crtc_wait_for_pending_flips(&crtc->base);
if (atomic->disable_fbc)
- intel_fbc_disable_crtc(crtc);
+ intel_fbc_deactivate(crtc);
if (crtc->atomic.disable_ips)
hsw_disable_ips(crtc);
@@ -4915,6 +4915,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
if (HAS_PCH_CPT(dev))
cpt_verify_modeset(dev, intel_crtc->pipe);
+
+ intel_fbc_enable(intel_crtc);
}
/* IPS only exists on ULT machines and is tied to pipe A. */
@@ -5017,6 +5019,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_wait_for_vblank(dev, hsw_workaround_pipe);
intel_wait_for_vblank(dev, hsw_workaround_pipe);
}
+
+ intel_fbc_enable(intel_crtc);
}
static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
@@ -5083,6 +5087,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
ironlake_fdi_pll_disable(intel_crtc);
}
+
+ intel_fbc_disable_crtc(intel_crtc);
}
static void haswell_crtc_disable(struct drm_crtc *crtc)
@@ -5129,6 +5135,8 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->post_disable)
encoder->post_disable(encoder);
+
+ intel_fbc_disable_crtc(intel_crtc);
}
static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -6157,6 +6165,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
+
+ intel_fbc_enable(intel_crtc);
}
static void i9xx_pfit_disable(struct intel_crtc *crtc)
@@ -6219,6 +6229,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
if (!IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+
+ intel_fbc_disable_crtc(intel_crtc);
}
static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7203087..3854288 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1278,8 +1278,10 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
/* intel_fbc.c */
bool intel_fbc_is_active(struct drm_i915_private *dev_priv);
+void intel_fbc_deactivate(struct intel_crtc *crtc);
void intel_fbc_update(struct intel_crtc *crtc);
void intel_fbc_init(struct drm_i915_private *dev_priv);
+void intel_fbc_enable(struct intel_crtc *crtc);
void intel_fbc_disable(struct drm_i915_private *dev_priv);
void intel_fbc_disable_crtc(struct intel_crtc *crtc);
void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 15f74e2..502ab0b 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -452,7 +452,6 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
intel_fbc_cancel_work(dev_priv);
- dev_priv->fbc.crtc = crtc;
work = kzalloc(sizeof(*work), GFP_KERNEL);
if (work == NULL) {
@@ -482,7 +481,7 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
schedule_delayed_work(&work->work, msecs_to_jiffies(50));
}
-static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
+static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv)
{
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
@@ -492,35 +491,13 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
dev_priv->fbc.deactivate(dev_priv);
}
-static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
-{
- intel_fbc_deactivate(dev_priv);
- dev_priv->fbc.crtc = NULL;
-}
-
-/**
- * intel_fbc_disable - disable FBC
- * @dev_priv: i915 device instance
- *
- * This function disables FBC.
- */
-void intel_fbc_disable(struct drm_i915_private *dev_priv)
-{
- if (!fbc_supported(dev_priv))
- return;
-
- mutex_lock(&dev_priv->fbc.lock);
- __intel_fbc_disable(dev_priv);
- mutex_unlock(&dev_priv->fbc.lock);
-}
-
/*
- * intel_fbc_disable_crtc - disable FBC if it's associated with crtc
+ * intel_fbc_deactivate - deactivate FBC if it's associated with crtc
* @crtc: the CRTC
*
- * This function disables FBC if it's associated with the provided CRTC.
+ * This function deactivates FBC if it's associated with the provided CRTC.
*/
-void intel_fbc_disable_crtc(struct intel_crtc *crtc)
+void intel_fbc_deactivate(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
@@ -529,7 +506,7 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc)
mutex_lock(&dev_priv->fbc.lock);
if (dev_priv->fbc.crtc == crtc)
- __intel_fbc_disable(dev_priv);
+ __intel_fbc_deactivate(dev_priv);
mutex_unlock(&dev_priv->fbc.lock);
}
@@ -543,15 +520,18 @@ static void set_no_fbc_reason(struct drm_i915_private *dev_priv,
DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
}
-static bool crtc_is_valid(struct intel_crtc *crtc)
+static bool crtc_can_fbc(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
- enum pipe pipe = crtc->pipe;
- if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) &&
- pipe != PIPE_A)
- return false;
+ if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)
+ return crtc->pipe == PIPE_A;
+ else
+ return true;
+}
+static bool crtc_is_valid(struct intel_crtc *crtc)
+{
return intel_crtc_active(&crtc->base) &&
to_intel_plane_state(crtc->base.primary->state)->visible &&
crtc->base.primary->fb != NULL;
@@ -838,11 +818,11 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
}
/**
- * __intel_fbc_update - enable/disable FBC as needed, unlocked
+ * __intel_fbc_update - activate/deactivate FBC as needed, unlocked
* @crtc: the CRTC that triggered the update
*
- * This function completely reevaluates the status of FBC, then enables,
- * disables or maintains it on the same state.
+ * This function completely reevaluates the status of FBC, then activates,
+ * deactivates or maintains it on the same state.
*/
static void __intel_fbc_update(struct intel_crtc *crtc)
{
@@ -858,22 +838,9 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
goto out_disable;
}
- if (dev_priv->fbc.crtc != NULL && dev_priv->fbc.crtc != crtc)
+ if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc)
return;
- if (intel_vgpu_active(dev_priv->dev))
- i915.enable_fbc = 0;
-
- if (i915.enable_fbc < 0) {
- set_no_fbc_reason(dev_priv, "disabled per chip default");
- goto out_disable;
- }
-
- if (!i915.enable_fbc) {
- set_no_fbc_reason(dev_priv, "disabled per module param");
- goto out_disable;
- }
-
if (!crtc_is_valid(crtc)) {
set_no_fbc_reason(dev_priv, "no output");
goto out_disable;
@@ -978,8 +945,8 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
* disabling paths we do need to wait for a vblank at
* some point. And we wait before enabling FBC anyway.
*/
- DRM_DEBUG_KMS("disabling active FBC for update\n");
- __intel_fbc_disable(dev_priv);
+ DRM_DEBUG_KMS("deactivating FBC for update\n");
+ __intel_fbc_deactivate(dev_priv);
}
intel_fbc_schedule_activation(crtc);
@@ -989,17 +956,17 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
out_disable:
/* Multiple disables should be harmless */
if (intel_fbc_is_active(dev_priv)) {
- DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
- __intel_fbc_disable(dev_priv);
+ DRM_DEBUG_KMS("unsupported config, deactivating FBC\n");
+ __intel_fbc_deactivate(dev_priv);
}
__intel_fbc_cleanup_cfb(dev_priv);
}
/*
- * intel_fbc_update - enable/disable FBC as needed
+ * intel_fbc_update - activate/deactivate FBC as needed
* @crtc: the CRTC that triggered the update
*
- * This function reevaluates the overall state and enables or disables FBC.
+ * This function reevaluates the overall state and activates or deactivates FBC.
*/
void intel_fbc_update(struct intel_crtc *crtc)
{
@@ -1027,7 +994,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
mutex_lock(&dev_priv->fbc.lock);
- if (dev_priv->fbc.active || dev_priv->fbc.fbc_work)
+ if (dev_priv->fbc.enabled)
fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
else
fbc_bits = dev_priv->fbc.possible_framebuffer_bits;
@@ -1035,7 +1002,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits);
if (dev_priv->fbc.busy_bits)
- intel_fbc_deactivate(dev_priv);
+ __intel_fbc_deactivate(dev_priv);
mutex_unlock(&dev_priv->fbc.lock);
}
@@ -1055,7 +1022,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
- if (!dev_priv->fbc.busy_bits && dev_priv->fbc.crtc) {
+ if (!dev_priv->fbc.busy_bits && dev_priv->fbc.enabled) {
if (origin == ORIGIN_FLIP) {
__intel_fbc_update(dev_priv->fbc.crtc);
} else {
@@ -1086,9 +1053,123 @@ void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
} else if (dev_priv->fbc.fbc_work) {
fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
if (fbc_bits & frontbuffer_bits)
- intel_fbc_deactivate(dev_priv);
+ __intel_fbc_deactivate(dev_priv);
+ }
+
+ mutex_unlock(&dev_priv->fbc.lock);
+}
+
+/**
+ * intel_fbc_enable: tries to enable FBC on the CRTC
+ * @crtc: the CRTC
+ *
+ * This function checks if it's possible to enable FBC on the following CRTC,
+ * then enables it. Notice that it doesn't activate FBC.
+ */
+void intel_fbc_enable(struct intel_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+ if (!fbc_supported(dev_priv))
+ return;
+
+ mutex_lock(&dev_priv->fbc.lock);
+
+ if (dev_priv->fbc.enabled) {
+ WARN_ON(dev_priv->fbc.crtc == crtc);
+ goto out;
+ }
+
+ WARN_ON(dev_priv->fbc.active);
+ WARN_ON(dev_priv->fbc.crtc != NULL);
+
+ if (intel_vgpu_active(dev_priv->dev)) {
+ set_no_fbc_reason(dev_priv, "VGPU is active");
+ goto out;
+ }
+
+ if (i915.enable_fbc < 0) {
+ set_no_fbc_reason(dev_priv, "disabled per chip default");
+ goto out;
+ }
+
+ if (!i915.enable_fbc) {
+ set_no_fbc_reason(dev_priv, "disabled per module param");
+ goto out;
+ }
+
+ if (!crtc_can_fbc(crtc)) {
+ set_no_fbc_reason(dev_priv, "no enabled pipes can have FBC");
+ goto out;
}
+ DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+ dev_priv->fbc.no_fbc_reason = "FBC enabled but not active yet\n";
+
+ dev_priv->fbc.enabled = true;
+ dev_priv->fbc.crtc = crtc;
+out:
+ mutex_unlock(&dev_priv->fbc.lock);
+}
+
+/**
+ * __intel_fbc_disable - disable FBC
+ * @dev_priv: i915 device instance
+ *
+ * This is the low level function that actually disables FBC. Callers should
+ * grab the FBC lock.
+ */
+static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
+{
+ struct intel_crtc *crtc = dev_priv->fbc.crtc;
+
+ WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
+ WARN_ON(!dev_priv->fbc.enabled);
+ WARN_ON(dev_priv->fbc.active);
+ assert_pipe_disabled(dev_priv, crtc->pipe);
+
+ DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+
+ dev_priv->fbc.enabled = false;
+ dev_priv->fbc.crtc = NULL;
+}
+
+/**
+ * intel_fbc_disable_crtc - disable FBC if it's associated with crtc
+ * @crtc: the CRTC
+ *
+ * This function disables FBC if it's associated with the provided CRTC.
+ */
+void intel_fbc_disable_crtc(struct intel_crtc *crtc)
+{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+ if (!fbc_supported(dev_priv))
+ return;
+
+ mutex_lock(&dev_priv->fbc.lock);
+ if (dev_priv->fbc.crtc == crtc) {
+ WARN_ON(!dev_priv->fbc.enabled);
+ WARN_ON(dev_priv->fbc.active);
+ __intel_fbc_disable(dev_priv);
+ }
+ mutex_unlock(&dev_priv->fbc.lock);
+}
+
+/**
+ * intel_fbc_disable - globally disable FBC
+ * @dev_priv: i915 device instance
+ *
+ * This function disables FBC regardless of which CRTC is associated with it.
+ */
+void intel_fbc_disable(struct drm_i915_private *dev_priv)
+{
+ if (!fbc_supported(dev_priv))
+ return;
+
+ mutex_lock(&dev_priv->fbc.lock);
+ if (dev_priv->fbc.enabled)
+ __intel_fbc_disable(dev_priv);
mutex_unlock(&dev_priv->fbc.lock);
}
@@ -1103,6 +1184,7 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
enum pipe pipe;
mutex_init(&dev_priv->fbc.lock);
+ dev_priv->fbc.enabled = false;
dev_priv->fbc.active = false;
if (!HAS_FBC(dev_priv)) {
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 13/18] drm/i915: remove too-frequent FBC debug message
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (11 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 12/18] drm/i915: introduce intel_fbc_{enable, disable} Paulo Zanoni
@ 2015-10-20 13:49 ` Paulo Zanoni
2015-10-21 13:01 ` Chris Wilson
2015-10-20 13:50 ` [PATCH 14/18] drm/i915: fix the CFB size check Paulo Zanoni
` (5 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:49 UTC (permalink / raw)
To: intel-gfx
If we run igt/kms_frontbuffer_tracking, this message will appear
thousands of times, eating a significant part of our dmesg buffer.
It's part of the expected FBC behavior, so let's just silence it.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 502ab0b..5dab0e0 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -426,8 +426,6 @@ static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv)
if (dev_priv->fbc.fbc_work == NULL)
return;
- DRM_DEBUG_KMS("cancelling pending FBC activation\n");
-
/* Synchronisation is provided by struct_mutex and checking of
* dev_priv->fbc.fbc_work, so we can perform the cancellation
* entirely asynchronously.
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 14/18] drm/i915: fix the CFB size check
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (12 preceding siblings ...)
2015-10-20 13:49 ` [PATCH 13/18] drm/i915: remove too-frequent FBC debug message Paulo Zanoni
@ 2015-10-20 13:50 ` Paulo Zanoni
2015-10-20 13:50 ` [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable Paulo Zanoni
` (4 subsequent siblings)
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:50 UTC (permalink / raw)
To: intel-gfx
In function find_compression_threshold() we try to over-allocate CFB
space in order to reudce reallocations and fragmentation, and we're
not considering that at the CFB size check. Consider it.
There is also a longer-term plan to kill
dev_priv->fbc.uncompressed_size, but this will come later.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 5dab0e0..bf855b2 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -733,7 +733,8 @@ static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
size = intel_fbc_calculate_cfb_size(crtc);
cpp = drm_format_plane_cpp(fb->pixel_format, 0);
- if (size <= dev_priv->fbc.uncompressed_size)
+ if (dev_priv->fbc.compressed_fb.allocated &&
+ size <= dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold)
return 0;
/* Release any current block */
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (13 preceding siblings ...)
2015-10-20 13:50 ` [PATCH 14/18] drm/i915: fix the CFB size check Paulo Zanoni
@ 2015-10-20 13:50 ` Paulo Zanoni
2015-10-21 7:11 ` Daniel Vetter
2015-10-20 13:50 ` [PATCH 16/18] drm/i915: move adjusted_mode checks from fbc_update to fbc_enable Paulo Zanoni
` (3 subsequent siblings)
18 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:50 UTC (permalink / raw)
To: intel-gfx
One of the problems with the current code is that it frees the CFB and
releases its drm_mm node as soon as we flip FBC's enable bit. This is
bad because after we disbale FBC the hardware may still use the CFB
for the rest of the frame, so in theory we should only release the
drm_mm node one frame after we disable FBC. Otherwise, a stolen memory
allocation done right after an FBC disable may result in either
corrupted memory for the new owner of that memory region or corrupted
screen/underruns in case the new owner changes it while the hardware
is still reading it. This case is not exactly easy to reproduce since
we currently don't do a lot of stolen memory allocations, but I see
patches on the mailing list trying to expose stolen memory to user
space, so races will be possible.
I thought about three different approaches to solve this, and they all
have downsides.
The first approach would be to simply use multiple drm_mm nodes and
freeing the unused ones only after a frame has passed. The problem
with this approach is that since stolen memory is rather small,
there's a risk we just won't be able to allocate a new CFB from stolen
if the previous one was not freed yet. This could happen in case we
quickly disable FBC from pipe A and decide to enable it on pipe B, or
just if we change pipe A's fb stride while FBC is enabled.
The second approach would be similar to the first one, but maintaining
a single drm_mm node and keeping track of when it can be reused. This
would remove the disadvantage of not having enough space for two
nodes, but would create the new problem where we may not be able to
enable FBC at the point intel_fbc_update() is called, so we would have
to add more code to retry updating FBC after the time has passed. And
that can quickly get too complex since we can get invalidate, flush,
flip_prepare, disable and other calls in the middle of the wait.
Both solutions above - and also the current code - have the problem
that we unnecessarily free+realloc FBC during invalidate+flush
operations even if the CFB size doesn't change.
The third option would be to move the allocation/deallocation to
enable/disable. This makes sure that the pipe is always disabled when
we allocate/deallocate the CFB, so there's no risk that the FBC
hardware may read or write to the memory right after it is freed from
drm_mm. The downside is that it is possible for user space to change
the buffer stride without triggering a disable/enable - only
deactivate/activate -, so we'll have to handle this case somehow, even
though it is uncommon - see igt's kms_frontbuffer_tracking test,
fbc-stridechange subtest. It could be possible to implement a way to
free+alloc the CFB during said stride change, but it would involve a
lot of book-keeping - exactly as mentioned above - just for a rare
case, so for now I'll keep it simple and just deactivate FBC. Besides,
we may not even need to disable FBC since we do CFB over-allocation.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 132 ++++++++++++++++++++-------------------
1 file changed, 68 insertions(+), 64 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index bf855b2..48d8cfc 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -59,6 +59,45 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)
return crtc->base.y - crtc->adjusted_y;
}
+/*
+ * 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(struct intel_crtc *crtc,
+ int *width, int *height)
+{
+ struct intel_plane_state *plane_state =
+ to_intel_plane_state(crtc->base.primary->state);
+ int w, h;
+
+ if (intel_rotation_90_or_270(plane_state->base.rotation)) {
+ w = drm_rect_height(&plane_state->src) >> 16;
+ h = drm_rect_width(&plane_state->src) >> 16;
+ } else {
+ w = drm_rect_width(&plane_state->src) >> 16;
+ h = drm_rect_height(&plane_state->src) >> 16;
+ }
+
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+}
+
+static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc,
+ struct drm_framebuffer *fb)
+{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ int lines;
+
+ intel_fbc_get_plane_source_size(crtc, NULL, &lines);
+ if (INTEL_INFO(dev_priv)->gen >= 7)
+ lines = min(lines, 2048);
+
+ return lines * fb->pitches[0];
+}
+
static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
{
u32 fbc_ctl;
@@ -604,11 +643,17 @@ again:
}
}
-static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, int size,
- int fb_cpp)
+static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_framebuffer *fb = crtc->base.primary->state->fb;
struct drm_mm_node *uninitialized_var(compressed_llb);
- int ret;
+ int size, fb_cpp, ret;
+
+ WARN_ON(dev_priv->fbc.compressed_fb.allocated);
+
+ size = intel_fbc_calculate_cfb_size(crtc, fb);
+ fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0);
ret = find_compression_threshold(dev_priv, &dev_priv->fbc.compressed_fb,
size, fb_cpp);
@@ -685,64 +730,6 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
mutex_unlock(&dev_priv->fbc.lock);
}
-/*
- * 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(struct intel_crtc *crtc,
- int *width, int *height)
-{
- struct intel_plane_state *plane_state =
- to_intel_plane_state(crtc->base.primary->state);
- int w, h;
-
- if (intel_rotation_90_or_270(plane_state->base.rotation)) {
- w = drm_rect_height(&plane_state->src) >> 16;
- h = drm_rect_width(&plane_state->src) >> 16;
- } else {
- w = drm_rect_width(&plane_state->src) >> 16;
- h = drm_rect_height(&plane_state->src) >> 16;
- }
-
- if (width)
- *width = w;
- if (height)
- *height = h;
-}
-
-static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
- struct drm_framebuffer *fb = crtc->base.primary->fb;
- int lines;
-
- intel_fbc_get_plane_source_size(crtc, NULL, &lines);
- if (INTEL_INFO(dev_priv)->gen >= 7)
- lines = min(lines, 2048);
-
- return lines * fb->pitches[0];
-}
-
-static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
- struct drm_framebuffer *fb = crtc->base.primary->fb;
- int size, cpp;
-
- size = intel_fbc_calculate_cfb_size(crtc);
- cpp = drm_format_plane_cpp(fb->pixel_format, 0);
-
- if (dev_priv->fbc.compressed_fb.allocated &&
- size <= dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold)
- return 0;
-
- /* Release any current block */
- __intel_fbc_cleanup_cfb(dev_priv);
-
- return intel_fbc_alloc_cfb(dev_priv, size, cpp);
-}
-
static bool stride_is_valid(struct drm_i915_private *dev_priv,
unsigned int stride)
{
@@ -904,8 +891,19 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
goto out_disable;
}
- if (intel_fbc_setup_cfb(crtc)) {
- set_no_fbc_reason(dev_priv, "not enough stolen memory");
+ /* 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
+ * if this happens, but if we exceed the current CFB size we'll have to
+ * disable FBC. Notice that it would be possible to disable FBC, wait
+ * 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 case we expect to be uncommon, so we
+ * just don't have this code for now. */
+ if (intel_fbc_calculate_cfb_size(crtc, fb) >
+ dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) {
+ set_no_fbc_reason(dev_priv, "CFB requirements changed");
goto out_disable;
}
@@ -958,7 +956,6 @@ out_disable:
DRM_DEBUG_KMS("unsupported config, deactivating FBC\n");
__intel_fbc_deactivate(dev_priv);
}
- __intel_fbc_cleanup_cfb(dev_priv);
}
/*
@@ -1102,6 +1099,11 @@ void intel_fbc_enable(struct intel_crtc *crtc)
goto out;
}
+ if (intel_fbc_alloc_cfb(crtc)) {
+ set_no_fbc_reason(dev_priv, "not enough stolen memory");
+ goto out;
+ }
+
DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
dev_priv->fbc.no_fbc_reason = "FBC enabled but not active yet\n";
@@ -1129,6 +1131,8 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
+ __intel_fbc_cleanup_cfb(dev_priv);
+
dev_priv->fbc.enabled = false;
dev_priv->fbc.crtc = NULL;
}
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 16/18] drm/i915: move adjusted_mode checks from fbc_update to fbc_enable
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (14 preceding siblings ...)
2015-10-20 13:50 ` [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable Paulo Zanoni
@ 2015-10-20 13:50 ` Paulo Zanoni
2015-10-20 13:50 ` [PATCH 17/18] drm/i915: move clock frequency " Paulo Zanoni
` (2 subsequent siblings)
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:50 UTC (permalink / raw)
To: intel-gfx
These things can't change without a full modeset.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 48d8cfc..af22bc8 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -815,7 +815,6 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct drm_framebuffer *fb;
struct drm_i915_gem_object *obj;
- const struct drm_display_mode *adjusted_mode;
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
@@ -834,13 +833,6 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
fb = crtc->base.primary->fb;
obj = intel_fb_obj(fb);
- adjusted_mode = &crtc->config->base.adjusted_mode;
-
- if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
- (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
- set_no_fbc_reason(dev_priv, "incompatible mode");
- goto out_disable;
- }
if (!intel_fbc_hw_tracking_covers_screen(crtc)) {
set_no_fbc_reason(dev_priv, "mode too large for compression");
@@ -1065,6 +1057,8 @@ void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
void intel_fbc_enable(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ const struct drm_display_mode *adjusted_mode =
+ &crtc->config->base.adjusted_mode;
if (!fbc_supported(dev_priv))
return;
@@ -1099,6 +1093,12 @@ void intel_fbc_enable(struct intel_crtc *crtc)
goto out;
}
+ if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
+ (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
+ set_no_fbc_reason(dev_priv, "incompatible mode");
+ goto out;
+ }
+
if (intel_fbc_alloc_cfb(crtc)) {
set_no_fbc_reason(dev_priv, "not enough stolen memory");
goto out;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 17/18] drm/i915: move clock frequency checks from fbc_update to fbc_enable
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (15 preceding siblings ...)
2015-10-20 13:50 ` [PATCH 16/18] drm/i915: move adjusted_mode checks from fbc_update to fbc_enable Paulo Zanoni
@ 2015-10-20 13:50 ` Paulo Zanoni
2015-10-20 13:50 ` [PATCH 18/18] drm/i915: check for FBC planes in the same place as the pipes Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC Paulo Zanoni
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:50 UTC (permalink / raw)
To: intel-gfx
These also can't change without a full modeset.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index af22bc8..7f54b6f 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -875,14 +875,6 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
goto out_disable;
}
- /* WaFbcExceedCdClockThreshold:hsw,bdw */
- if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
- ilk_pipe_pixel_rate(crtc->config) >=
- dev_priv->cdclk_freq * 95 / 100) {
- set_no_fbc_reason(dev_priv, "pixel rate is too big");
- goto out_disable;
- }
-
/* 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
@@ -1099,6 +1091,14 @@ void intel_fbc_enable(struct intel_crtc *crtc)
goto out;
}
+ /* WaFbcExceedCdClockThreshold:hsw,bdw */
+ if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
+ ilk_pipe_pixel_rate(crtc->config) >=
+ dev_priv->cdclk_freq * 95 / 100) {
+ set_no_fbc_reason(dev_priv, "pixel rate is too big");
+ goto out;
+ }
+
if (intel_fbc_alloc_cfb(crtc)) {
set_no_fbc_reason(dev_priv, "not enough stolen memory");
goto out;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 18/18] drm/i915: check for FBC planes in the same place as the pipes
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (16 preceding siblings ...)
2015-10-20 13:50 ` [PATCH 17/18] drm/i915: move clock frequency " Paulo Zanoni
@ 2015-10-20 13:50 ` Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC Paulo Zanoni
18 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 13:50 UTC (permalink / raw)
To: intel-gfx
This moves the pre-gen4 check from update() to enable(). The HAS_DDI
in the original code is not needed since only gen 2/3 have the plane
swapping code.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
drivers/gpu/drm/i915/intel_fbc.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 7f54b6f..47862c5 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -563,6 +563,8 @@ static bool crtc_can_fbc(struct intel_crtc *crtc)
if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)
return crtc->pipe == PIPE_A;
+ else if (INTEL_INFO(dev_priv)->gen < 4)
+ return crtc->plane == PLANE_A;
else
return true;
}
@@ -839,12 +841,6 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
goto out_disable;
}
- if ((INTEL_INFO(dev_priv)->gen < 4 || HAS_DDI(dev_priv)) &&
- crtc->plane != PLANE_A) {
- set_no_fbc_reason(dev_priv, "FBC unsupported on plane");
- goto out_disable;
- }
-
/* The use of a CPU fence is mandatory in order to detect writes
* by the CPU to the scanout and trigger updates to the FBC.
*/
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-20 13:49 ` [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code Paulo Zanoni
@ 2015-10-20 15:52 ` Chris Wilson
2015-10-21 17:16 ` Zanoni, Paulo R
2015-10-22 7:52 ` Maarten Lankhorst
1 sibling, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2015-10-20 15:52 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:50AM -0200, Paulo Zanoni wrote:
> We're going to kill intel_fbc_find_crtc(), that's why a big part of
> the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
> 1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index b9cfd16..1162787 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct drm_i915_private *dev_priv,
> DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> }
>
> +static bool crtc_is_valid(struct intel_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> + enum pipe pipe = crtc->pipe;
> +
> + if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) &&
> + pipe != PIPE_A)
Keeping
if (pipe_a_only(dev_priv) && pipe != PIPE_A)
return false;
would have been nicer.
> + return false;
> +
> + return intel_crtc_active(&crtc->base) &&
> + to_intel_plane_state(crtc->base.primary->state)->visible &&
> + crtc->base.primary->fb != NULL;
And then you can split this line up for a little more clarity. If you
are taking the time to refactor into a separate function for
readability, you may as well apply a little polish as well.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 12/18] drm/i915: introduce intel_fbc_{enable, disable}
2015-10-20 13:49 ` [PATCH 12/18] drm/i915: introduce intel_fbc_{enable, disable} Paulo Zanoni
@ 2015-10-20 15:55 ` Chris Wilson
0 siblings, 0 replies; 57+ messages in thread
From: Chris Wilson @ 2015-10-20 15:55 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:58AM -0200, Paulo Zanoni wrote:
> These are the functions that lock/unlock FBC to/from a CRTC without
> changing the hardware state. The goal is to run once per modeset. For
> now the functions don't really do much, but we'll still move more
> stuff there, such as the stolen memory allocations.
>
> With this, activate/deactivate will just start/stop FBC without
> changing its associated pipe. This is the same naming scheme we use in
> other features, such as PSR.
>
> This will also help in case we decide to move FBC to pipe_config or
> something else later.
Pop quiz: can you summarise the rules on when the functions should be
called in the modeset sequence? Are there more places where you could
assert FBC state?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush
2015-10-20 13:49 ` [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush Paulo Zanoni
@ 2015-10-20 15:59 ` Chris Wilson
2015-10-21 17:08 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2015-10-20 15:59 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:49AM -0200, Paulo Zanoni wrote:
> There's no need to stop and restart FBC: a nuke should be fine.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_fbc.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index 9477379..b9cfd16 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -1088,8 +1088,10 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
> if (origin == ORIGIN_FLIP) {
> __intel_fbc_update(dev_priv);
> } else {
> - __intel_fbc_disable(dev_priv);
> - __intel_fbc_update(dev_priv);
> + if (dev_priv->fbc.enabled)
> + intel_fbc_nuke(dev_priv);
Ok, what does nuke actually do? From the name, I would expect FBC to be
left in an unusable state.
> + else
> + __intel_fbc_update(dev_priv);
> }
> }
This becomes
if (enabled && origin != ORIGIN_FLIP)
intel_fbc_nuke();
else
__intel_fbc_update();
It seems a little odd that anything is done if disabled, so care to
elaborate that reason, and I presume there is an equally good comment
before the context that explains why FLIP is special?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work
2015-10-20 13:49 ` [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work Paulo Zanoni
@ 2015-10-20 16:03 ` Chris Wilson
2015-10-21 17:27 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2015-10-20 16:03 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:51AM -0200, Paulo Zanoni wrote:
> This thing where we need to get the crtc either from the work
> structure or the fbc structure itself is confusing and unnecessary.
> Set fbc.crtc right when scheduling the enable work so we can always
> use it.
Pardon? It was confusing to have the crtc passed along with the work
item as opposed to digging it out from an indirect link on the dev_priv.
iirc work->crtc was part of the serialisation of the work item.
What I think you meant was that you were passing around the wrong
struct, e.g.
intel_fbc_enable() just wants the crtc, in intel_fbc_flip_prepare() you
check for the work struct, and then you should just use the work struct.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
` (17 preceding siblings ...)
2015-10-20 13:50 ` [PATCH 18/18] drm/i915: check for FBC planes in the same place as the pipes Paulo Zanoni
@ 2015-10-20 21:22 ` Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 2/4] kms_frontbuffer_tracking: add flag to not assert feature status Paulo Zanoni
` (2 more replies)
18 siblings, 3 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 21:22 UTC (permalink / raw)
To: intel-gfx
This fixes the failures for cases where you use --run-subtest to run
single subtests that don't use any drawing patterns.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
tests/kms_frontbuffer_tracking.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c
index d97e148..421f949 100644
--- a/tests/kms_frontbuffer_tracking.c
+++ b/tests/kms_frontbuffer_tracking.c
@@ -1179,6 +1179,8 @@ static void init_blue_crc(enum pixel_format format)
print_crc("Blue CRC: ", &blue_crcs[format].crc);
+ unset_all_crtcs();
+
igt_remove_fb(drm.fd, &blue);
blue_crcs[format].initialized = true;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH igt 2/4] kms_frontbuffer_tracking: add flag to not assert feature status
2015-10-20 21:22 ` [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC Paulo Zanoni
@ 2015-10-20 21:22 ` Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 3/4] kms_frontbuffer_tracking: add stridechange subtest Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 4/4] kms_frontbuffer_tracking: remove opt.only_feature Paulo Zanoni
2 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 21:22 UTC (permalink / raw)
To: intel-gfx
This will be used by the stridechange subtest.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
tests/kms_frontbuffer_tracking.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c
index 421f949..2c0295c 100644
--- a/tests/kms_frontbuffer_tracking.c
+++ b/tests/kms_frontbuffer_tracking.c
@@ -1540,23 +1540,26 @@ static void do_flush(const struct test_mode *t)
}
#define DONT_ASSERT_CRC (1 << 0)
+#define DONT_ASSERT_FEATURE_STATUS (1 << 1)
-#define FBC_ASSERT_FLAGS (0xF << 1)
-#define ASSERT_FBC_ENABLED (1 << 1)
-#define ASSERT_FBC_DISABLED (1 << 2)
-#define ASSERT_LAST_ACTION_CHANGED (1 << 3)
-#define ASSERT_NO_ACTION_CHANGE (1 << 4)
+#define FBC_ASSERT_FLAGS (0xF << 2)
+#define ASSERT_FBC_ENABLED (1 << 2)
+#define ASSERT_FBC_DISABLED (1 << 3)
+#define ASSERT_LAST_ACTION_CHANGED (1 << 4)
+#define ASSERT_NO_ACTION_CHANGE (1 << 5)
-#define PSR_ASSERT_FLAGS (3 << 5)
-#define ASSERT_PSR_ENABLED (1 << 5)
-#define ASSERT_PSR_DISABLED (1 << 6)
+#define PSR_ASSERT_FLAGS (3 << 6)
+#define ASSERT_PSR_ENABLED (1 << 6)
+#define ASSERT_PSR_DISABLED (1 << 7)
static int adjust_assertion_flags(const struct test_mode *t, int flags)
{
- if (!(flags & ASSERT_FBC_DISABLED))
- flags |= ASSERT_FBC_ENABLED;
- if (!(flags & ASSERT_PSR_DISABLED))
- flags |= ASSERT_PSR_ENABLED;
+ if (!(flags & DONT_ASSERT_FEATURE_STATUS)) {
+ if (!(flags & ASSERT_FBC_DISABLED))
+ flags |= ASSERT_FBC_ENABLED;
+ if (!(flags & ASSERT_PSR_DISABLED))
+ flags |= ASSERT_PSR_ENABLED;
+ }
if ((t->feature & FEATURE_FBC) == 0)
flags &= ~FBC_ASSERT_FLAGS;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH igt 3/4] kms_frontbuffer_tracking: add stridechange subtest
2015-10-20 21:22 ` [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 2/4] kms_frontbuffer_tracking: add flag to not assert feature status Paulo Zanoni
@ 2015-10-20 21:22 ` Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 4/4] kms_frontbuffer_tracking: remove opt.only_feature Paulo Zanoni
2 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 21:22 UTC (permalink / raw)
To: intel-gfx
This is a corner case not exercised by the other subtests. The test is
expected to pass both with the current Kernel tree and with the
patches that are on the mailing list.
The patches currently on the mailing list change how the CFB is
allocated, and this subtest is designed to make sure everything still
works as expected.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
tests/kms_frontbuffer_tracking.c | 47 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c
index 2c0295c..e183a06 100644
--- a/tests/kms_frontbuffer_tracking.c
+++ b/tests/kms_frontbuffer_tracking.c
@@ -2876,6 +2876,47 @@ static void badstride_subtest(const struct test_mode *t)
igt_remove_fb(drm.fd, &wide_fb);
}
+/**
+ * stridechange - change the frontbuffer stride by doing a modeset
+ *
+ * METHOD
+ * This test sets a mode on a CRTC, then creates a buffer with a different
+ * stride - still compatible with FBC -, and sets the mode on it. The Kernel
+ * currently shortcuts the modeset path for this case, so it won't trigger
+ * calls to xx_crtc_enable or xx_crtc_disable, and that could lead to
+ * problems, so test the case.
+ *
+ * EXPECTED RESULTS
+ * With the current Kernel, FBC may or may not remain enabled on this case,
+ * but we can still check the CRC values.
+ *
+ * FAILURES
+ * A bad Kernel may just not resize the CFB while keeping FBC enabled, and
+ * this can lead to underruns or stolen memory corruption. Underruns usually
+ * lead to CRC check errors, and stolen memory corruption can't be easily
+ * checked currently. A bad Kernel may also just throw some WARNs on dmesg.
+ */
+static void stridechange_subtest(const struct test_mode *t)
+{
+ struct igt_fb new_fb;
+ struct modeset_params *params = pick_params(t);
+
+ prepare_subtest(t, NULL);
+
+ create_fb(t->format, params->fb.fb->width + 512, params->fb.fb->height,
+ LOCAL_I915_FORMAT_MOD_X_TILED, t->plane, &new_fb);
+ fill_fb(&new_fb, COLOR_PRIM_BG);
+
+ params->fb.fb = &new_fb;
+ set_mode_for_params(params);
+
+ /* We can't assert that FBC will be enabled since there may not be
+ * enough space for the CFB, but we can check the CRC. */
+ do_assertions(DONT_ASSERT_FEATURE_STATUS);
+
+ igt_remove_fb(drm.fd, &new_fb);
+}
+
static int opt_handler(int option, int option_index, void *data)
{
switch (option) {
@@ -3276,10 +3317,14 @@ int main(int argc, char *argv[])
igt_subtest_f("%s-modesetfrombusy", feature_str(t.feature))
modesetfrombusy_subtest(&t);
- if (t.feature & FEATURE_FBC)
+ if (t.feature & FEATURE_FBC) {
igt_subtest_f("%s-badstride", feature_str(t.feature))
badstride_subtest(&t);
+ igt_subtest_f("%s-stridechange", feature_str(t.feature))
+ stridechange_subtest(&t);
+ }
+
if (t.feature & FEATURE_PSR)
igt_subtest_f("%s-slowdraw", feature_str(t.feature))
slow_draw_subtest(&t);
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH igt 4/4] kms_frontbuffer_tracking: remove opt.only_feature
2015-10-20 21:22 ` [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 2/4] kms_frontbuffer_tracking: add flag to not assert feature status Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 3/4] kms_frontbuffer_tracking: add stridechange subtest Paulo Zanoni
@ 2015-10-20 21:22 ` Paulo Zanoni
2 siblings, 0 replies; 57+ messages in thread
From: Paulo Zanoni @ 2015-10-20 21:22 UTC (permalink / raw)
To: intel-gfx
That option is not needed anymore since:
commit 982934625ac67234c6d85c6cf29a5a487e54d4f0
Author: Thomas Wood <thomas.wood@intel.com>
Date: Wed Sep 16 14:36:24 2015 +0100
lib: allow wildcard matching when specifying subtests
In fact, using "--run-subtest 'fbc-*'" is better than using --fbc-only
due to how SKIPs are handled. In the former, only the tests matching
the expression are tried, so the number of SKIPs only contains the
number of tests on the specified pattern that were skipped. If you
used --fbc-only, all the non-fbc tests would count as SKIPs, so it
would be harder to know which of the tests marked as skipped were
actual FBC tests.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
tests/kms_frontbuffer_tracking.c | 29 ++---------------------------
1 file changed, 2 insertions(+), 27 deletions(-)
diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c
index e183a06..15707b9 100644
--- a/tests/kms_frontbuffer_tracking.c
+++ b/tests/kms_frontbuffer_tracking.c
@@ -239,7 +239,6 @@ struct {
bool small_modes;
bool show_hidden;
int step;
- int only_feature;
int only_pipes;
int shared_fb_x_offset;
int shared_fb_y_offset;
@@ -252,7 +251,6 @@ struct {
.small_modes = false,
.show_hidden= false,
.step = 0,
- .only_feature = FEATURE_COUNT,
.only_pipes = PIPE_COUNT,
.shared_fb_x_offset = 500,
.shared_fb_y_offset = 500,
@@ -1727,9 +1725,6 @@ static void check_test_requirements(const struct test_mode *t)
"Can't test PSR without sink CRCs\n");
}
- if (opt.only_feature != FEATURE_COUNT)
- igt_require(t->feature == opt.only_feature);
-
if (opt.only_pipes != PIPE_COUNT)
igt_require(t->pipes == opt.only_pipes);
}
@@ -2944,18 +2939,6 @@ static int opt_handler(int option, int option_index, void *data)
case 't':
opt.step++;
break;
- case 'n':
- igt_assert(opt.only_feature == FEATURE_COUNT);
- opt.only_feature = FEATURE_NONE;
- break;
- case 'f':
- igt_assert(opt.only_feature == FEATURE_COUNT);
- opt.only_feature = FEATURE_FBC;
- break;
- case 'p':
- igt_assert(opt.only_feature == FEATURE_COUNT);
- opt.only_feature = FEATURE_PSR;
- break;
case 'x':
errno = 0;
opt.shared_fb_x_offset = strtol(optarg, NULL, 0);
@@ -2990,9 +2973,6 @@ const char *help_str =
" --use-small-modes Use smaller resolutions for the modes\n"
" --show-hidden Show hidden subtests\n"
" --step Stop on each step so you can check the screen\n"
-" --nop-only Only run the \"nop\" feature subtests\n"
-" --fbc-only Only run the \"fbc\" feature subtests\n"
-" --psr-only Only run the \"psr\" feature subtests\n"
" --shared-fb-x offset Use 'offset' as the X offset for the shared FB\n"
" --shared-fb-y offset Use 'offset' as the Y offset for the shared FB\n"
" --1p-only Only run subtests that use 1 pipe\n"
@@ -3095,8 +3075,7 @@ static const char *format_str(enum pixel_format format)
if (!opt.show_hidden && t.pipes == PIPE_DUAL && \
t.screen == SCREEN_OFFSCREEN) \
continue; \
- if ((!opt.show_hidden && opt.only_feature != FEATURE_NONE) \
- && t.feature == FEATURE_NONE) \
+ if (!opt.show_hidden && t.feature == FEATURE_NONE) \
continue; \
if (!opt.show_hidden && t.fbs == FBS_SHARED && \
(t.plane == PLANE_CUR || t.plane == PLANE_SPR)) \
@@ -3117,9 +3096,6 @@ int main(int argc, char *argv[])
{ "use-small-modes", 0, 0, 'm'},
{ "show-hidden", 0, 0, 'i'},
{ "step", 0, 0, 't'},
- { "nop-only", 0, 0, 'n'},
- { "fbc-only", 0, 0, 'f'},
- { "psr-only", 0, 0, 'p'},
{ "shared-fb-x", 1, 0, 'x'},
{ "shared-fb-y", 1, 0, 'y'},
{ "1p-only", 0, 0, '1'},
@@ -3134,8 +3110,7 @@ int main(int argc, char *argv[])
setup_environment();
for (t.feature = 0; t.feature < FEATURE_COUNT; t.feature++) {
- if ((!opt.show_hidden && opt.only_feature != FEATURE_NONE)
- && t.feature == FEATURE_NONE)
+ if (!opt.show_hidden && t.feature == FEATURE_NONE)
continue;
for (t.pipes = 0; t.pipes < PIPE_COUNT; t.pipes++) {
t.screen = SCREEN_PRIM;
--
2.6.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string
2015-10-20 13:49 ` [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string Paulo Zanoni
@ 2015-10-21 6:52 ` Daniel Vetter
0 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2015-10-21 6:52 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:47AM -0200, Paulo Zanoni wrote:
> I wanted to add yet another check to intel_fbc_update() and realized
> I would need to create yet another enum no_fbc_reason case. So I
> remembered this patch series that Damien wrote a long time ago and
> nobody ever reviewed, so I decided to reimplement it since the code
> changed a lot since then.
>
> Credits-to: Damien Lespiau <damien.lespiau@intel.com>
> Cc: Damien Lespiau <damien.lespiau@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Yeah that enum indirection is pointless.
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
> drivers/gpu/drm/i915/i915_drv.h | 19 +--------
> drivers/gpu/drm/i915/intel_drv.h | 1 -
> drivers/gpu/drm/i915/intel_fbc.c | 77 +++++++++----------------------------
> 4 files changed, 20 insertions(+), 79 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index a3b22bd..6ac4ba3 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1640,7 +1640,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
> seq_puts(m, "FBC enabled\n");
> else
> seq_printf(m, "FBC disabled: %s\n",
> - intel_no_fbc_reason_str(dev_priv->fbc.no_fbc_reason));
> + dev_priv->fbc.no_fbc_reason);
>
> if (INTEL_INFO(dev_priv)->gen >= 7)
> seq_printf(m, "Compressing: %s\n",
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8afda45..c334525 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -925,24 +925,7 @@ struct i915_fbc {
> struct drm_framebuffer *fb;
> } *fbc_work;
>
> - enum no_fbc_reason {
> - FBC_OK, /* FBC is enabled */
> - FBC_UNSUPPORTED, /* FBC is not supported by this chipset */
> - FBC_NO_OUTPUT, /* no outputs enabled to compress */
> - FBC_STOLEN_TOO_SMALL, /* not enough space for buffers */
> - FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */
> - FBC_MODE_TOO_LARGE, /* mode too large for compression */
> - FBC_BAD_PLANE, /* fbc not supported on plane */
> - FBC_NOT_TILED, /* buffer not tiled */
> - FBC_MULTIPLE_PIPES, /* more than one pipe active */
> - FBC_MODULE_PARAM,
> - FBC_CHIP_DEFAULT, /* disabled by default on this chip */
> - FBC_ROTATION, /* rotation is not supported */
> - FBC_IN_DBG_MASTER, /* kernel debugger is active */
> - FBC_BAD_STRIDE, /* stride is not supported */
> - FBC_PIXEL_RATE, /* pixel rate is too big */
> - FBC_PIXEL_FORMAT /* pixel format is invalid */
> - } no_fbc_reason;
> + const char *no_fbc_reason;
>
> bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
> void (*enable_fbc)(struct intel_crtc *crtc);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 27dccf3..dc55e4c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1287,7 +1287,6 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
> enum fb_op_origin origin);
> void intel_fbc_flush(struct drm_i915_private *dev_priv,
> unsigned int frontbuffer_bits, enum fb_op_origin origin);
> -const char *intel_no_fbc_reason_str(enum no_fbc_reason reason);
> void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
>
> /* intel_hdmi.c */
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index cf47352..d9d7e54 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -471,55 +471,14 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc)
> mutex_unlock(&dev_priv->fbc.lock);
> }
>
> -const char *intel_no_fbc_reason_str(enum no_fbc_reason reason)
> -{
> - switch (reason) {
> - case FBC_OK:
> - return "FBC enabled but currently disabled in hardware";
> - case FBC_UNSUPPORTED:
> - return "unsupported by this chipset";
> - case FBC_NO_OUTPUT:
> - return "no output";
> - case FBC_STOLEN_TOO_SMALL:
> - return "not enough stolen memory";
> - case FBC_UNSUPPORTED_MODE:
> - return "mode incompatible with compression";
> - case FBC_MODE_TOO_LARGE:
> - return "mode too large for compression";
> - case FBC_BAD_PLANE:
> - return "FBC unsupported on plane";
> - case FBC_NOT_TILED:
> - return "framebuffer not tiled or fenced";
> - case FBC_MULTIPLE_PIPES:
> - return "more than one pipe active";
> - case FBC_MODULE_PARAM:
> - return "disabled per module param";
> - case FBC_CHIP_DEFAULT:
> - return "disabled per chip default";
> - case FBC_ROTATION:
> - return "rotation unsupported";
> - case FBC_IN_DBG_MASTER:
> - return "Kernel debugger is active";
> - case FBC_BAD_STRIDE:
> - return "framebuffer stride not supported";
> - case FBC_PIXEL_RATE:
> - return "pixel rate is too big";
> - case FBC_PIXEL_FORMAT:
> - return "pixel format is invalid";
> - default:
> - MISSING_CASE(reason);
> - return "unknown reason";
> - }
> -}
> -
> static void set_no_fbc_reason(struct drm_i915_private *dev_priv,
> - enum no_fbc_reason reason)
> + const char *reason)
> {
> if (dev_priv->fbc.no_fbc_reason == reason)
> return;
>
> dev_priv->fbc.no_fbc_reason = reason;
> - DRM_DEBUG_KMS("Disabling FBC: %s\n", intel_no_fbc_reason_str(reason));
> + DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> }
>
> static struct drm_crtc *intel_fbc_find_crtc(struct drm_i915_private *dev_priv)
> @@ -862,12 +821,12 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
> i915.enable_fbc = 0;
>
> if (i915.enable_fbc < 0) {
> - set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT);
> + set_no_fbc_reason(dev_priv, "disabled per chip default");
> goto out_disable;
> }
>
> if (!i915.enable_fbc) {
> - set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM);
> + set_no_fbc_reason(dev_priv, "disabled per module param");
> goto out_disable;
> }
>
> @@ -882,12 +841,12 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
> */
> crtc = intel_fbc_find_crtc(dev_priv);
> if (!crtc) {
> - set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT);
> + set_no_fbc_reason(dev_priv, "no output");
> goto out_disable;
> }
>
> if (!multiple_pipes_ok(dev_priv)) {
> - set_no_fbc_reason(dev_priv, FBC_MULTIPLE_PIPES);
> + set_no_fbc_reason(dev_priv, "more than one pipe active");
> goto out_disable;
> }
>
> @@ -898,18 +857,18 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
>
> if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
> (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
> - set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE);
> + set_no_fbc_reason(dev_priv, "incompatible mode");
> goto out_disable;
> }
>
> if (!intel_fbc_hw_tracking_covers_screen(intel_crtc)) {
> - set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE);
> + set_no_fbc_reason(dev_priv, "mode too large for compression");
> goto out_disable;
> }
>
> if ((INTEL_INFO(dev_priv)->gen < 4 || HAS_DDI(dev_priv)) &&
> intel_crtc->plane != PLANE_A) {
> - set_no_fbc_reason(dev_priv, FBC_BAD_PLANE);
> + set_no_fbc_reason(dev_priv, "FBC unsupported on plane");
> goto out_disable;
> }
>
> @@ -918,28 +877,28 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
> */
> if (obj->tiling_mode != I915_TILING_X ||
> obj->fence_reg == I915_FENCE_REG_NONE) {
> - set_no_fbc_reason(dev_priv, FBC_NOT_TILED);
> + set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced");
> goto out_disable;
> }
> if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) &&
> crtc->primary->state->rotation != BIT(DRM_ROTATE_0)) {
> - set_no_fbc_reason(dev_priv, FBC_ROTATION);
> + set_no_fbc_reason(dev_priv, "rotation unsupported");
> goto out_disable;
> }
>
> if (!stride_is_valid(dev_priv, fb->pitches[0])) {
> - set_no_fbc_reason(dev_priv, FBC_BAD_STRIDE);
> + set_no_fbc_reason(dev_priv, "framebuffer stride not supported");
> goto out_disable;
> }
>
> if (!pixel_format_is_valid(fb)) {
> - set_no_fbc_reason(dev_priv, FBC_PIXEL_FORMAT);
> + set_no_fbc_reason(dev_priv, "pixel format is invalid");
> goto out_disable;
> }
>
> /* If the kernel debugger is active, always disable compression */
> if (in_dbg_master()) {
> - set_no_fbc_reason(dev_priv, FBC_IN_DBG_MASTER);
> + set_no_fbc_reason(dev_priv, "Kernel debugger is active");
> goto out_disable;
> }
>
> @@ -947,12 +906,12 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
> if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
> ilk_pipe_pixel_rate(intel_crtc->config) >=
> dev_priv->cdclk_freq * 95 / 100) {
> - set_no_fbc_reason(dev_priv, FBC_PIXEL_RATE);
> + set_no_fbc_reason(dev_priv, "pixel rate is too big");
> goto out_disable;
> }
>
> if (intel_fbc_setup_cfb(intel_crtc)) {
> - set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL);
> + set_no_fbc_reason(dev_priv, "not enough stolen memory");
> goto out_disable;
> }
>
> @@ -995,7 +954,7 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
> }
>
> intel_fbc_schedule_enable(intel_crtc);
> - dev_priv->fbc.no_fbc_reason = FBC_OK;
> + dev_priv->fbc.no_fbc_reason = "FBC enabled (not necessarily active)\n";
> return;
>
> out_disable:
> @@ -1088,7 +1047,7 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
>
> if (!HAS_FBC(dev_priv)) {
> dev_priv->fbc.enabled = false;
> - dev_priv->fbc.no_fbc_reason = FBC_UNSUPPORTED;
> + dev_priv->fbc.no_fbc_reason = "unsupported by this chipset";
> return;
> }
>
> --
> 2.6.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 02/18] drm/i915: don't stop+start FBC at every flip
2015-10-20 13:49 ` [PATCH 02/18] drm/i915: don't stop+start FBC at every flip Paulo Zanoni
@ 2015-10-21 7:04 ` Daniel Vetter
2015-10-21 7:12 ` Ville Syrjälä
0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2015-10-21 7:04 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:48AM -0200, Paulo Zanoni wrote:
> The hardware already takes care of disabling and recompressing FBC
> when we do a page flip, so all we need to do is to update the fence
> registers and move on.
>
> One of the important things to notice is that on the pre-gen6
> platforms the fence is programmed on the FBC control register and the
> documentation says we can't update the control register while FBC is
> enabled. This would basically mean we'd have to to disable+enable FBC
> at every flip in order to make sure the hardware tracking still works,
> which doesn't seem to make too much sense. So I sent an email to the
> hardware team requesting some clarification. The information I got was
> this:
>
> "I don't think any hardware is latching on to 0x100100, 0x100104, or
> the old fence number in FBC_CTL. Instructions against changing on the
> fly would be to simplify testing and ensure you don't miss any
> invalidation that happened right at that time."
>
> So I guess we're fine for flips. But I can't really say I tested FBC
> on these ancient platforms - nor that I'll ever propose enabling FBC
> by default on them exactly because of problems like these.
>
> Testcase: igt/kms_frontbuffer_tracking/fbc*-fliptrack
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Iirc on pre-g4x flips don't invalidate the fbc compression, and we do
actually have to disable fbc entirely. There's some funky language that if
you want to flip with fbc you have to track the new backbuffer.
So I'm not entirely sure this is correct for the i8x case. Otoh we don't
ever enable it, so we could also just nuke the i8x fbc code. Either way it
doesn't matter to much.
> ---
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/i915_reg.h | 3 +
> drivers/gpu/drm/i915/intel_display.c | 1 -
> drivers/gpu/drm/i915/intel_drv.h | 2 +
> drivers/gpu/drm/i915/intel_fbc.c | 98 +++++++++++++++++++++++++++++++-
> drivers/gpu/drm/i915/intel_frontbuffer.c | 1 +
> 6 files changed, 103 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c334525..f04f56f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -930,6 +930,7 @@ struct i915_fbc {
> bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
> void (*enable_fbc)(struct intel_crtc *crtc);
> void (*disable_fbc)(struct drm_i915_private *dev_priv);
> + void (*flip_prepare)(struct drm_i915_private *dev_priv);
> };
>
> /**
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 9ebf032..3620b59 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2028,6 +2028,7 @@ enum skl_disp_power_wells {
> #define FBC_CTL_C3_IDLE (1<<13)
> #define FBC_CTL_STRIDE_SHIFT (5)
> #define FBC_CTL_FENCENO_SHIFT (0)
> +#define FBC_CTL_FENCENO_MASK 0xF
> #define FBC_COMMAND 0x0320c
> #define FBC_CMD_COMPRESS (1<<0)
> #define FBC_STATUS 0x03210
> @@ -2064,6 +2065,7 @@ enum skl_disp_power_wells {
> #define DPFC_CTL_LIMIT_1X (0<<6)
> #define DPFC_CTL_LIMIT_2X (1<<6)
> #define DPFC_CTL_LIMIT_4X (2<<6)
> +#define DPFC_CTL_FENCE_MASK 0xF
> #define DPFC_RECOMP_CTL 0x320c
> #define DPFC_RECOMP_STALL_EN (1<<27)
> #define DPFC_RECOMP_STALL_WM_SHIFT (16)
> @@ -2086,6 +2088,7 @@ enum skl_disp_power_wells {
> #define FBC_CTL_FALSE_COLOR (1<<10)
> /* The bit 28-8 is reserved */
> #define DPFC_RESERVED (0x1FFFFF00)
> +#define ILK_DPFC_FENCE_MASK 0xF
> #define ILK_DPFC_RECOMP_CTL 0x4320c
> #define ILK_DPFC_STATUS 0x43210
> #define ILK_DPFC_FENCE_YOFF 0x43218
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 1fc1d24..e83a428 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11470,7 +11470,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> to_intel_plane(primary)->frontbuffer_bit);
> mutex_unlock(&dev->struct_mutex);
>
> - intel_fbc_disable_crtc(intel_crtc);
> intel_frontbuffer_flip_prepare(dev,
> to_intel_plane(primary)->frontbuffer_bit);
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index dc55e4c..1e08c8a 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1287,6 +1287,8 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
> enum fb_op_origin origin);
> void intel_fbc_flush(struct drm_i915_private *dev_priv,
> unsigned int frontbuffer_bits, enum fb_op_origin origin);
> +void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
> + unsigned int frontbuffer_bits);
> void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
>
> /* intel_hdmi.c */
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index d9d7e54..9477379 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -82,6 +82,22 @@ static void i8xx_fbc_disable(struct drm_i915_private *dev_priv)
> DRM_DEBUG_KMS("disabled FBC\n");
> }
>
> +static void i8xx_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> +{
> + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> + struct drm_framebuffer *fb = crtc->base.primary->fb;
> + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> + uint32_t val;
> +
> + /* Although the documentation suggests we can't change DPFC_CONTROL
> + * while compression is enabled, the hardware guys said that updating
> + * the fence register bits during a flip is fine. */
> + val = I915_READ(FBC_CONTROL);
> + val &= ~FBC_CTL_FENCENO_MASK;
> + val |= obj->fence_reg;
> + I915_WRITE(FBC_CONTROL, val);
> +}
> +
> static void i8xx_fbc_enable(struct intel_crtc *crtc)
> {
> struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> @@ -161,6 +177,22 @@ static void g4x_fbc_enable(struct intel_crtc *crtc)
> DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
> }
>
> +static void g4x_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> +{
> + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> + struct drm_framebuffer *fb = crtc->base.primary->fb;
> + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> + uint32_t val;
> +
> + /* Although the documentation suggests we can't change DPFC_CONTROL
> + * while compression is enabled, the hardware guys said that updating
> + * the fence register bits during a flip is fine. */
> + val = I915_READ(DPFC_CONTROL);
> + val &= ~DPFC_CTL_FENCE_MASK;
> + val |= obj->fence_reg;
> + I915_WRITE(DPFC_CONTROL, val);
> +}
> +
> static void g4x_fbc_disable(struct drm_i915_private *dev_priv)
> {
> u32 dpfc_ctl;
> @@ -236,6 +268,31 @@ static void ilk_fbc_enable(struct intel_crtc *crtc)
> DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
> }
>
> +static void ilk_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> +{
> + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> + struct drm_framebuffer *fb = crtc->base.primary->fb;
> + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> + uint32_t val;
> +
> + /* Although the documentation suggests we can't change DPFC_CONTROL
> + * while compression is enabled, the hardware guys said that updating
> + * the fence register bits during a flip is fine. */
> + val = I915_READ(ILK_DPFC_CONTROL);
> + val &= ~ILK_DPFC_FENCE_MASK;
> + val |= obj->fence_reg;
> + I915_WRITE(ILK_DPFC_CONTROL, val);
> +}
> +
> +static void snb_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> +{
> + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> + struct drm_framebuffer *fb = crtc->base.primary->fb;
> + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> +
> + I915_WRITE(SNB_DPFC_CTL_SA, SNB_CPU_FENCE_ENABLE | obj->fence_reg);
> +}
> +
> static void ilk_fbc_disable(struct drm_i915_private *dev_priv)
> {
> u32 dpfc_ctl;
> @@ -1020,14 +1077,44 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
>
> if (origin == ORIGIN_GTT)
> return;
> + if (origin == ORIGIN_FLIP && dev_priv->fbc.enabled)
> + return;
>
> mutex_lock(&dev_priv->fbc.lock);
>
> dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
>
> if (!dev_priv->fbc.busy_bits) {
> - __intel_fbc_disable(dev_priv);
> - __intel_fbc_update(dev_priv);
> + if (origin == ORIGIN_FLIP) {
> + __intel_fbc_update(dev_priv);
> + } else {
> + __intel_fbc_disable(dev_priv);
> + __intel_fbc_update(dev_priv);
> + }
> + }
> +
> + mutex_unlock(&dev_priv->fbc.lock);
> +}
> +
> +void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
> + unsigned int frontbuffer_bits)
> +{
> + unsigned int fbc_bits;
> +
> + if (!fbc_supported(dev_priv))
> + return;
> +
> + mutex_lock(&dev_priv->fbc.lock);
> +
> + if (dev_priv->fbc.enabled) {
> + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
> + if (fbc_bits & frontbuffer_bits)
> + dev_priv->fbc.flip_prepare(dev_priv);
> + } else if (dev_priv->fbc.fbc_work) {
> + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(
> + dev_priv->fbc.fbc_work->crtc->pipe);
> + if (fbc_bits & frontbuffer_bits)
> + __intel_fbc_disable(dev_priv);
> }
>
> mutex_unlock(&dev_priv->fbc.lock);
> @@ -1063,18 +1150,25 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
> dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
> dev_priv->fbc.enable_fbc = gen7_fbc_enable;
> dev_priv->fbc.disable_fbc = ilk_fbc_disable;
> + dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
> } else if (INTEL_INFO(dev_priv)->gen >= 5) {
> dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
> dev_priv->fbc.enable_fbc = ilk_fbc_enable;
> dev_priv->fbc.disable_fbc = ilk_fbc_disable;
> + if (INTEL_INFO(dev_priv)->gen == 5)
> + dev_priv->fbc.flip_prepare = ilk_fbc_flip_prepare;
> + else
> + dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
> } else if (IS_GM45(dev_priv)) {
> dev_priv->fbc.fbc_enabled = g4x_fbc_enabled;
> dev_priv->fbc.enable_fbc = g4x_fbc_enable;
> dev_priv->fbc.disable_fbc = g4x_fbc_disable;
> + dev_priv->fbc.flip_prepare = g4x_fbc_flip_prepare;
> } else {
> dev_priv->fbc.fbc_enabled = i8xx_fbc_enabled;
> dev_priv->fbc.enable_fbc = i8xx_fbc_enable;
> dev_priv->fbc.disable_fbc = i8xx_fbc_disable;
> + dev_priv->fbc.flip_prepare = i8xx_fbc_flip_prepare;
>
> /* This value was pulled out of someone's hat */
> I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
> diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
> index ac85357..31a1ad3 100644
> --- a/drivers/gpu/drm/i915/intel_frontbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
> @@ -192,6 +192,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,
> mutex_unlock(&dev_priv->fb_tracking.lock);
>
> intel_psr_single_frame_update(dev, frontbuffer_bits);
> + intel_fbc_flip_prepare(dev_priv, frontbuffer_bits);
I haven't read ahead, but both psr single frame update and this here
should be converted. Since with this here there's the small (but very
real) chance that rendering the buffer for this flip will take longer than
the next vblank, and at least for the psr case we'd then fail to upload
the changes. For fbc it's less of a problem, since if you page flip then
userspace shouldn't race frontbuffer rendering.
So I think this is ok (but the PSR case should be fixed by moving the
register write itself into the atomic update, which means we need to have
a boolean to decided whether to do that in the intel_crtc_state).
-Daniel
> }
>
> /**
> --
> 2.6.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable
2015-10-20 13:50 ` [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable Paulo Zanoni
@ 2015-10-21 7:11 ` Daniel Vetter
2015-10-21 7:20 ` Ville Syrjälä
0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2015-10-21 7:11 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:50:01AM -0200, Paulo Zanoni wrote:
> One of the problems with the current code is that it frees the CFB and
> releases its drm_mm node as soon as we flip FBC's enable bit. This is
> bad because after we disbale FBC the hardware may still use the CFB
> for the rest of the frame, so in theory we should only release the
> drm_mm node one frame after we disable FBC. Otherwise, a stolen memory
> allocation done right after an FBC disable may result in either
> corrupted memory for the new owner of that memory region or corrupted
> screen/underruns in case the new owner changes it while the hardware
> is still reading it. This case is not exactly easy to reproduce since
> we currently don't do a lot of stolen memory allocations, but I see
> patches on the mailing list trying to expose stolen memory to user
> space, so races will be possible.
>
> I thought about three different approaches to solve this, and they all
> have downsides.
>
> The first approach would be to simply use multiple drm_mm nodes and
> freeing the unused ones only after a frame has passed. The problem
> with this approach is that since stolen memory is rather small,
> there's a risk we just won't be able to allocate a new CFB from stolen
> if the previous one was not freed yet. This could happen in case we
> quickly disable FBC from pipe A and decide to enable it on pipe B, or
> just if we change pipe A's fb stride while FBC is enabled.
>
> The second approach would be similar to the first one, but maintaining
> a single drm_mm node and keeping track of when it can be reused. This
> would remove the disadvantage of not having enough space for two
> nodes, but would create the new problem where we may not be able to
> enable FBC at the point intel_fbc_update() is called, so we would have
> to add more code to retry updating FBC after the time has passed. And
> that can quickly get too complex since we can get invalidate, flush,
> flip_prepare, disable and other calls in the middle of the wait.
>
> Both solutions above - and also the current code - have the problem
> that we unnecessarily free+realloc FBC during invalidate+flush
> operations even if the CFB size doesn't change.
>
> The third option would be to move the allocation/deallocation to
> enable/disable. This makes sure that the pipe is always disabled when
> we allocate/deallocate the CFB, so there's no risk that the FBC
> hardware may read or write to the memory right after it is freed from
> drm_mm. The downside is that it is possible for user space to change
> the buffer stride without triggering a disable/enable - only
> deactivate/activate -, so we'll have to handle this case somehow, even
> though it is uncommon - see igt's kms_frontbuffer_tracking test,
> fbc-stridechange subtest. It could be possible to implement a way to
> free+alloc the CFB during said stride change, but it would involve a
> lot of book-keeping - exactly as mentioned above - just for a rare
> case, so for now I'll keep it simple and just deactivate FBC. Besides,
> we may not even need to disable FBC since we do CFB over-allocation.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_fbc.c | 132 ++++++++++++++++++++-------------------
> 1 file changed, 68 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index bf855b2..48d8cfc 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -59,6 +59,45 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)
> return crtc->base.y - crtc->adjusted_y;
> }
>
> +/*
> + * 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(struct intel_crtc *crtc,
> + int *width, int *height)
> +{
> + struct intel_plane_state *plane_state =
> + to_intel_plane_state(crtc->base.primary->state);
> + int w, h;
> +
> + if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> + w = drm_rect_height(&plane_state->src) >> 16;
> + h = drm_rect_width(&plane_state->src) >> 16;
> + } else {
> + w = drm_rect_width(&plane_state->src) >> 16;
> + h = drm_rect_height(&plane_state->src) >> 16;
> + }
> +
> + if (width)
> + *width = w;
> + if (height)
> + *height = h;
> +}
> +
> +static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc,
> + struct drm_framebuffer *fb)
> +{
> + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> + int lines;
> +
> + intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> + if (INTEL_INFO(dev_priv)->gen >= 7)
> + lines = min(lines, 2048);
> +
> + return lines * fb->pitches[0];
Why are we even looking at fb->pitches here? I thought that for fbc we
only compress what we actually scan out, i.e. the source rectangle of the
plane in pixels. Maybe some rounding involved perhaps.
Or did I miss something?
-Daniel
> +}
> +
> static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
> {
> u32 fbc_ctl;
> @@ -604,11 +643,17 @@ again:
> }
> }
>
> -static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, int size,
> - int fb_cpp)
> +static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
> {
> + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> + struct drm_framebuffer *fb = crtc->base.primary->state->fb;
> struct drm_mm_node *uninitialized_var(compressed_llb);
> - int ret;
> + int size, fb_cpp, ret;
> +
> + WARN_ON(dev_priv->fbc.compressed_fb.allocated);
> +
> + size = intel_fbc_calculate_cfb_size(crtc, fb);
> + fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0);
>
> ret = find_compression_threshold(dev_priv, &dev_priv->fbc.compressed_fb,
> size, fb_cpp);
> @@ -685,64 +730,6 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
> mutex_unlock(&dev_priv->fbc.lock);
> }
>
> -/*
> - * 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(struct intel_crtc *crtc,
> - int *width, int *height)
> -{
> - struct intel_plane_state *plane_state =
> - to_intel_plane_state(crtc->base.primary->state);
> - int w, h;
> -
> - if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> - w = drm_rect_height(&plane_state->src) >> 16;
> - h = drm_rect_width(&plane_state->src) >> 16;
> - } else {
> - w = drm_rect_width(&plane_state->src) >> 16;
> - h = drm_rect_height(&plane_state->src) >> 16;
> - }
> -
> - if (width)
> - *width = w;
> - if (height)
> - *height = h;
> -}
> -
> -static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc)
> -{
> - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> - struct drm_framebuffer *fb = crtc->base.primary->fb;
> - int lines;
> -
> - intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> - if (INTEL_INFO(dev_priv)->gen >= 7)
> - lines = min(lines, 2048);
> -
> - return lines * fb->pitches[0];
> -}
> -
> -static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
> -{
> - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> - struct drm_framebuffer *fb = crtc->base.primary->fb;
> - int size, cpp;
> -
> - size = intel_fbc_calculate_cfb_size(crtc);
> - cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> -
> - if (dev_priv->fbc.compressed_fb.allocated &&
> - size <= dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold)
> - return 0;
> -
> - /* Release any current block */
> - __intel_fbc_cleanup_cfb(dev_priv);
> -
> - return intel_fbc_alloc_cfb(dev_priv, size, cpp);
> -}
> -
> static bool stride_is_valid(struct drm_i915_private *dev_priv,
> unsigned int stride)
> {
> @@ -904,8 +891,19 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
> goto out_disable;
> }
>
> - if (intel_fbc_setup_cfb(crtc)) {
> - set_no_fbc_reason(dev_priv, "not enough stolen memory");
> + /* 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
> + * if this happens, but if we exceed the current CFB size we'll have to
> + * disable FBC. Notice that it would be possible to disable FBC, wait
> + * 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 case we expect to be uncommon, so we
> + * just don't have this code for now. */
> + if (intel_fbc_calculate_cfb_size(crtc, fb) >
> + dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) {
> + set_no_fbc_reason(dev_priv, "CFB requirements changed");
> goto out_disable;
> }
>
> @@ -958,7 +956,6 @@ out_disable:
> DRM_DEBUG_KMS("unsupported config, deactivating FBC\n");
> __intel_fbc_deactivate(dev_priv);
> }
> - __intel_fbc_cleanup_cfb(dev_priv);
> }
>
> /*
> @@ -1102,6 +1099,11 @@ void intel_fbc_enable(struct intel_crtc *crtc)
> goto out;
> }
>
> + if (intel_fbc_alloc_cfb(crtc)) {
> + set_no_fbc_reason(dev_priv, "not enough stolen memory");
> + goto out;
> + }
> +
> DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
> dev_priv->fbc.no_fbc_reason = "FBC enabled but not active yet\n";
>
> @@ -1129,6 +1131,8 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
>
> DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
>
> + __intel_fbc_cleanup_cfb(dev_priv);
> +
> dev_priv->fbc.enabled = false;
> dev_priv->fbc.crtc = NULL;
> }
> --
> 2.6.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 02/18] drm/i915: don't stop+start FBC at every flip
2015-10-21 7:04 ` Daniel Vetter
@ 2015-10-21 7:12 ` Ville Syrjälä
2015-10-21 7:40 ` Ville Syrjälä
0 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjälä @ 2015-10-21 7:12 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Wed, Oct 21, 2015 at 09:04:39AM +0200, Daniel Vetter wrote:
> On Tue, Oct 20, 2015 at 11:49:48AM -0200, Paulo Zanoni wrote:
> > The hardware already takes care of disabling and recompressing FBC
> > when we do a page flip, so all we need to do is to update the fence
> > registers and move on.
> >
> > One of the important things to notice is that on the pre-gen6
> > platforms the fence is programmed on the FBC control register and the
> > documentation says we can't update the control register while FBC is
> > enabled. This would basically mean we'd have to to disable+enable FBC
> > at every flip in order to make sure the hardware tracking still works,
> > which doesn't seem to make too much sense. So I sent an email to the
> > hardware team requesting some clarification. The information I got was
> > this:
> >
> > "I don't think any hardware is latching on to 0x100100, 0x100104, or
> > the old fence number in FBC_CTL. Instructions against changing on the
> > fly would be to simplify testing and ensure you don't miss any
> > invalidation that happened right at that time."
> >
> > So I guess we're fine for flips. But I can't really say I tested FBC
> > on these ancient platforms - nor that I'll ever propose enabling FBC
> > by default on them exactly because of problems like these.
> >
> > Testcase: igt/kms_frontbuffer_tracking/fbc*-fliptrack
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Iirc on pre-g4x flips don't invalidate the fbc compression, and we do
> actually have to disable fbc entirely.
Nope. At least my gen2 was doing fine with hw flip nuke >1 year ago.
> There's some funky language that if
> you want to flip with fbc you have to track the new backbuffer.
>
> So I'm not entirely sure this is correct for the i8x case. Otoh we don't
> ever enable it, so we could also just nuke the i8x fbc code. Either way it
> doesn't matter to much.
>
> > ---
> > drivers/gpu/drm/i915/i915_drv.h | 1 +
> > drivers/gpu/drm/i915/i915_reg.h | 3 +
> > drivers/gpu/drm/i915/intel_display.c | 1 -
> > drivers/gpu/drm/i915/intel_drv.h | 2 +
> > drivers/gpu/drm/i915/intel_fbc.c | 98 +++++++++++++++++++++++++++++++-
> > drivers/gpu/drm/i915/intel_frontbuffer.c | 1 +
> > 6 files changed, 103 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index c334525..f04f56f 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -930,6 +930,7 @@ struct i915_fbc {
> > bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
> > void (*enable_fbc)(struct intel_crtc *crtc);
> > void (*disable_fbc)(struct drm_i915_private *dev_priv);
> > + void (*flip_prepare)(struct drm_i915_private *dev_priv);
> > };
> >
> > /**
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 9ebf032..3620b59 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -2028,6 +2028,7 @@ enum skl_disp_power_wells {
> > #define FBC_CTL_C3_IDLE (1<<13)
> > #define FBC_CTL_STRIDE_SHIFT (5)
> > #define FBC_CTL_FENCENO_SHIFT (0)
> > +#define FBC_CTL_FENCENO_MASK 0xF
> > #define FBC_COMMAND 0x0320c
> > #define FBC_CMD_COMPRESS (1<<0)
> > #define FBC_STATUS 0x03210
> > @@ -2064,6 +2065,7 @@ enum skl_disp_power_wells {
> > #define DPFC_CTL_LIMIT_1X (0<<6)
> > #define DPFC_CTL_LIMIT_2X (1<<6)
> > #define DPFC_CTL_LIMIT_4X (2<<6)
> > +#define DPFC_CTL_FENCE_MASK 0xF
> > #define DPFC_RECOMP_CTL 0x320c
> > #define DPFC_RECOMP_STALL_EN (1<<27)
> > #define DPFC_RECOMP_STALL_WM_SHIFT (16)
> > @@ -2086,6 +2088,7 @@ enum skl_disp_power_wells {
> > #define FBC_CTL_FALSE_COLOR (1<<10)
> > /* The bit 28-8 is reserved */
> > #define DPFC_RESERVED (0x1FFFFF00)
> > +#define ILK_DPFC_FENCE_MASK 0xF
> > #define ILK_DPFC_RECOMP_CTL 0x4320c
> > #define ILK_DPFC_STATUS 0x43210
> > #define ILK_DPFC_FENCE_YOFF 0x43218
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 1fc1d24..e83a428 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -11470,7 +11470,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> > to_intel_plane(primary)->frontbuffer_bit);
> > mutex_unlock(&dev->struct_mutex);
> >
> > - intel_fbc_disable_crtc(intel_crtc);
> > intel_frontbuffer_flip_prepare(dev,
> > to_intel_plane(primary)->frontbuffer_bit);
> >
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index dc55e4c..1e08c8a 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1287,6 +1287,8 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
> > enum fb_op_origin origin);
> > void intel_fbc_flush(struct drm_i915_private *dev_priv,
> > unsigned int frontbuffer_bits, enum fb_op_origin origin);
> > +void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
> > + unsigned int frontbuffer_bits);
> > void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
> >
> > /* intel_hdmi.c */
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> > index d9d7e54..9477379 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -82,6 +82,22 @@ static void i8xx_fbc_disable(struct drm_i915_private *dev_priv)
> > DRM_DEBUG_KMS("disabled FBC\n");
> > }
> >
> > +static void i8xx_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > +{
> > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > + uint32_t val;
> > +
> > + /* Although the documentation suggests we can't change DPFC_CONTROL
> > + * while compression is enabled, the hardware guys said that updating
> > + * the fence register bits during a flip is fine. */
> > + val = I915_READ(FBC_CONTROL);
> > + val &= ~FBC_CTL_FENCENO_MASK;
> > + val |= obj->fence_reg;
> > + I915_WRITE(FBC_CONTROL, val);
> > +}
> > +
> > static void i8xx_fbc_enable(struct intel_crtc *crtc)
> > {
> > struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > @@ -161,6 +177,22 @@ static void g4x_fbc_enable(struct intel_crtc *crtc)
> > DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
> > }
> >
> > +static void g4x_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > +{
> > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > + uint32_t val;
> > +
> > + /* Although the documentation suggests we can't change DPFC_CONTROL
> > + * while compression is enabled, the hardware guys said that updating
> > + * the fence register bits during a flip is fine. */
> > + val = I915_READ(DPFC_CONTROL);
> > + val &= ~DPFC_CTL_FENCE_MASK;
> > + val |= obj->fence_reg;
> > + I915_WRITE(DPFC_CONTROL, val);
> > +}
> > +
> > static void g4x_fbc_disable(struct drm_i915_private *dev_priv)
> > {
> > u32 dpfc_ctl;
> > @@ -236,6 +268,31 @@ static void ilk_fbc_enable(struct intel_crtc *crtc)
> > DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
> > }
> >
> > +static void ilk_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > +{
> > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > + uint32_t val;
> > +
> > + /* Although the documentation suggests we can't change DPFC_CONTROL
> > + * while compression is enabled, the hardware guys said that updating
> > + * the fence register bits during a flip is fine. */
> > + val = I915_READ(ILK_DPFC_CONTROL);
> > + val &= ~ILK_DPFC_FENCE_MASK;
> > + val |= obj->fence_reg;
> > + I915_WRITE(ILK_DPFC_CONTROL, val);
> > +}
> > +
> > +static void snb_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > +{
> > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > +
> > + I915_WRITE(SNB_DPFC_CTL_SA, SNB_CPU_FENCE_ENABLE | obj->fence_reg);
> > +}
> > +
> > static void ilk_fbc_disable(struct drm_i915_private *dev_priv)
> > {
> > u32 dpfc_ctl;
> > @@ -1020,14 +1077,44 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
> >
> > if (origin == ORIGIN_GTT)
> > return;
> > + if (origin == ORIGIN_FLIP && dev_priv->fbc.enabled)
> > + return;
> >
> > mutex_lock(&dev_priv->fbc.lock);
> >
> > dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
> >
> > if (!dev_priv->fbc.busy_bits) {
> > - __intel_fbc_disable(dev_priv);
> > - __intel_fbc_update(dev_priv);
> > + if (origin == ORIGIN_FLIP) {
> > + __intel_fbc_update(dev_priv);
> > + } else {
> > + __intel_fbc_disable(dev_priv);
> > + __intel_fbc_update(dev_priv);
> > + }
> > + }
> > +
> > + mutex_unlock(&dev_priv->fbc.lock);
> > +}
> > +
> > +void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
> > + unsigned int frontbuffer_bits)
> > +{
> > + unsigned int fbc_bits;
> > +
> > + if (!fbc_supported(dev_priv))
> > + return;
> > +
> > + mutex_lock(&dev_priv->fbc.lock);
> > +
> > + if (dev_priv->fbc.enabled) {
> > + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
> > + if (fbc_bits & frontbuffer_bits)
> > + dev_priv->fbc.flip_prepare(dev_priv);
> > + } else if (dev_priv->fbc.fbc_work) {
> > + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(
> > + dev_priv->fbc.fbc_work->crtc->pipe);
> > + if (fbc_bits & frontbuffer_bits)
> > + __intel_fbc_disable(dev_priv);
> > }
> >
> > mutex_unlock(&dev_priv->fbc.lock);
> > @@ -1063,18 +1150,25 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
> > dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
> > dev_priv->fbc.enable_fbc = gen7_fbc_enable;
> > dev_priv->fbc.disable_fbc = ilk_fbc_disable;
> > + dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
> > } else if (INTEL_INFO(dev_priv)->gen >= 5) {
> > dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
> > dev_priv->fbc.enable_fbc = ilk_fbc_enable;
> > dev_priv->fbc.disable_fbc = ilk_fbc_disable;
> > + if (INTEL_INFO(dev_priv)->gen == 5)
> > + dev_priv->fbc.flip_prepare = ilk_fbc_flip_prepare;
> > + else
> > + dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
> > } else if (IS_GM45(dev_priv)) {
> > dev_priv->fbc.fbc_enabled = g4x_fbc_enabled;
> > dev_priv->fbc.enable_fbc = g4x_fbc_enable;
> > dev_priv->fbc.disable_fbc = g4x_fbc_disable;
> > + dev_priv->fbc.flip_prepare = g4x_fbc_flip_prepare;
> > } else {
> > dev_priv->fbc.fbc_enabled = i8xx_fbc_enabled;
> > dev_priv->fbc.enable_fbc = i8xx_fbc_enable;
> > dev_priv->fbc.disable_fbc = i8xx_fbc_disable;
> > + dev_priv->fbc.flip_prepare = i8xx_fbc_flip_prepare;
> >
> > /* This value was pulled out of someone's hat */
> > I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
> > diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
> > index ac85357..31a1ad3 100644
> > --- a/drivers/gpu/drm/i915/intel_frontbuffer.c
> > +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
> > @@ -192,6 +192,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,
> > mutex_unlock(&dev_priv->fb_tracking.lock);
> >
> > intel_psr_single_frame_update(dev, frontbuffer_bits);
> > + intel_fbc_flip_prepare(dev_priv, frontbuffer_bits);
>
> I haven't read ahead, but both psr single frame update and this here
> should be converted. Since with this here there's the small (but very
> real) chance that rendering the buffer for this flip will take longer than
> the next vblank, and at least for the psr case we'd then fail to upload
> the changes. For fbc it's less of a problem, since if you page flip then
> userspace shouldn't race frontbuffer rendering.
>
> So I think this is ok (but the PSR case should be fixed by moving the
> register write itself into the atomic update, which means we need to have
> a boolean to decided whether to do that in the intel_crtc_state).
> -Daniel
>
>
> > }
> >
> > /**
> > --
> > 2.6.1
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable
2015-10-21 7:11 ` Daniel Vetter
@ 2015-10-21 7:20 ` Ville Syrjälä
2015-10-21 7:24 ` Daniel Vetter
0 siblings, 1 reply; 57+ messages in thread
From: Ville Syrjälä @ 2015-10-21 7:20 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Wed, Oct 21, 2015 at 09:11:08AM +0200, Daniel Vetter wrote:
> On Tue, Oct 20, 2015 at 11:50:01AM -0200, Paulo Zanoni wrote:
> > One of the problems with the current code is that it frees the CFB and
> > releases its drm_mm node as soon as we flip FBC's enable bit. This is
> > bad because after we disbale FBC the hardware may still use the CFB
> > for the rest of the frame, so in theory we should only release the
> > drm_mm node one frame after we disable FBC. Otherwise, a stolen memory
> > allocation done right after an FBC disable may result in either
> > corrupted memory for the new owner of that memory region or corrupted
> > screen/underruns in case the new owner changes it while the hardware
> > is still reading it. This case is not exactly easy to reproduce since
> > we currently don't do a lot of stolen memory allocations, but I see
> > patches on the mailing list trying to expose stolen memory to user
> > space, so races will be possible.
> >
> > I thought about three different approaches to solve this, and they all
> > have downsides.
> >
> > The first approach would be to simply use multiple drm_mm nodes and
> > freeing the unused ones only after a frame has passed. The problem
> > with this approach is that since stolen memory is rather small,
> > there's a risk we just won't be able to allocate a new CFB from stolen
> > if the previous one was not freed yet. This could happen in case we
> > quickly disable FBC from pipe A and decide to enable it on pipe B, or
> > just if we change pipe A's fb stride while FBC is enabled.
> >
> > The second approach would be similar to the first one, but maintaining
> > a single drm_mm node and keeping track of when it can be reused. This
> > would remove the disadvantage of not having enough space for two
> > nodes, but would create the new problem where we may not be able to
> > enable FBC at the point intel_fbc_update() is called, so we would have
> > to add more code to retry updating FBC after the time has passed. And
> > that can quickly get too complex since we can get invalidate, flush,
> > flip_prepare, disable and other calls in the middle of the wait.
> >
> > Both solutions above - and also the current code - have the problem
> > that we unnecessarily free+realloc FBC during invalidate+flush
> > operations even if the CFB size doesn't change.
> >
> > The third option would be to move the allocation/deallocation to
> > enable/disable. This makes sure that the pipe is always disabled when
> > we allocate/deallocate the CFB, so there's no risk that the FBC
> > hardware may read or write to the memory right after it is freed from
> > drm_mm. The downside is that it is possible for user space to change
> > the buffer stride without triggering a disable/enable - only
> > deactivate/activate -, so we'll have to handle this case somehow, even
> > though it is uncommon - see igt's kms_frontbuffer_tracking test,
> > fbc-stridechange subtest. It could be possible to implement a way to
> > free+alloc the CFB during said stride change, but it would involve a
> > lot of book-keeping - exactly as mentioned above - just for a rare
> > case, so for now I'll keep it simple and just deactivate FBC. Besides,
> > we may not even need to disable FBC since we do CFB over-allocation.
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_fbc.c | 132 ++++++++++++++++++++-------------------
> > 1 file changed, 68 insertions(+), 64 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> > index bf855b2..48d8cfc 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -59,6 +59,45 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)
> > return crtc->base.y - crtc->adjusted_y;
> > }
> >
> > +/*
> > + * 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(struct intel_crtc *crtc,
> > + int *width, int *height)
> > +{
> > + struct intel_plane_state *plane_state =
> > + to_intel_plane_state(crtc->base.primary->state);
> > + int w, h;
> > +
> > + if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> > + w = drm_rect_height(&plane_state->src) >> 16;
> > + h = drm_rect_width(&plane_state->src) >> 16;
> > + } else {
> > + w = drm_rect_width(&plane_state->src) >> 16;
> > + h = drm_rect_height(&plane_state->src) >> 16;
> > + }
> > +
> > + if (width)
> > + *width = w;
> > + if (height)
> > + *height = h;
> > +}
> > +
> > +static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc,
> > + struct drm_framebuffer *fb)
> > +{
> > + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > + int lines;
> > +
> > + intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > + if (INTEL_INFO(dev_priv)->gen >= 7)
> > + lines = min(lines, 2048);
> > +
> > + return lines * fb->pitches[0];
>
> Why are we even looking at fb->pitches here? I thought that for fbc we
> only compress what we actually scan out, i.e. the source rectangle of the
> plane in pixels. Maybe some rounding involved perhaps.
IIRC the docs do say the hw uses the plane stride register figure this
out. It's something I've been wondering for a few years now, but never
actually tested to see if we can get away with less.
>
> Or did I miss something?
> -Daniel
>
> > +}
> > +
> > static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
> > {
> > u32 fbc_ctl;
> > @@ -604,11 +643,17 @@ again:
> > }
> > }
> >
> > -static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, int size,
> > - int fb_cpp)
> > +static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
> > {
> > + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > + struct drm_framebuffer *fb = crtc->base.primary->state->fb;
> > struct drm_mm_node *uninitialized_var(compressed_llb);
> > - int ret;
> > + int size, fb_cpp, ret;
> > +
> > + WARN_ON(dev_priv->fbc.compressed_fb.allocated);
> > +
> > + size = intel_fbc_calculate_cfb_size(crtc, fb);
> > + fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> >
> > ret = find_compression_threshold(dev_priv, &dev_priv->fbc.compressed_fb,
> > size, fb_cpp);
> > @@ -685,64 +730,6 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
> > mutex_unlock(&dev_priv->fbc.lock);
> > }
> >
> > -/*
> > - * 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(struct intel_crtc *crtc,
> > - int *width, int *height)
> > -{
> > - struct intel_plane_state *plane_state =
> > - to_intel_plane_state(crtc->base.primary->state);
> > - int w, h;
> > -
> > - if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> > - w = drm_rect_height(&plane_state->src) >> 16;
> > - h = drm_rect_width(&plane_state->src) >> 16;
> > - } else {
> > - w = drm_rect_width(&plane_state->src) >> 16;
> > - h = drm_rect_height(&plane_state->src) >> 16;
> > - }
> > -
> > - if (width)
> > - *width = w;
> > - if (height)
> > - *height = h;
> > -}
> > -
> > -static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc)
> > -{
> > - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > - int lines;
> > -
> > - intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > - if (INTEL_INFO(dev_priv)->gen >= 7)
> > - lines = min(lines, 2048);
> > -
> > - return lines * fb->pitches[0];
> > -}
> > -
> > -static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
> > -{
> > - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > - int size, cpp;
> > -
> > - size = intel_fbc_calculate_cfb_size(crtc);
> > - cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > -
> > - if (dev_priv->fbc.compressed_fb.allocated &&
> > - size <= dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold)
> > - return 0;
> > -
> > - /* Release any current block */
> > - __intel_fbc_cleanup_cfb(dev_priv);
> > -
> > - return intel_fbc_alloc_cfb(dev_priv, size, cpp);
> > -}
> > -
> > static bool stride_is_valid(struct drm_i915_private *dev_priv,
> > unsigned int stride)
> > {
> > @@ -904,8 +891,19 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
> > goto out_disable;
> > }
> >
> > - if (intel_fbc_setup_cfb(crtc)) {
> > - set_no_fbc_reason(dev_priv, "not enough stolen memory");
> > + /* 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
> > + * if this happens, but if we exceed the current CFB size we'll have to
> > + * disable FBC. Notice that it would be possible to disable FBC, wait
> > + * 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 case we expect to be uncommon, so we
> > + * just don't have this code for now. */
> > + if (intel_fbc_calculate_cfb_size(crtc, fb) >
> > + dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) {
> > + set_no_fbc_reason(dev_priv, "CFB requirements changed");
> > goto out_disable;
> > }
> >
> > @@ -958,7 +956,6 @@ out_disable:
> > DRM_DEBUG_KMS("unsupported config, deactivating FBC\n");
> > __intel_fbc_deactivate(dev_priv);
> > }
> > - __intel_fbc_cleanup_cfb(dev_priv);
> > }
> >
> > /*
> > @@ -1102,6 +1099,11 @@ void intel_fbc_enable(struct intel_crtc *crtc)
> > goto out;
> > }
> >
> > + if (intel_fbc_alloc_cfb(crtc)) {
> > + set_no_fbc_reason(dev_priv, "not enough stolen memory");
> > + goto out;
> > + }
> > +
> > DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
> > dev_priv->fbc.no_fbc_reason = "FBC enabled but not active yet\n";
> >
> > @@ -1129,6 +1131,8 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
> >
> > DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
> >
> > + __intel_fbc_cleanup_cfb(dev_priv);
> > +
> > dev_priv->fbc.enabled = false;
> > dev_priv->fbc.crtc = NULL;
> > }
> > --
> > 2.6.1
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable
2015-10-21 7:20 ` Ville Syrjälä
@ 2015-10-21 7:24 ` Daniel Vetter
2015-10-21 18:30 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2015-10-21 7:24 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: intel-gfx
On Wed, Oct 21, 2015 at 10:20:55AM +0300, Ville Syrjälä wrote:
> On Wed, Oct 21, 2015 at 09:11:08AM +0200, Daniel Vetter wrote:
> > On Tue, Oct 20, 2015 at 11:50:01AM -0200, Paulo Zanoni wrote:
> > > One of the problems with the current code is that it frees the CFB and
> > > releases its drm_mm node as soon as we flip FBC's enable bit. This is
> > > bad because after we disbale FBC the hardware may still use the CFB
> > > for the rest of the frame, so in theory we should only release the
> > > drm_mm node one frame after we disable FBC. Otherwise, a stolen memory
> > > allocation done right after an FBC disable may result in either
> > > corrupted memory for the new owner of that memory region or corrupted
> > > screen/underruns in case the new owner changes it while the hardware
> > > is still reading it. This case is not exactly easy to reproduce since
> > > we currently don't do a lot of stolen memory allocations, but I see
> > > patches on the mailing list trying to expose stolen memory to user
> > > space, so races will be possible.
> > >
> > > I thought about three different approaches to solve this, and they all
> > > have downsides.
> > >
> > > The first approach would be to simply use multiple drm_mm nodes and
> > > freeing the unused ones only after a frame has passed. The problem
> > > with this approach is that since stolen memory is rather small,
> > > there's a risk we just won't be able to allocate a new CFB from stolen
> > > if the previous one was not freed yet. This could happen in case we
> > > quickly disable FBC from pipe A and decide to enable it on pipe B, or
> > > just if we change pipe A's fb stride while FBC is enabled.
> > >
> > > The second approach would be similar to the first one, but maintaining
> > > a single drm_mm node and keeping track of when it can be reused. This
> > > would remove the disadvantage of not having enough space for two
> > > nodes, but would create the new problem where we may not be able to
> > > enable FBC at the point intel_fbc_update() is called, so we would have
> > > to add more code to retry updating FBC after the time has passed. And
> > > that can quickly get too complex since we can get invalidate, flush,
> > > flip_prepare, disable and other calls in the middle of the wait.
> > >
> > > Both solutions above - and also the current code - have the problem
> > > that we unnecessarily free+realloc FBC during invalidate+flush
> > > operations even if the CFB size doesn't change.
> > >
> > > The third option would be to move the allocation/deallocation to
> > > enable/disable. This makes sure that the pipe is always disabled when
> > > we allocate/deallocate the CFB, so there's no risk that the FBC
> > > hardware may read or write to the memory right after it is freed from
> > > drm_mm. The downside is that it is possible for user space to change
> > > the buffer stride without triggering a disable/enable - only
> > > deactivate/activate -, so we'll have to handle this case somehow, even
> > > though it is uncommon - see igt's kms_frontbuffer_tracking test,
> > > fbc-stridechange subtest. It could be possible to implement a way to
> > > free+alloc the CFB during said stride change, but it would involve a
> > > lot of book-keeping - exactly as mentioned above - just for a rare
> > > case, so for now I'll keep it simple and just deactivate FBC. Besides,
> > > we may not even need to disable FBC since we do CFB over-allocation.
> > >
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > ---
> > > drivers/gpu/drm/i915/intel_fbc.c | 132 ++++++++++++++++++++-------------------
> > > 1 file changed, 68 insertions(+), 64 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> > > index bf855b2..48d8cfc 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -59,6 +59,45 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc)
> > > return crtc->base.y - crtc->adjusted_y;
> > > }
> > >
> > > +/*
> > > + * 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(struct intel_crtc *crtc,
> > > + int *width, int *height)
> > > +{
> > > + struct intel_plane_state *plane_state =
> > > + to_intel_plane_state(crtc->base.primary->state);
> > > + int w, h;
> > > +
> > > + if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> > > + w = drm_rect_height(&plane_state->src) >> 16;
> > > + h = drm_rect_width(&plane_state->src) >> 16;
> > > + } else {
> > > + w = drm_rect_width(&plane_state->src) >> 16;
> > > + h = drm_rect_height(&plane_state->src) >> 16;
> > > + }
> > > +
> > > + if (width)
> > > + *width = w;
> > > + if (height)
> > > + *height = h;
> > > +}
> > > +
> > > +static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc,
> > > + struct drm_framebuffer *fb)
> > > +{
> > > + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > > + int lines;
> > > +
> > > + intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > > + if (INTEL_INFO(dev_priv)->gen >= 7)
> > > + lines = min(lines, 2048);
> > > +
> > > + return lines * fb->pitches[0];
> >
> > Why are we even looking at fb->pitches here? I thought that for fbc we
> > only compress what we actually scan out, i.e. the source rectangle of the
> > plane in pixels. Maybe some rounding involved perhaps.
>
> IIRC the docs do say the hw uses the plane stride register figure this
> out. It's something I've been wondering for a few years now, but never
> actually tested to see if we can get away with less.
In that case a comment would be great, maybe even with the Bspec citation.
-Daniel
>
> >
> > Or did I miss something?
> > -Daniel
> >
> > > +}
> > > +
> > > static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
> > > {
> > > u32 fbc_ctl;
> > > @@ -604,11 +643,17 @@ again:
> > > }
> > > }
> > >
> > > -static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv, int size,
> > > - int fb_cpp)
> > > +static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
> > > {
> > > + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > > + struct drm_framebuffer *fb = crtc->base.primary->state->fb;
> > > struct drm_mm_node *uninitialized_var(compressed_llb);
> > > - int ret;
> > > + int size, fb_cpp, ret;
> > > +
> > > + WARN_ON(dev_priv->fbc.compressed_fb.allocated);
> > > +
> > > + size = intel_fbc_calculate_cfb_size(crtc, fb);
> > > + fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > >
> > > ret = find_compression_threshold(dev_priv, &dev_priv->fbc.compressed_fb,
> > > size, fb_cpp);
> > > @@ -685,64 +730,6 @@ void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
> > > mutex_unlock(&dev_priv->fbc.lock);
> > > }
> > >
> > > -/*
> > > - * 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(struct intel_crtc *crtc,
> > > - int *width, int *height)
> > > -{
> > > - struct intel_plane_state *plane_state =
> > > - to_intel_plane_state(crtc->base.primary->state);
> > > - int w, h;
> > > -
> > > - if (intel_rotation_90_or_270(plane_state->base.rotation)) {
> > > - w = drm_rect_height(&plane_state->src) >> 16;
> > > - h = drm_rect_width(&plane_state->src) >> 16;
> > > - } else {
> > > - w = drm_rect_width(&plane_state->src) >> 16;
> > > - h = drm_rect_height(&plane_state->src) >> 16;
> > > - }
> > > -
> > > - if (width)
> > > - *width = w;
> > > - if (height)
> > > - *height = h;
> > > -}
> > > -
> > > -static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc)
> > > -{
> > > - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > - int lines;
> > > -
> > > - intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > > - if (INTEL_INFO(dev_priv)->gen >= 7)
> > > - lines = min(lines, 2048);
> > > -
> > > - return lines * fb->pitches[0];
> > > -}
> > > -
> > > -static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
> > > -{
> > > - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > - int size, cpp;
> > > -
> > > - size = intel_fbc_calculate_cfb_size(crtc);
> > > - cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > > -
> > > - if (dev_priv->fbc.compressed_fb.allocated &&
> > > - size <= dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold)
> > > - return 0;
> > > -
> > > - /* Release any current block */
> > > - __intel_fbc_cleanup_cfb(dev_priv);
> > > -
> > > - return intel_fbc_alloc_cfb(dev_priv, size, cpp);
> > > -}
> > > -
> > > static bool stride_is_valid(struct drm_i915_private *dev_priv,
> > > unsigned int stride)
> > > {
> > > @@ -904,8 +891,19 @@ static void __intel_fbc_update(struct intel_crtc *crtc)
> > > goto out_disable;
> > > }
> > >
> > > - if (intel_fbc_setup_cfb(crtc)) {
> > > - set_no_fbc_reason(dev_priv, "not enough stolen memory");
> > > + /* 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
> > > + * if this happens, but if we exceed the current CFB size we'll have to
> > > + * disable FBC. Notice that it would be possible to disable FBC, wait
> > > + * 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 case we expect to be uncommon, so we
> > > + * just don't have this code for now. */
> > > + if (intel_fbc_calculate_cfb_size(crtc, fb) >
> > > + dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) {
> > > + set_no_fbc_reason(dev_priv, "CFB requirements changed");
> > > goto out_disable;
> > > }
> > >
> > > @@ -958,7 +956,6 @@ out_disable:
> > > DRM_DEBUG_KMS("unsupported config, deactivating FBC\n");
> > > __intel_fbc_deactivate(dev_priv);
> > > }
> > > - __intel_fbc_cleanup_cfb(dev_priv);
> > > }
> > >
> > > /*
> > > @@ -1102,6 +1099,11 @@ void intel_fbc_enable(struct intel_crtc *crtc)
> > > goto out;
> > > }
> > >
> > > + if (intel_fbc_alloc_cfb(crtc)) {
> > > + set_no_fbc_reason(dev_priv, "not enough stolen memory");
> > > + goto out;
> > > + }
> > > +
> > > DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe));
> > > dev_priv->fbc.no_fbc_reason = "FBC enabled but not active yet\n";
> > >
> > > @@ -1129,6 +1131,8 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
> > >
> > > DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe));
> > >
> > > + __intel_fbc_cleanup_cfb(dev_priv);
> > > +
> > > dev_priv->fbc.enabled = false;
> > > dev_priv->fbc.crtc = NULL;
> > > }
> > > --
> > > 2.6.1
> > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Ville Syrjälä
> Intel OTC
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 02/18] drm/i915: don't stop+start FBC at every flip
2015-10-21 7:12 ` Ville Syrjälä
@ 2015-10-21 7:40 ` Ville Syrjälä
0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2015-10-21 7:40 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Wed, Oct 21, 2015 at 10:12:50AM +0300, Ville Syrjälä wrote:
> On Wed, Oct 21, 2015 at 09:04:39AM +0200, Daniel Vetter wrote:
> > On Tue, Oct 20, 2015 at 11:49:48AM -0200, Paulo Zanoni wrote:
> > > The hardware already takes care of disabling and recompressing FBC
> > > when we do a page flip, so all we need to do is to update the fence
> > > registers and move on.
> > >
> > > One of the important things to notice is that on the pre-gen6
> > > platforms the fence is programmed on the FBC control register and the
> > > documentation says we can't update the control register while FBC is
> > > enabled. This would basically mean we'd have to to disable+enable FBC
> > > at every flip in order to make sure the hardware tracking still works,
> > > which doesn't seem to make too much sense. So I sent an email to the
> > > hardware team requesting some clarification. The information I got was
> > > this:
> > >
> > > "I don't think any hardware is latching on to 0x100100, 0x100104, or
> > > the old fence number in FBC_CTL. Instructions against changing on the
> > > fly would be to simplify testing and ensure you don't miss any
> > > invalidation that happened right at that time."
> > >
> > > So I guess we're fine for flips. But I can't really say I tested FBC
> > > on these ancient platforms - nor that I'll ever propose enabling FBC
> > > by default on them exactly because of problems like these.
> > >
> > > Testcase: igt/kms_frontbuffer_tracking/fbc*-fliptrack
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > Iirc on pre-g4x flips don't invalidate the fbc compression, and we do
> > actually have to disable fbc entirely.
>
> Nope. At least my gen2 was doing fine with hw flip nuke >1 year ago.
Double checked the spec, and it's contradictory.
In on place it says"
"2. Async Flips and/or panning of Display Plane A is not permitted.
3. Sync flips of Display Plane A are permitted, given that only the
source buffer address is changed (and note that it is UNDEFINED
to flip to the currently-displayed buffer). Other source display
buffer parameters must be kept in synch with the FBC control
parameters (which will require RLE-FBC to first be disabled)."
I have no idea what it thinks is the difference between panning and
sync flips on gen2.
In another place it says:
"All lines will be marked as modified whenever:
- uncompressed source Frame Buffer base address changes (this is only permitted to happen as a result of a
direct register write – flips of Display Plane A are not allowed when RLE-FBC is enabled)"
But IIRC CS flips worked just fine on my 855.
>
> > There's some funky language that if
> > you want to flip with fbc you have to track the new backbuffer.
> >
> > So I'm not entirely sure this is correct for the i8x case. Otoh we don't
> > ever enable it, so we could also just nuke the i8x fbc code. Either way it
> > doesn't matter to much.
> >
> > > ---
> > > drivers/gpu/drm/i915/i915_drv.h | 1 +
> > > drivers/gpu/drm/i915/i915_reg.h | 3 +
> > > drivers/gpu/drm/i915/intel_display.c | 1 -
> > > drivers/gpu/drm/i915/intel_drv.h | 2 +
> > > drivers/gpu/drm/i915/intel_fbc.c | 98 +++++++++++++++++++++++++++++++-
> > > drivers/gpu/drm/i915/intel_frontbuffer.c | 1 +
> > > 6 files changed, 103 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index c334525..f04f56f 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -930,6 +930,7 @@ struct i915_fbc {
> > > bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
> > > void (*enable_fbc)(struct intel_crtc *crtc);
> > > void (*disable_fbc)(struct drm_i915_private *dev_priv);
> > > + void (*flip_prepare)(struct drm_i915_private *dev_priv);
> > > };
> > >
> > > /**
> > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > > index 9ebf032..3620b59 100644
> > > --- a/drivers/gpu/drm/i915/i915_reg.h
> > > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > > @@ -2028,6 +2028,7 @@ enum skl_disp_power_wells {
> > > #define FBC_CTL_C3_IDLE (1<<13)
> > > #define FBC_CTL_STRIDE_SHIFT (5)
> > > #define FBC_CTL_FENCENO_SHIFT (0)
> > > +#define FBC_CTL_FENCENO_MASK 0xF
> > > #define FBC_COMMAND 0x0320c
> > > #define FBC_CMD_COMPRESS (1<<0)
> > > #define FBC_STATUS 0x03210
> > > @@ -2064,6 +2065,7 @@ enum skl_disp_power_wells {
> > > #define DPFC_CTL_LIMIT_1X (0<<6)
> > > #define DPFC_CTL_LIMIT_2X (1<<6)
> > > #define DPFC_CTL_LIMIT_4X (2<<6)
> > > +#define DPFC_CTL_FENCE_MASK 0xF
> > > #define DPFC_RECOMP_CTL 0x320c
> > > #define DPFC_RECOMP_STALL_EN (1<<27)
> > > #define DPFC_RECOMP_STALL_WM_SHIFT (16)
> > > @@ -2086,6 +2088,7 @@ enum skl_disp_power_wells {
> > > #define FBC_CTL_FALSE_COLOR (1<<10)
> > > /* The bit 28-8 is reserved */
> > > #define DPFC_RESERVED (0x1FFFFF00)
> > > +#define ILK_DPFC_FENCE_MASK 0xF
> > > #define ILK_DPFC_RECOMP_CTL 0x4320c
> > > #define ILK_DPFC_STATUS 0x43210
> > > #define ILK_DPFC_FENCE_YOFF 0x43218
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > index 1fc1d24..e83a428 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -11470,7 +11470,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> > > to_intel_plane(primary)->frontbuffer_bit);
> > > mutex_unlock(&dev->struct_mutex);
> > >
> > > - intel_fbc_disable_crtc(intel_crtc);
> > > intel_frontbuffer_flip_prepare(dev,
> > > to_intel_plane(primary)->frontbuffer_bit);
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index dc55e4c..1e08c8a 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -1287,6 +1287,8 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
> > > enum fb_op_origin origin);
> > > void intel_fbc_flush(struct drm_i915_private *dev_priv,
> > > unsigned int frontbuffer_bits, enum fb_op_origin origin);
> > > +void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
> > > + unsigned int frontbuffer_bits);
> > > void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv);
> > >
> > > /* intel_hdmi.c */
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> > > index d9d7e54..9477379 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -82,6 +82,22 @@ static void i8xx_fbc_disable(struct drm_i915_private *dev_priv)
> > > DRM_DEBUG_KMS("disabled FBC\n");
> > > }
> > >
> > > +static void i8xx_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > > +{
> > > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > > + uint32_t val;
> > > +
> > > + /* Although the documentation suggests we can't change DPFC_CONTROL
> > > + * while compression is enabled, the hardware guys said that updating
> > > + * the fence register bits during a flip is fine. */
> > > + val = I915_READ(FBC_CONTROL);
> > > + val &= ~FBC_CTL_FENCENO_MASK;
> > > + val |= obj->fence_reg;
> > > + I915_WRITE(FBC_CONTROL, val);
> > > +}
> > > +
> > > static void i8xx_fbc_enable(struct intel_crtc *crtc)
> > > {
> > > struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > > @@ -161,6 +177,22 @@ static void g4x_fbc_enable(struct intel_crtc *crtc)
> > > DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
> > > }
> > >
> > > +static void g4x_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > > +{
> > > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > > + uint32_t val;
> > > +
> > > + /* Although the documentation suggests we can't change DPFC_CONTROL
> > > + * while compression is enabled, the hardware guys said that updating
> > > + * the fence register bits during a flip is fine. */
> > > + val = I915_READ(DPFC_CONTROL);
> > > + val &= ~DPFC_CTL_FENCE_MASK;
> > > + val |= obj->fence_reg;
> > > + I915_WRITE(DPFC_CONTROL, val);
> > > +}
> > > +
> > > static void g4x_fbc_disable(struct drm_i915_private *dev_priv)
> > > {
> > > u32 dpfc_ctl;
> > > @@ -236,6 +268,31 @@ static void ilk_fbc_enable(struct intel_crtc *crtc)
> > > DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(crtc->plane));
> > > }
> > >
> > > +static void ilk_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > > +{
> > > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > > + uint32_t val;
> > > +
> > > + /* Although the documentation suggests we can't change DPFC_CONTROL
> > > + * while compression is enabled, the hardware guys said that updating
> > > + * the fence register bits during a flip is fine. */
> > > + val = I915_READ(ILK_DPFC_CONTROL);
> > > + val &= ~ILK_DPFC_FENCE_MASK;
> > > + val |= obj->fence_reg;
> > > + I915_WRITE(ILK_DPFC_CONTROL, val);
> > > +}
> > > +
> > > +static void snb_fbc_flip_prepare(struct drm_i915_private *dev_priv)
> > > +{
> > > + struct intel_crtc *crtc = dev_priv->fbc.crtc;
> > > + struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > + struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> > > +
> > > + I915_WRITE(SNB_DPFC_CTL_SA, SNB_CPU_FENCE_ENABLE | obj->fence_reg);
> > > +}
> > > +
> > > static void ilk_fbc_disable(struct drm_i915_private *dev_priv)
> > > {
> > > u32 dpfc_ctl;
> > > @@ -1020,14 +1077,44 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
> > >
> > > if (origin == ORIGIN_GTT)
> > > return;
> > > + if (origin == ORIGIN_FLIP && dev_priv->fbc.enabled)
> > > + return;
> > >
> > > mutex_lock(&dev_priv->fbc.lock);
> > >
> > > dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
> > >
> > > if (!dev_priv->fbc.busy_bits) {
> > > - __intel_fbc_disable(dev_priv);
> > > - __intel_fbc_update(dev_priv);
> > > + if (origin == ORIGIN_FLIP) {
> > > + __intel_fbc_update(dev_priv);
> > > + } else {
> > > + __intel_fbc_disable(dev_priv);
> > > + __intel_fbc_update(dev_priv);
> > > + }
> > > + }
> > > +
> > > + mutex_unlock(&dev_priv->fbc.lock);
> > > +}
> > > +
> > > +void intel_fbc_flip_prepare(struct drm_i915_private *dev_priv,
> > > + unsigned int frontbuffer_bits)
> > > +{
> > > + unsigned int fbc_bits;
> > > +
> > > + if (!fbc_supported(dev_priv))
> > > + return;
> > > +
> > > + mutex_lock(&dev_priv->fbc.lock);
> > > +
> > > + if (dev_priv->fbc.enabled) {
> > > + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe);
> > > + if (fbc_bits & frontbuffer_bits)
> > > + dev_priv->fbc.flip_prepare(dev_priv);
> > > + } else if (dev_priv->fbc.fbc_work) {
> > > + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(
> > > + dev_priv->fbc.fbc_work->crtc->pipe);
> > > + if (fbc_bits & frontbuffer_bits)
> > > + __intel_fbc_disable(dev_priv);
> > > }
> > >
> > > mutex_unlock(&dev_priv->fbc.lock);
> > > @@ -1063,18 +1150,25 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
> > > dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
> > > dev_priv->fbc.enable_fbc = gen7_fbc_enable;
> > > dev_priv->fbc.disable_fbc = ilk_fbc_disable;
> > > + dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
> > > } else if (INTEL_INFO(dev_priv)->gen >= 5) {
> > > dev_priv->fbc.fbc_enabled = ilk_fbc_enabled;
> > > dev_priv->fbc.enable_fbc = ilk_fbc_enable;
> > > dev_priv->fbc.disable_fbc = ilk_fbc_disable;
> > > + if (INTEL_INFO(dev_priv)->gen == 5)
> > > + dev_priv->fbc.flip_prepare = ilk_fbc_flip_prepare;
> > > + else
> > > + dev_priv->fbc.flip_prepare = snb_fbc_flip_prepare;
> > > } else if (IS_GM45(dev_priv)) {
> > > dev_priv->fbc.fbc_enabled = g4x_fbc_enabled;
> > > dev_priv->fbc.enable_fbc = g4x_fbc_enable;
> > > dev_priv->fbc.disable_fbc = g4x_fbc_disable;
> > > + dev_priv->fbc.flip_prepare = g4x_fbc_flip_prepare;
> > > } else {
> > > dev_priv->fbc.fbc_enabled = i8xx_fbc_enabled;
> > > dev_priv->fbc.enable_fbc = i8xx_fbc_enable;
> > > dev_priv->fbc.disable_fbc = i8xx_fbc_disable;
> > > + dev_priv->fbc.flip_prepare = i8xx_fbc_flip_prepare;
> > >
> > > /* This value was pulled out of someone's hat */
> > > I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT);
> > > diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c
> > > index ac85357..31a1ad3 100644
> > > --- a/drivers/gpu/drm/i915/intel_frontbuffer.c
> > > +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c
> > > @@ -192,6 +192,7 @@ void intel_frontbuffer_flip_prepare(struct drm_device *dev,
> > > mutex_unlock(&dev_priv->fb_tracking.lock);
> > >
> > > intel_psr_single_frame_update(dev, frontbuffer_bits);
> > > + intel_fbc_flip_prepare(dev_priv, frontbuffer_bits);
> >
> > I haven't read ahead, but both psr single frame update and this here
> > should be converted. Since with this here there's the small (but very
> > real) chance that rendering the buffer for this flip will take longer than
> > the next vblank, and at least for the psr case we'd then fail to upload
> > the changes. For fbc it's less of a problem, since if you page flip then
> > userspace shouldn't race frontbuffer rendering.
> >
> > So I think this is ok (but the PSR case should be fixed by moving the
> > register write itself into the atomic update, which means we need to have
> > a boolean to decided whether to do that in the intel_crtc_state).
> > -Daniel
> >
> >
> > > }
> > >
> > > /**
> > > --
> > > 2.6.1
> > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Ville Syrjälä
> Intel OTC
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology
2015-10-20 13:49 ` [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology Paulo Zanoni
@ 2015-10-21 12:34 ` Chris Wilson
2015-10-21 17:45 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2015-10-21 12:34 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:56AM -0200, Paulo Zanoni wrote:
> The long term goal is to have enable/disable as the higher level
> functions and activate/deactivate as the lower level functions, just
> like we do for PSR and for the CRTC. Let's start this by renaming the
> functions that touch the hardware state and their wrappers.
So enable() calls activate() and disable() calls deactivate(). So what's the
benefit? What mistakes and confusion are made right now and is the
mismatch between low/high worth it? This is your chance to justify the
churn and sell us on the new naming scheme, and explain your long term
vision in making the driver consistent everywhere.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments
2015-10-20 13:49 ` [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments Paulo Zanoni
@ 2015-10-21 12:37 ` Chris Wilson
2015-10-21 17:32 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2015-10-21 12:37 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:53AM -0200, Paulo Zanoni wrote:
> Don't try to list in comments the cases where we should enable or
> disable FBC: it varies a lot with the hardware generations and the
> code should be the documentation. Also notice that there's already a
> huge gap between the comments and what's in the code.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_fbc.c | 26 ++------------------------
> 1 file changed, 2 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index e856304..5fa4ce4 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -853,20 +853,8 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
> * __intel_fbc_update - enable/disable FBC as needed, unlocked
> * @dev_priv: i915 device instance
> *
> - * Set up the framebuffer compression hardware at mode set time. We
> - * enable it if possible:
> - * - plane A only (on pre-965)
> - * - no pixel mulitply/line duplication
> - * - no alpha buffer discard
> - * - no dual wide
> - * - framebuffer <= max_hdisplay in width, max_vdisplay in height
> - *
> - * We can't assume that any compression will take place (worst case),
> - * so the compressed buffer has to be the same size as the uncompressed
> - * one. It also must reside (along with the line length buffer) in
> - * stolen memory.
> - *
> - * We need to enable/disable FBC on a global basis.
> + * This function completely reevaluates the status of FBC, then enables,
> + * disables or maintains it on the same state.
By the end, this comment is not strictly true ,right? Since you move
some of the status checking into modeset enable paths. Could you refine
the function comment?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 11/18] drm/i915: refactor FBC deactivation at init
2015-10-20 13:49 ` [PATCH 11/18] drm/i915: refactor FBC deactivation at init Paulo Zanoni
@ 2015-10-21 12:59 ` Chris Wilson
0 siblings, 0 replies; 57+ messages in thread
From: Chris Wilson @ 2015-10-21 12:59 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:57AM -0200, Paulo Zanoni wrote:
> Make sure we deactivate FBC at intel_fbc_init(), so we can remove the
> call from intel_display.c.
Though you should keep the comment as to why we want to sanitize
incoming register state as a reminder. Does this function document it
needs rpm-active (or take a rpm ref itself)?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 13/18] drm/i915: remove too-frequent FBC debug message
2015-10-20 13:49 ` [PATCH 13/18] drm/i915: remove too-frequent FBC debug message Paulo Zanoni
@ 2015-10-21 13:01 ` Chris Wilson
2015-10-21 18:19 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2015-10-21 13:01 UTC (permalink / raw)
To: Paulo Zanoni; +Cc: intel-gfx
On Tue, Oct 20, 2015 at 11:49:59AM -0200, Paulo Zanoni wrote:
> If we run igt/kms_frontbuffer_tracking, this message will appear
> thousands of times, eating a significant part of our dmesg buffer.
> It's part of the expected FBC behavior, so let's just silence it.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Looks fine. Out of curiosity what metrics do we have for FBC activity? I
presume we have tracepoints for activate/deactivate. and perhaps a sw
timer, and a hw debug register?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush
2015-10-20 15:59 ` Chris Wilson
@ 2015-10-21 17:08 ` Zanoni, Paulo R
2015-10-21 17:31 ` chris
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 17:08 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Ter, 2015-10-20 às 16:59 +0100, Chris Wilson escreveu:
> On Tue, Oct 20, 2015 at 11:49:49AM -0200, Paulo Zanoni wrote:
> > There's no need to stop and restart FBC: a nuke should be fine.
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_fbc.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index 9477379..b9cfd16 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -1088,8 +1088,10 @@ void intel_fbc_flush(struct drm_i915_private
> > *dev_priv,
> > if (origin == ORIGIN_FLIP) {
> > __intel_fbc_update(dev_priv);
> > } else {
> > - __intel_fbc_disable(dev_priv);
> > - __intel_fbc_update(dev_priv);
> > + if (dev_priv->fbc.enabled)
> > + intel_fbc_nuke(dev_priv);
>
> Ok, what does nuke actually do? From the name, I would expect FBC to
> be
> left in an unusable state.
As far as I understand, it triggers a full recompression of the CFB. It
should be equivalent to disable+reenable.
>
> > + else
> > + __intel_fbc_update(dev_priv);
> > }
> > }
>
> This becomes
>
> if (enabled && origin != ORIGIN_FLIP)
> intel_fbc_nuke();
> else
> __intel_fbc_update();
Now I see this code could definitely have been made simpler... Fixing
this here would require me to redo many of the next patches. I hope you
accept patch 19/18 as a possible "fix".
>
> It seems a little odd that anything is done if disabled, so care to
> elaborate that reason
When we're drawing on the frontbuffer we may get an invalidate() call
first, which will trigger an FBC deactivation. Then later we'll get a
flush() and will have to reenable. Sometimes we may just get the
flush() without the previous invalidate(), and for this case a nuke is
the easiest thing to do. That's all just the normal frontbuffer
tracking mechanism.
> , and I presume there is an equally good comment
> before the context that explains why FLIP is special?
It's just that we ignore flushes() for the FLIP case if FBC is active
due to the hardware tracking, which automatically does a nuke. There's
a check for this earlier on this function, which you can't see on this
diff context but you can see on patch 02/18. So if origin is FLIP, and
FBC is active, we return early.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-20 15:52 ` Chris Wilson
@ 2015-10-21 17:16 ` Zanoni, Paulo R
2015-10-21 17:28 ` chris
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 17:16 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Ter, 2015-10-20 às 16:52 +0100, Chris Wilson escreveu:
> On Tue, Oct 20, 2015 at 11:49:50AM -0200, Paulo Zanoni wrote:
> > We're going to kill intel_fbc_find_crtc(), that's why a big part of
> > the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
> > 1 file changed, 16 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index b9cfd16..1162787 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct
> > drm_i915_private *dev_priv,
> > DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> > }
> >
> > +static bool crtc_is_valid(struct intel_crtc *crtc)
> > +{
> > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > >dev_private;
> > + enum pipe pipe = crtc->pipe;
> > +
> > + if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >=
> > 8) &&
> > + pipe != PIPE_A)
>
> Keeping
>
> if (pipe_a_only(dev_priv) && pipe != PIPE_A)
> return false;
>
> would have been nicer.
I can do that on v2.
>
> > + return false;
> > +
> > + return intel_crtc_active(&crtc->base) &&
> > + to_intel_plane_state(crtc->base.primary->state)-
> > >visible &&
> > + crtc->base.primary->fb != NULL;
>
> And then you can split this line up for a little more clarity. If you
> are taking the time to refactor into a separate function for
> readability, you may as well apply a little polish as well.
I really don't get what you're suggesting here. Can you please clarify?
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work
2015-10-20 16:03 ` Chris Wilson
@ 2015-10-21 17:27 ` Zanoni, Paulo R
2015-10-21 18:15 ` chris
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 17:27 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Ter, 2015-10-20 às 17:03 +0100, Chris Wilson escreveu:
> On Tue, Oct 20, 2015 at 11:49:51AM -0200, Paulo Zanoni wrote:
> > This thing where we need to get the crtc either from the work
> > structure or the fbc structure itself is confusing and unnecessary.
> > Set fbc.crtc right when scheduling the enable work so we can always
> > use it.
>
> Pardon? It was confusing to have the crtc passed along with the work
> item as opposed to digging it out from an indirect link on the
> dev_priv.
> iirc work->crtc was part of the serialisation of the work item.
>
> What I think you meant was that you were passing around the wrong
> struct, e.g.
> intel_fbc_enable() just wants the crtc, in intel_fbc_flip_prepare()
> you
> check for the work struct, and then you should just use the work
> struct.
The problem is not what gets passed and how to retrieve it. The problem
is that when we're in the other parts of the code we always have to
keep in mind that if FBC is already enabled we have to get the CRTC
from place A, if FBC is scheduled we have to get the CRTC from place B,
and if it's disabled there's no CRTC. Having a single place to retrieve
the CRTC from allows us to treat the "is enabled" and "is scheduled"
cases as the same case, reducing the mistake surface. I guess I should
add this to the commit message.
Anyway, it's worth mentioning that later on this series when we
introduce enable() and disable() we already set dev_priv->fbc.crtc at
enable(), so all the activate/deactivate/update code can just look at
that regardless of the current state. So this patch is just an
intermediate step to keep everything simple and working until the
enable/disable patch.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-21 17:16 ` Zanoni, Paulo R
@ 2015-10-21 17:28 ` chris
0 siblings, 0 replies; 57+ messages in thread
From: chris @ 2015-10-21 17:28 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 05:16:04PM +0000, Zanoni, Paulo R wrote:
> Em Ter, 2015-10-20 às 16:52 +0100, Chris Wilson escreveu:
> > On Tue, Oct 20, 2015 at 11:49:50AM -0200, Paulo Zanoni wrote:
> > > We're going to kill intel_fbc_find_crtc(), that's why a big part of
> > > the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
> > >
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > ---
> > > drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
> > > 1 file changed, 16 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > index b9cfd16..1162787 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct
> > > drm_i915_private *dev_priv,
> > > DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> > > }
> > >
> > > +static bool crtc_is_valid(struct intel_crtc *crtc)
> > > +{
> > > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > > >dev_private;
> > > + enum pipe pipe = crtc->pipe;
> > > +
> > > + if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >=
> > > 8) &&
> > > + pipe != PIPE_A)
> >
> > Keeping
> >
> > if (pipe_a_only(dev_priv) && pipe != PIPE_A)
> > return false;
> >
> > would have been nicer.
>
> I can do that on v2.
>
> >
> > > + return false;
> > > +
> > > + return intel_crtc_active(&crtc->base) &&
> > > + to_intel_plane_state(crtc->base.primary->state)-
> > > >visible &&
> > > + crtc->base.primary->fb != NULL;
> >
> > And then you can split this line up for a little more clarity. If you
> > are taking the time to refactor into a separate function for
> > readability, you may as well apply a little polish as well.
>
> I really don't get what you're suggesting here. Can you please clarify?
I think multiline conditionals do not add to readibilty. Since you have
already taken the effort to split the predicate out into its own
function,
if (!intel_crtc_active(&crtc->base))
return false;
if (!to_intel_plane_state(crtc->base.primary->state)->visible)
return false;
/* both of these are used repeatedly in intel_display.c, probably worth
* refactoring into intel_plane_active(crtc, crtc->base.primary); later
* on
*/
/* given the two above, this is redundant. more evidence that we should
* not be writing this code ourselves but calling an intel_display
* helper
*/
if (crtc->base.primary->fb)
return false;
return true;
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush
2015-10-21 17:08 ` Zanoni, Paulo R
@ 2015-10-21 17:31 ` chris
2015-10-21 17:51 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: chris @ 2015-10-21 17:31 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 05:08:42PM +0000, Zanoni, Paulo R wrote:
> Em Ter, 2015-10-20 às 16:59 +0100, Chris Wilson escreveu:
> > On Tue, Oct 20, 2015 at 11:49:49AM -0200, Paulo Zanoni wrote:
> > > There's no need to stop and restart FBC: a nuke should be fine.
> > >
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > ---
> > > drivers/gpu/drm/i915/intel_fbc.c | 6 ++++--
> > > 1 file changed, 4 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > index 9477379..b9cfd16 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -1088,8 +1088,10 @@ void intel_fbc_flush(struct drm_i915_private
> > > *dev_priv,
> > > if (origin == ORIGIN_FLIP) {
> > > __intel_fbc_update(dev_priv);
> > > } else {
> > > - __intel_fbc_disable(dev_priv);
> > > - __intel_fbc_update(dev_priv);
> > > + if (dev_priv->fbc.enabled)
> > > + intel_fbc_nuke(dev_priv);
> >
> > Ok, what does nuke actually do? From the name, I would expect FBC to
> > be
> > left in an unusable state.
>
> As far as I understand, it triggers a full recompression of the CFB. It
> should be equivalent to disable+reenable.
Maybe intel_fbc_recompress(), that seems a little more obvious than nuke?
> >
> > > + else
> > > + __intel_fbc_update(dev_priv);
> > > }
> > > }
> >
> > This becomes
> >
> > if (enabled && origin != ORIGIN_FLIP)
> > intel_fbc_nuke();
> > else
> > __intel_fbc_update();
>
> Now I see this code could definitely have been made simpler... Fixing
> this here would require me to redo many of the next patches. I hope you
> accept patch 19/18 as a possible "fix".
Sure.
> >
> > It seems a little odd that anything is done if disabled, so care to
> > elaborate that reason
>
> When we're drawing on the frontbuffer we may get an invalidate() call
> first, which will trigger an FBC deactivation. Then later we'll get a
> flush() and will have to reenable. Sometimes we may just get the
> flush() without the previous invalidate(), and for this case a nuke is
> the easiest thing to do. That's all just the normal frontbuffer
> tracking mechanism.
>
>
> > , and I presume there is an equally good comment
> > before the context that explains why FLIP is special?
>
> It's just that we ignore flushes() for the FLIP case if FBC is active
> due to the hardware tracking, which automatically does a nuke. There's
> a check for this earlier on this function, which you can't see on this
> diff context but you can see on patch 02/18. So if origin is FLIP, and
> FBC is active, we return early.
I like this comment. Care to add it to the function?
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments
2015-10-21 12:37 ` Chris Wilson
@ 2015-10-21 17:32 ` Zanoni, Paulo R
2015-10-21 17:38 ` chris
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 17:32 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Qua, 2015-10-21 às 13:37 +0100, Chris Wilson escreveu:
> On Tue, Oct 20, 2015 at 11:49:53AM -0200, Paulo Zanoni wrote:
> > Don't try to list in comments the cases where we should enable or
> > disable FBC: it varies a lot with the hardware generations and the
> > code should be the documentation. Also notice that there's already
> > a
> > huge gap between the comments and what's in the code.
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_fbc.c | 26 ++------------------------
> > 1 file changed, 2 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index e856304..5fa4ce4 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -853,20 +853,8 @@ static bool
> > intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
> > * __intel_fbc_update - enable/disable FBC as needed, unlocked
> > * @dev_priv: i915 device instance
> > *
> > - * Set up the framebuffer compression hardware at mode set
> > time. We
> > - * enable it if possible:
> > - * - plane A only (on pre-965)
> > - * - no pixel mulitply/line duplication
> > - * - no alpha buffer discard
> > - * - no dual wide
> > - * - framebuffer <= max_hdisplay in width, max_vdisplay in
> > height
> > - *
> > - * We can't assume that any compression will take place (worst
> > case),
> > - * so the compressed buffer has to be the same size as the
> > uncompressed
> > - * one. It also must reside (along with the line length buffer)
> > in
> > - * stolen memory.
> > - *
> > - * We need to enable/disable FBC on a global basis.
> > + * This function completely reevaluates the status of FBC, then
> > enables,
> > + * disables or maintains it on the same state.
>
> By the end, this comment is not strictly true ,right? Since you move
> some of the status checking into modeset enable paths. Could you
> refine
> the function comment?
I only move the status checking into modeset enable paths on patch 12.
The comment above is modified on patch 12 to reflect
activate/deactivate instead of enable/disable.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments
2015-10-21 17:32 ` Zanoni, Paulo R
@ 2015-10-21 17:38 ` chris
2015-10-22 20:15 ` Zanoni, Paulo R
0 siblings, 1 reply; 57+ messages in thread
From: chris @ 2015-10-21 17:38 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 05:32:16PM +0000, Zanoni, Paulo R wrote:
> Em Qua, 2015-10-21 às 13:37 +0100, Chris Wilson escreveu:
> > On Tue, Oct 20, 2015 at 11:49:53AM -0200, Paulo Zanoni wrote:
> > > Don't try to list in comments the cases where we should enable or
> > > disable FBC: it varies a lot with the hardware generations and the
> > > code should be the documentation. Also notice that there's already
> > > a
> > > huge gap between the comments and what's in the code.
> > >
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > ---
> > > drivers/gpu/drm/i915/intel_fbc.c | 26 ++------------------------
> > > 1 file changed, 2 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > index e856304..5fa4ce4 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -853,20 +853,8 @@ static bool
> > > intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
> > > * __intel_fbc_update - enable/disable FBC as needed, unlocked
> > > * @dev_priv: i915 device instance
> > > *
> > > - * Set up the framebuffer compression hardware at mode set
> > > time. We
> > > - * enable it if possible:
> > > - * - plane A only (on pre-965)
> > > - * - no pixel mulitply/line duplication
> > > - * - no alpha buffer discard
> > > - * - no dual wide
> > > - * - framebuffer <= max_hdisplay in width, max_vdisplay in
> > > height
> > > - *
> > > - * We can't assume that any compression will take place (worst
> > > case),
> > > - * so the compressed buffer has to be the same size as the
> > > uncompressed
> > > - * one. It also must reside (along with the line length buffer)
> > > in
> > > - * stolen memory.
> > > - *
> > > - * We need to enable/disable FBC on a global basis.
> > > + * This function completely reevaluates the status of FBC, then
> > > enables,
> > > + * disables or maintains it on the same state.
> >
> > By the end, this comment is not strictly true ,right? Since you move
> > some of the status checking into modeset enable paths. Could you
> > refine
> > the function comment?
>
> I only move the status checking into modeset enable paths on patch 12.
> The comment above is modified on patch 12 to reflect
> activate/deactivate instead of enable/disable.
Honestly, I would just squash this patch, or apply it after the moving
the code to correctly reflect the split in work between update/enable.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology
2015-10-21 12:34 ` Chris Wilson
@ 2015-10-21 17:45 ` Zanoni, Paulo R
2015-10-21 17:55 ` chris
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 17:45 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Qua, 2015-10-21 às 13:34 +0100, Chris Wilson escreveu:
> On Tue, Oct 20, 2015 at 11:49:56AM -0200, Paulo Zanoni wrote:
> > The long term goal is to have enable/disable as the higher level
> > functions and activate/deactivate as the lower level functions,
> > just
> > like we do for PSR and for the CRTC. Let's start this by renaming
> > the
> > functions that touch the hardware state and their wrappers.
>
> So enable() calls activate() and disable() calls deactivate(). So
> what's the
> benefit?
I explained each individual change on its own patch, but I guess I
should have put a higher level description here. Will fix this in v2.
With just this patch there's really no benefit. The main benefit is patch 12, when we actually have separate enable/disable and activate/deactivate functions.
One of the main points is that enable/disable are called once per modeset, while update/activate/deactivate can be called tons of times during normal operation, so moving code to enable() when possible makes sure it is not ran over and over again unnecessarily.
> What mistakes and confusion are made right now
The confusion right now is that we don't have the real higher level
enable/disable that we get on patch 12.
> and is the
> mismatch between low/high worth it? This is your chance to justify
> the
> churn and sell us on the new naming scheme, and explain your long
> term
> vision in making the driver consistent everywhere.
Maybe I should just redirect users to patch 12 on the commit, since
this patch does not add any value by itself. I could have squashed this
and 12, but I don't like huge patches: they're not easy to review and
are a pain to rebase.
Anyway, v2 will hopefully have a better commit message.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush
2015-10-21 17:31 ` chris
@ 2015-10-21 17:51 ` Zanoni, Paulo R
0 siblings, 0 replies; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 17:51 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Qua, 2015-10-21 às 18:31 +0100, chris@chris-wilson.co.uk escreveu:
> On Wed, Oct 21, 2015 at 05:08:42PM +0000, Zanoni, Paulo R wrote:
> > Em Ter, 2015-10-20 às 16:59 +0100, Chris Wilson escreveu:
> > > On Tue, Oct 20, 2015 at 11:49:49AM -0200, Paulo Zanoni wrote:
> > > > There's no need to stop and restart FBC: a nuke should be fine.
> > > >
> > > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > > ---
> > > > drivers/gpu/drm/i915/intel_fbc.c | 6 ++++--
> > > > 1 file changed, 4 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > > index 9477379..b9cfd16 100644
> > > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > > @@ -1088,8 +1088,10 @@ void intel_fbc_flush(struct
> > > > drm_i915_private
> > > > *dev_priv,
> > > > if (origin == ORIGIN_FLIP) {
> > > > __intel_fbc_update(dev_priv);
> > > > } else {
> > > > - __intel_fbc_disable(dev_priv);
> > > > - __intel_fbc_update(dev_priv);
> > > > + if (dev_priv->fbc.enabled)
> > > > + intel_fbc_nuke(dev_priv);
> > >
> > > Ok, what does nuke actually do? From the name, I would expect FBC
> > > to
> > > be
> > > left in an unusable state.
> >
> > As far as I understand, it triggers a full recompression of the
> > CFB. It
> > should be equivalent to disable+reenable.
>
> Maybe intel_fbc_recompress(), that seems a little more obvious than
> nuke?
Sure. I guess I just got used to seeing 'nuke' on the specs and forgot
that people without the specs would not know what it means.
> > >
> > > > + else
> > > > + __intel_fbc_update(dev_priv);
> > > > }
> > > > }
> > >
> > > This becomes
> > >
> > > if (enabled && origin != ORIGIN_FLIP)
> > > intel_fbc_nuke();
> > > else
> > > __intel_fbc_update();
> >
> > Now I see this code could definitely have been made simpler...
> > Fixing
> > this here would require me to redo many of the next patches. I hope
> > you
> > accept patch 19/18 as a possible "fix".
>
> Sure.
>
> > >
> > > It seems a little odd that anything is done if disabled, so care
> > > to
> > > elaborate that reason
> >
> > When we're drawing on the frontbuffer we may get an invalidate()
> > call
> > first, which will trigger an FBC deactivation. Then later we'll get
> > a
> > flush() and will have to reenable. Sometimes we may just get the
> > flush() without the previous invalidate(), and for this case a nuke
> > is
> > the easiest thing to do. That's all just the normal frontbuffer
> > tracking mechanism.
> >
> >
> > > , and I presume there is an equally good comment
> > > before the context that explains why FLIP is special?
> >
> > It's just that we ignore flushes() for the FLIP case if FBC is
> > active
> > due to the hardware tracking, which automatically does a nuke.
> > There's
> > a check for this earlier on this function, which you can't see on
> > this
> > diff context but you can see on patch 02/18. So if origin is FLIP,
> > and
> > FBC is active, we return early.
>
> I like this comment. Care to add it to the function?
Will do.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology
2015-10-21 17:45 ` Zanoni, Paulo R
@ 2015-10-21 17:55 ` chris
0 siblings, 0 replies; 57+ messages in thread
From: chris @ 2015-10-21 17:55 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 05:45:33PM +0000, Zanoni, Paulo R wrote:
> Em Qua, 2015-10-21 às 13:34 +0100, Chris Wilson escreveu:
> > On Tue, Oct 20, 2015 at 11:49:56AM -0200, Paulo Zanoni wrote:
> > > The long term goal is to have enable/disable as the higher level
> > > functions and activate/deactivate as the lower level functions,
> > > just
> > > like we do for PSR and for the CRTC. Let's start this by renaming
> > > the
> > > functions that touch the hardware state and their wrappers.
> >
> > So enable() calls activate() and disable() calls deactivate(). So
> > what's the
> > benefit?
>
> I explained each individual change on its own patch, but I guess I
> should have put a higher level description here. Will fix this in v2.
>
> With just this patch there's really no benefit. The main benefit is patch 12, when we actually have separate enable/disable and activate/deactivate functions.
>
> One of the main points is that enable/disable are called once per modeset, while update/activate/deactivate can be called tons of times during normal operation, so moving code to enable() when possible makes sure it is not ran over and over again unnecessarily.
>
>
> > What mistakes and confusion are made right now
>
> The confusion right now is that we don't have the real higher level
> enable/disable that we get on patch 12.
>
> > and is the
> > mismatch between low/high worth it? This is your chance to justify
> > the
> > churn and sell us on the new naming scheme, and explain your long
> > term
> > vision in making the driver consistent everywhere.
>
> Maybe I should just redirect users to patch 12 on the commit, since
> this patch does not add any value by itself. I could have squashed this
> and 12, but I don't like huge patches: they're not easy to review and
> are a pain to rebase.
>
> Anyway, v2 will hopefully have a better commit message.
Yes, just explain how you intend to separate the levels should be enough
to justify the change, and the overview in how they are intended to be
used invaluable.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work
2015-10-21 17:27 ` Zanoni, Paulo R
@ 2015-10-21 18:15 ` chris
0 siblings, 0 replies; 57+ messages in thread
From: chris @ 2015-10-21 18:15 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 05:27:32PM +0000, Zanoni, Paulo R wrote:
> Em Ter, 2015-10-20 às 17:03 +0100, Chris Wilson escreveu:
> > On Tue, Oct 20, 2015 at 11:49:51AM -0200, Paulo Zanoni wrote:
> > > This thing where we need to get the crtc either from the work
> > > structure or the fbc structure itself is confusing and unnecessary.
> > > Set fbc.crtc right when scheduling the enable work so we can always
> > > use it.
> >
> > Pardon? It was confusing to have the crtc passed along with the work
> > item as opposed to digging it out from an indirect link on the
> > dev_priv.
> > iirc work->crtc was part of the serialisation of the work item.
> >
> > What I think you meant was that you were passing around the wrong
> > struct, e.g.
> > intel_fbc_enable() just wants the crtc, in intel_fbc_flip_prepare()
> > you
> > check for the work struct, and then you should just use the work
> > struct.
>
> The problem is not what gets passed and how to retrieve it. The problem
> is that when we're in the other parts of the code we always have to
> keep in mind that if FBC is already enabled we have to get the CRTC
> from place A, if FBC is scheduled we have to get the CRTC from place B,
> and if it's disabled there's no CRTC. Having a single place to retrieve
> the CRTC from allows us to treat the "is enabled" and "is scheduled"
> cases as the same case, reducing the mistake surface. I guess I should
> add this to the commit message.
Sure that's also my argument why I don't like this particular patch as
is. :) The functions here had just one place to retreive everything they
needed, and now they need two.
I guess the way to make us both happy is to embed the work_struct inside
the fbc struct - and that way you can eliminate the divergence.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 13/18] drm/i915: remove too-frequent FBC debug message
2015-10-21 13:01 ` Chris Wilson
@ 2015-10-21 18:19 ` Zanoni, Paulo R
2015-10-22 19:52 ` chris
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 18:19 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Qua, 2015-10-21 às 14:01 +0100, Chris Wilson escreveu:
> On Tue, Oct 20, 2015 at 11:49:59AM -0200, Paulo Zanoni wrote:
> > If we run igt/kms_frontbuffer_tracking, this message will appear
> > thousands of times, eating a significant part of our dmesg buffer.
> > It's part of the expected FBC behavior, so let's just silence it.
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Looks fine. Out of curiosity what metrics do we have for FBC
> activity? I
> presume we have tracepoints for activate/deactivate. and perhaps a sw
> timer, and a hw debug register?
The most important metric is PC state residency, but that requires the
machine to be properly configured: if SATA is preventing our machine
from going deeper than PC3, FBC won't change PC state residencies.
Also, our public processor datasheet docs mention the maximum expected
PC states for the most common screen resolutions.
We can work on adding more things later, such as the tracepoints or
software timer you mentioned. I've been 100% focused on getting the
bugs out first. Is there anything specific you think you could use?
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable
2015-10-21 7:24 ` Daniel Vetter
@ 2015-10-21 18:30 ` Zanoni, Paulo R
2015-10-22 7:59 ` Daniel Vetter
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-21 18:30 UTC (permalink / raw)
To: daniel@ffwll.ch, ville.syrjala@linux.intel.com
Cc: intel-gfx@lists.freedesktop.org
Em Qua, 2015-10-21 às 09:24 +0200, Daniel Vetter escreveu:
> On Wed, Oct 21, 2015 at 10:20:55AM +0300, Ville Syrjälä wrote:
> > On Wed, Oct 21, 2015 at 09:11:08AM +0200, Daniel Vetter wrote:
> > > On Tue, Oct 20, 2015 at 11:50:01AM -0200, Paulo Zanoni wrote:
> > > > One of the problems with the current code is that it frees the
> > > > CFB and
> > > > releases its drm_mm node as soon as we flip FBC's enable bit.
> > > > This is
> > > > bad because after we disbale FBC the hardware may still use the
> > > > CFB
> > > > for the rest of the frame, so in theory we should only release
> > > > the
> > > > drm_mm node one frame after we disable FBC. Otherwise, a stolen
> > > > memory
> > > > allocation done right after an FBC disable may result in either
> > > > corrupted memory for the new owner of that memory region or
> > > > corrupted
> > > > screen/underruns in case the new owner changes it while the
> > > > hardware
> > > > is still reading it. This case is not exactly easy to reproduce
> > > > since
> > > > we currently don't do a lot of stolen memory allocations, but I
> > > > see
> > > > patches on the mailing list trying to expose stolen memory to
> > > > user
> > > > space, so races will be possible.
> > > >
> > > > I thought about three different approaches to solve this, and
> > > > they all
> > > > have downsides.
> > > >
> > > > The first approach would be to simply use multiple drm_mm nodes
> > > > and
> > > > freeing the unused ones only after a frame has passed. The
> > > > problem
> > > > with this approach is that since stolen memory is rather small,
> > > > there's a risk we just won't be able to allocate a new CFB from
> > > > stolen
> > > > if the previous one was not freed yet. This could happen in
> > > > case we
> > > > quickly disable FBC from pipe A and decide to enable it on pipe
> > > > B, or
> > > > just if we change pipe A's fb stride while FBC is enabled.
> > > >
> > > > The second approach would be similar to the first one, but
> > > > maintaining
> > > > a single drm_mm node and keeping track of when it can be
> > > > reused. This
> > > > would remove the disadvantage of not having enough space for
> > > > two
> > > > nodes, but would create the new problem where we may not be
> > > > able to
> > > > enable FBC at the point intel_fbc_update() is called, so we
> > > > would have
> > > > to add more code to retry updating FBC after the time has
> > > > passed. And
> > > > that can quickly get too complex since we can get invalidate,
> > > > flush,
> > > > flip_prepare, disable and other calls in the middle of the
> > > > wait.
> > > >
> > > > Both solutions above - and also the current code - have the
> > > > problem
> > > > that we unnecessarily free+realloc FBC during invalidate+flush
> > > > operations even if the CFB size doesn't change.
> > > >
> > > > The third option would be to move the allocation/deallocation
> > > > to
> > > > enable/disable. This makes sure that the pipe is always
> > > > disabled when
> > > > we allocate/deallocate the CFB, so there's no risk that the FBC
> > > > hardware may read or write to the memory right after it is
> > > > freed from
> > > > drm_mm. The downside is that it is possible for user space to
> > > > change
> > > > the buffer stride without triggering a disable/enable - only
> > > > deactivate/activate -, so we'll have to handle this case
> > > > somehow, even
> > > > though it is uncommon - see igt's kms_frontbuffer_tracking
> > > > test,
> > > > fbc-stridechange subtest. It could be possible to implement a
> > > > way to
> > > > free+alloc the CFB during said stride change, but it would
> > > > involve a
> > > > lot of book-keeping - exactly as mentioned above - just for a
> > > > rare
> > > > case, so for now I'll keep it simple and just deactivate FBC.
> > > > Besides,
> > > > we may not even need to disable FBC since we do CFB over-
> > > > allocation.
> > > >
> > > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > > ---
> > > > drivers/gpu/drm/i915/intel_fbc.c | 132 ++++++++++++++++++++---
> > > > ----------------
> > > > 1 file changed, 68 insertions(+), 64 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > > index bf855b2..48d8cfc 100644
> > > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > > @@ -59,6 +59,45 @@ static unsigned int
> > > > get_crtc_fence_y_offset(struct intel_crtc *crtc)
> > > > return crtc->base.y - crtc->adjusted_y;
> > > > }
> > > >
> > > > +/*
> > > > + * 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(struct intel_crtc
> > > > *crtc,
> > > > + int *width, int
> > > > *height)
> > > > +{
> > > > + struct intel_plane_state *plane_state =
> > > > + to_intel_plane_state(crtc-
> > > > >base.primary->state);
> > > > + int w, h;
> > > > +
> > > > + if (intel_rotation_90_or_270(plane_state-
> > > > >base.rotation)) {
> > > > + w = drm_rect_height(&plane_state->src) >> 16;
> > > > + h = drm_rect_width(&plane_state->src) >> 16;
> > > > + } else {
> > > > + w = drm_rect_width(&plane_state->src) >> 16;
> > > > + h = drm_rect_height(&plane_state->src) >> 16;
> > > > + }
> > > > +
> > > > + if (width)
> > > > + *width = w;
> > > > + if (height)
> > > > + *height = h;
> > > > +}
> > > > +
> > > > +static int intel_fbc_calculate_cfb_size(struct intel_crtc
> > > > *crtc,
> > > > + struct drm_framebuffer
> > > > *fb)
> > > > +{
> > > > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > >dev_private;
> > > > + int lines;
> > > > +
> > > > + intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > > > + if (INTEL_INFO(dev_priv)->gen >= 7)
> > > > + lines = min(lines, 2048);
> > > > +
> > > > + return lines * fb->pitches[0];
> > >
> > > Why are we even looking at fb->pitches here? I thought that for
> > > fbc we
> > > only compress what we actually scan out, i.e. the source
> > > rectangle of the
> > > plane in pixels. Maybe some rounding involved perhaps.
> >
> > IIRC the docs do say the hw uses the plane stride register figure
> > this
> > out. It's something I've been wondering for a few years now, but
> > never
> > actually tested to see if we can get away with less.
So we have a volunteer to implement the stolen memory checker? :)
> In that case a comment would be great, maybe even with the Bspec
> citation.
Well, the docs talk about the stride and the HW guys confirmed it, so
it didn't seem to be as something that needed a comment.
You can also git-blame it :)
http://cgit.freedesktop.org/drm-intel/commit/drivers/gpu/drm/i915/intel
_fbc.c?id=c4ffd40908c30a33291227920e921f6b45b9e8f7
> -Daniel
>
> >
> > >
> > > Or did I miss something?
> > > -Daniel
> > >
> > > > +}
> > > > +
> > > > static void i8xx_fbc_deactivate(struct drm_i915_private
> > > > *dev_priv)
> > > > {
> > > > u32 fbc_ctl;
> > > > @@ -604,11 +643,17 @@ again:
> > > > }
> > > > }
> > > >
> > > > -static int intel_fbc_alloc_cfb(struct drm_i915_private
> > > > *dev_priv, int size,
> > > > - int fb_cpp)
> > > > +static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
> > > > {
> > > > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > >dev_private;
> > > > + struct drm_framebuffer *fb = crtc->base.primary-
> > > > >state->fb;
> > > > struct drm_mm_node *uninitialized_var(compressed_llb);
> > > > - int ret;
> > > > + int size, fb_cpp, ret;
> > > > +
> > > > + WARN_ON(dev_priv->fbc.compressed_fb.allocated);
> > > > +
> > > > + size = intel_fbc_calculate_cfb_size(crtc, fb);
> > > > + fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > > >
> > > > ret = find_compression_threshold(dev_priv, &dev_priv-
> > > > >fbc.compressed_fb,
> > > > size, fb_cpp);
> > > > @@ -685,64 +730,6 @@ void intel_fbc_cleanup_cfb(struct
> > > > drm_i915_private *dev_priv)
> > > > mutex_unlock(&dev_priv->fbc.lock);
> > > > }
> > > >
> > > > -/*
> > > > - * 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(struct intel_crtc
> > > > *crtc,
> > > > - int *width, int
> > > > *height)
> > > > -{
> > > > - struct intel_plane_state *plane_state =
> > > > - to_intel_plane_state(crtc-
> > > > >base.primary->state);
> > > > - int w, h;
> > > > -
> > > > - if (intel_rotation_90_or_270(plane_state-
> > > > >base.rotation)) {
> > > > - w = drm_rect_height(&plane_state->src) >> 16;
> > > > - h = drm_rect_width(&plane_state->src) >> 16;
> > > > - } else {
> > > > - w = drm_rect_width(&plane_state->src) >> 16;
> > > > - h = drm_rect_height(&plane_state->src) >> 16;
> > > > - }
> > > > -
> > > > - if (width)
> > > > - *width = w;
> > > > - if (height)
> > > > - *height = h;
> > > > -}
> > > > -
> > > > -static int intel_fbc_calculate_cfb_size(struct intel_crtc
> > > > *crtc)
> > > > -{
> > > > - struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > >dev_private;
> > > > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > > - int lines;
> > > > -
> > > > - intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > > > - if (INTEL_INFO(dev_priv)->gen >= 7)
> > > > - lines = min(lines, 2048);
> > > > -
> > > > - return lines * fb->pitches[0];
> > > > -}
> > > > -
> > > > -static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
> > > > -{
> > > > - struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > >dev_private;
> > > > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > > - int size, cpp;
> > > > -
> > > > - size = intel_fbc_calculate_cfb_size(crtc);
> > > > - cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > > > -
> > > > - if (dev_priv->fbc.compressed_fb.allocated &&
> > > > - size <= dev_priv->fbc.compressed_fb.size *
> > > > dev_priv->fbc.threshold)
> > > > - return 0;
> > > > -
> > > > - /* Release any current block */
> > > > - __intel_fbc_cleanup_cfb(dev_priv);
> > > > -
> > > > - return intel_fbc_alloc_cfb(dev_priv, size, cpp);
> > > > -}
> > > > -
> > > > static bool stride_is_valid(struct drm_i915_private *dev_priv,
> > > > unsigned int stride)
> > > > {
> > > > @@ -904,8 +891,19 @@ static void __intel_fbc_update(struct
> > > > intel_crtc *crtc)
> > > > goto out_disable;
> > > > }
> > > >
> > > > - if (intel_fbc_setup_cfb(crtc)) {
> > > > - set_no_fbc_reason(dev_priv, "not enough stolen
> > > > memory");
> > > > + /* 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
> > > > + * if this happens, but if we exceed the current CFB
> > > > size we'll have to
> > > > + * disable FBC. Notice that it would be possible to
> > > > disable FBC, wait
> > > > + * 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 case we expect to be
> > > > uncommon, so we
> > > > + * just don't have this code for now. */
> > > > + if (intel_fbc_calculate_cfb_size(crtc, fb) >
> > > > + dev_priv->fbc.compressed_fb.size * dev_priv-
> > > > >fbc.threshold) {
> > > > + set_no_fbc_reason(dev_priv, "CFB requirements
> > > > changed");
> > > > goto out_disable;
> > > > }
> > > >
> > > > @@ -958,7 +956,6 @@ out_disable:
> > > > DRM_DEBUG_KMS("unsupported config,
> > > > deactivating FBC\n");
> > > > __intel_fbc_deactivate(dev_priv);
> > > > }
> > > > - __intel_fbc_cleanup_cfb(dev_priv);
> > > > }
> > > >
> > > > /*
> > > > @@ -1102,6 +1099,11 @@ void intel_fbc_enable(struct intel_crtc
> > > > *crtc)
> > > > goto out;
> > > > }
> > > >
> > > > + if (intel_fbc_alloc_cfb(crtc)) {
> > > > + set_no_fbc_reason(dev_priv, "not enough stolen
> > > > memory");
> > > > + goto out;
> > > > + }
> > > > +
> > > > DRM_DEBUG_KMS("Enabling FBC on pipe %c\n",
> > > > pipe_name(crtc->pipe));
> > > > dev_priv->fbc.no_fbc_reason = "FBC enabled but not
> > > > active yet\n";
> > > >
> > > > @@ -1129,6 +1131,8 @@ static void __intel_fbc_disable(struct
> > > > drm_i915_private *dev_priv)
> > > >
> > > > DRM_DEBUG_KMS("Disabling FBC on pipe %c\n",
> > > > pipe_name(crtc->pipe));
> > > >
> > > > + __intel_fbc_cleanup_cfb(dev_priv);
> > > > +
> > > > dev_priv->fbc.enabled = false;
> > > > dev_priv->fbc.crtc = NULL;
> > > > }
> > > > --
> > > > 2.6.1
> > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > http://blog.ffwll.ch
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> > --
> > Ville Syrjälä
> > Intel OTC
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-20 13:49 ` [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code Paulo Zanoni
2015-10-20 15:52 ` Chris Wilson
@ 2015-10-22 7:52 ` Maarten Lankhorst
2015-10-22 19:26 ` Zanoni, Paulo R
1 sibling, 1 reply; 57+ messages in thread
From: Maarten Lankhorst @ 2015-10-22 7:52 UTC (permalink / raw)
To: Paulo Zanoni, intel-gfx
Op 20-10-15 om 15:49 schreef Paulo Zanoni:
> We're going to kill intel_fbc_find_crtc(), that's why a big part of
> the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
> drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
> 1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
> index b9cfd16..1162787 100644
> --- a/drivers/gpu/drm/i915/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/intel_fbc.c
> @@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct drm_i915_private *dev_priv,
> DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> }
>
> +static bool crtc_is_valid(struct intel_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> + enum pipe pipe = crtc->pipe;
> +
> + if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) &&
> + pipe != PIPE_A)
> + return false;
> +
> + return intel_crtc_active(&crtc->base) &&
> + to_intel_plane_state(crtc->base.primary->state)->visible &&
> + crtc->base.primary->fb != NULL;
> +}
>
I've been considering something like this, but could it be changed to take atomic states as arguments?
That way it will be easier to use when >1 flip depth is allowed in the future, and intel_crtc_active is not
a check that should be used here.
At some point in the near future I want to convert intel_unpin_work to take the previous and next crtc/plane
states, that would become a lot easier if this code would be more atomic like. :)
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable
2015-10-21 18:30 ` Zanoni, Paulo R
@ 2015-10-22 7:59 ` Daniel Vetter
0 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2015-10-22 7:59 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 06:30:09PM +0000, Zanoni, Paulo R wrote:
> Em Qua, 2015-10-21 às 09:24 +0200, Daniel Vetter escreveu:
> > On Wed, Oct 21, 2015 at 10:20:55AM +0300, Ville Syrjälä wrote:
> > > On Wed, Oct 21, 2015 at 09:11:08AM +0200, Daniel Vetter wrote:
> > > > On Tue, Oct 20, 2015 at 11:50:01AM -0200, Paulo Zanoni wrote:
> > > > > One of the problems with the current code is that it frees the
> > > > > CFB and
> > > > > releases its drm_mm node as soon as we flip FBC's enable bit.
> > > > > This is
> > > > > bad because after we disbale FBC the hardware may still use the
> > > > > CFB
> > > > > for the rest of the frame, so in theory we should only release
> > > > > the
> > > > > drm_mm node one frame after we disable FBC. Otherwise, a stolen
> > > > > memory
> > > > > allocation done right after an FBC disable may result in either
> > > > > corrupted memory for the new owner of that memory region or
> > > > > corrupted
> > > > > screen/underruns in case the new owner changes it while the
> > > > > hardware
> > > > > is still reading it. This case is not exactly easy to reproduce
> > > > > since
> > > > > we currently don't do a lot of stolen memory allocations, but I
> > > > > see
> > > > > patches on the mailing list trying to expose stolen memory to
> > > > > user
> > > > > space, so races will be possible.
> > > > >
> > > > > I thought about three different approaches to solve this, and
> > > > > they all
> > > > > have downsides.
> > > > >
> > > > > The first approach would be to simply use multiple drm_mm nodes
> > > > > and
> > > > > freeing the unused ones only after a frame has passed. The
> > > > > problem
> > > > > with this approach is that since stolen memory is rather small,
> > > > > there's a risk we just won't be able to allocate a new CFB from
> > > > > stolen
> > > > > if the previous one was not freed yet. This could happen in
> > > > > case we
> > > > > quickly disable FBC from pipe A and decide to enable it on pipe
> > > > > B, or
> > > > > just if we change pipe A's fb stride while FBC is enabled.
> > > > >
> > > > > The second approach would be similar to the first one, but
> > > > > maintaining
> > > > > a single drm_mm node and keeping track of when it can be
> > > > > reused. This
> > > > > would remove the disadvantage of not having enough space for
> > > > > two
> > > > > nodes, but would create the new problem where we may not be
> > > > > able to
> > > > > enable FBC at the point intel_fbc_update() is called, so we
> > > > > would have
> > > > > to add more code to retry updating FBC after the time has
> > > > > passed. And
> > > > > that can quickly get too complex since we can get invalidate,
> > > > > flush,
> > > > > flip_prepare, disable and other calls in the middle of the
> > > > > wait.
> > > > >
> > > > > Both solutions above - and also the current code - have the
> > > > > problem
> > > > > that we unnecessarily free+realloc FBC during invalidate+flush
> > > > > operations even if the CFB size doesn't change.
> > > > >
> > > > > The third option would be to move the allocation/deallocation
> > > > > to
> > > > > enable/disable. This makes sure that the pipe is always
> > > > > disabled when
> > > > > we allocate/deallocate the CFB, so there's no risk that the FBC
> > > > > hardware may read or write to the memory right after it is
> > > > > freed from
> > > > > drm_mm. The downside is that it is possible for user space to
> > > > > change
> > > > > the buffer stride without triggering a disable/enable - only
> > > > > deactivate/activate -, so we'll have to handle this case
> > > > > somehow, even
> > > > > though it is uncommon - see igt's kms_frontbuffer_tracking
> > > > > test,
> > > > > fbc-stridechange subtest. It could be possible to implement a
> > > > > way to
> > > > > free+alloc the CFB during said stride change, but it would
> > > > > involve a
> > > > > lot of book-keeping - exactly as mentioned above - just for a
> > > > > rare
> > > > > case, so for now I'll keep it simple and just deactivate FBC.
> > > > > Besides,
> > > > > we may not even need to disable FBC since we do CFB over-
> > > > > allocation.
> > > > >
> > > > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > > > ---
> > > > > drivers/gpu/drm/i915/intel_fbc.c | 132 ++++++++++++++++++++---
> > > > > ----------------
> > > > > 1 file changed, 68 insertions(+), 64 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > > > index bf855b2..48d8cfc 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > > > @@ -59,6 +59,45 @@ static unsigned int
> > > > > get_crtc_fence_y_offset(struct intel_crtc *crtc)
> > > > > return crtc->base.y - crtc->adjusted_y;
> > > > > }
> > > > >
> > > > > +/*
> > > > > + * 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(struct intel_crtc
> > > > > *crtc,
> > > > > + int *width, int
> > > > > *height)
> > > > > +{
> > > > > + struct intel_plane_state *plane_state =
> > > > > + to_intel_plane_state(crtc-
> > > > > >base.primary->state);
> > > > > + int w, h;
> > > > > +
> > > > > + if (intel_rotation_90_or_270(plane_state-
> > > > > >base.rotation)) {
> > > > > + w = drm_rect_height(&plane_state->src) >> 16;
> > > > > + h = drm_rect_width(&plane_state->src) >> 16;
> > > > > + } else {
> > > > > + w = drm_rect_width(&plane_state->src) >> 16;
> > > > > + h = drm_rect_height(&plane_state->src) >> 16;
> > > > > + }
> > > > > +
> > > > > + if (width)
> > > > > + *width = w;
> > > > > + if (height)
> > > > > + *height = h;
> > > > > +}
> > > > > +
> > > > > +static int intel_fbc_calculate_cfb_size(struct intel_crtc
> > > > > *crtc,
> > > > > + struct drm_framebuffer
> > > > > *fb)
> > > > > +{
> > > > > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > > >dev_private;
> > > > > + int lines;
> > > > > +
> > > > > + intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > > > > + if (INTEL_INFO(dev_priv)->gen >= 7)
> > > > > + lines = min(lines, 2048);
> > > > > +
> > > > > + return lines * fb->pitches[0];
> > > >
> > > > Why are we even looking at fb->pitches here? I thought that for
> > > > fbc we
> > > > only compress what we actually scan out, i.e. the source
> > > > rectangle of the
> > > > plane in pixels. Maybe some rounding involved perhaps.
> > >
> > > IIRC the docs do say the hw uses the plane stride register figure
> > > this
> > > out. It's something I've been wondering for a few years now, but
> > > never
> > > actually tested to see if we can get away with less.
>
> So we have a volunteer to implement the stolen memory checker? :)
>
>
> > In that case a comment would be great, maybe even with the Bspec
> > citation.
>
> Well, the docs talk about the stride and the HW guys confirmed it, so
> it didn't seem to be as something that needed a comment.
>
> You can also git-blame it :)
>
> http://cgit.freedesktop.org/drm-intel/commit/drivers/gpu/drm/i915/intel
> _fbc.c?id=c4ffd40908c30a33291227920e921f6b45b9e8f7
Indeed, \o/ for good commit message. Still seems fairly surprising that
the hw expects the stride and not just what it actually has to read. But I
guess I've learned that now. A comment for the next person would still be
good though I think. Something like:
/* hw needs the full buffer stride, not just the active area */
To make it clear this is 100% intentional ;-)
-Daniel
>
>
> > -Daniel
> >
> > >
> > > >
> > > > Or did I miss something?
> > > > -Daniel
> > > >
> > > > > +}
> > > > > +
> > > > > static void i8xx_fbc_deactivate(struct drm_i915_private
> > > > > *dev_priv)
> > > > > {
> > > > > u32 fbc_ctl;
> > > > > @@ -604,11 +643,17 @@ again:
> > > > > }
> > > > > }
> > > > >
> > > > > -static int intel_fbc_alloc_cfb(struct drm_i915_private
> > > > > *dev_priv, int size,
> > > > > - int fb_cpp)
> > > > > +static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
> > > > > {
> > > > > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > > >dev_private;
> > > > > + struct drm_framebuffer *fb = crtc->base.primary-
> > > > > >state->fb;
> > > > > struct drm_mm_node *uninitialized_var(compressed_llb);
> > > > > - int ret;
> > > > > + int size, fb_cpp, ret;
> > > > > +
> > > > > + WARN_ON(dev_priv->fbc.compressed_fb.allocated);
> > > > > +
> > > > > + size = intel_fbc_calculate_cfb_size(crtc, fb);
> > > > > + fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > > > >
> > > > > ret = find_compression_threshold(dev_priv, &dev_priv-
> > > > > >fbc.compressed_fb,
> > > > > size, fb_cpp);
> > > > > @@ -685,64 +730,6 @@ void intel_fbc_cleanup_cfb(struct
> > > > > drm_i915_private *dev_priv)
> > > > > mutex_unlock(&dev_priv->fbc.lock);
> > > > > }
> > > > >
> > > > > -/*
> > > > > - * 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(struct intel_crtc
> > > > > *crtc,
> > > > > - int *width, int
> > > > > *height)
> > > > > -{
> > > > > - struct intel_plane_state *plane_state =
> > > > > - to_intel_plane_state(crtc-
> > > > > >base.primary->state);
> > > > > - int w, h;
> > > > > -
> > > > > - if (intel_rotation_90_or_270(plane_state-
> > > > > >base.rotation)) {
> > > > > - w = drm_rect_height(&plane_state->src) >> 16;
> > > > > - h = drm_rect_width(&plane_state->src) >> 16;
> > > > > - } else {
> > > > > - w = drm_rect_width(&plane_state->src) >> 16;
> > > > > - h = drm_rect_height(&plane_state->src) >> 16;
> > > > > - }
> > > > > -
> > > > > - if (width)
> > > > > - *width = w;
> > > > > - if (height)
> > > > > - *height = h;
> > > > > -}
> > > > > -
> > > > > -static int intel_fbc_calculate_cfb_size(struct intel_crtc
> > > > > *crtc)
> > > > > -{
> > > > > - struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > > >dev_private;
> > > > > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > > > - int lines;
> > > > > -
> > > > > - intel_fbc_get_plane_source_size(crtc, NULL, &lines);
> > > > > - if (INTEL_INFO(dev_priv)->gen >= 7)
> > > > > - lines = min(lines, 2048);
> > > > > -
> > > > > - return lines * fb->pitches[0];
> > > > > -}
> > > > > -
> > > > > -static int intel_fbc_setup_cfb(struct intel_crtc *crtc)
> > > > > -{
> > > > > - struct drm_i915_private *dev_priv = crtc->base.dev-
> > > > > >dev_private;
> > > > > - struct drm_framebuffer *fb = crtc->base.primary->fb;
> > > > > - int size, cpp;
> > > > > -
> > > > > - size = intel_fbc_calculate_cfb_size(crtc);
> > > > > - cpp = drm_format_plane_cpp(fb->pixel_format, 0);
> > > > > -
> > > > > - if (dev_priv->fbc.compressed_fb.allocated &&
> > > > > - size <= dev_priv->fbc.compressed_fb.size *
> > > > > dev_priv->fbc.threshold)
> > > > > - return 0;
> > > > > -
> > > > > - /* Release any current block */
> > > > > - __intel_fbc_cleanup_cfb(dev_priv);
> > > > > -
> > > > > - return intel_fbc_alloc_cfb(dev_priv, size, cpp);
> > > > > -}
> > > > > -
> > > > > static bool stride_is_valid(struct drm_i915_private *dev_priv,
> > > > > unsigned int stride)
> > > > > {
> > > > > @@ -904,8 +891,19 @@ static void __intel_fbc_update(struct
> > > > > intel_crtc *crtc)
> > > > > goto out_disable;
> > > > > }
> > > > >
> > > > > - if (intel_fbc_setup_cfb(crtc)) {
> > > > > - set_no_fbc_reason(dev_priv, "not enough stolen
> > > > > memory");
> > > > > + /* 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
> > > > > + * if this happens, but if we exceed the current CFB
> > > > > size we'll have to
> > > > > + * disable FBC. Notice that it would be possible to
> > > > > disable FBC, wait
> > > > > + * 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 case we expect to be
> > > > > uncommon, so we
> > > > > + * just don't have this code for now. */
> > > > > + if (intel_fbc_calculate_cfb_size(crtc, fb) >
> > > > > + dev_priv->fbc.compressed_fb.size * dev_priv-
> > > > > >fbc.threshold) {
> > > > > + set_no_fbc_reason(dev_priv, "CFB requirements
> > > > > changed");
> > > > > goto out_disable;
> > > > > }
> > > > >
> > > > > @@ -958,7 +956,6 @@ out_disable:
> > > > > DRM_DEBUG_KMS("unsupported config,
> > > > > deactivating FBC\n");
> > > > > __intel_fbc_deactivate(dev_priv);
> > > > > }
> > > > > - __intel_fbc_cleanup_cfb(dev_priv);
> > > > > }
> > > > >
> > > > > /*
> > > > > @@ -1102,6 +1099,11 @@ void intel_fbc_enable(struct intel_crtc
> > > > > *crtc)
> > > > > goto out;
> > > > > }
> > > > >
> > > > > + if (intel_fbc_alloc_cfb(crtc)) {
> > > > > + set_no_fbc_reason(dev_priv, "not enough stolen
> > > > > memory");
> > > > > + goto out;
> > > > > + }
> > > > > +
> > > > > DRM_DEBUG_KMS("Enabling FBC on pipe %c\n",
> > > > > pipe_name(crtc->pipe));
> > > > > dev_priv->fbc.no_fbc_reason = "FBC enabled but not
> > > > > active yet\n";
> > > > >
> > > > > @@ -1129,6 +1131,8 @@ static void __intel_fbc_disable(struct
> > > > > drm_i915_private *dev_priv)
> > > > >
> > > > > DRM_DEBUG_KMS("Disabling FBC on pipe %c\n",
> > > > > pipe_name(crtc->pipe));
> > > > >
> > > > > + __intel_fbc_cleanup_cfb(dev_priv);
> > > > > +
> > > > > dev_priv->fbc.enabled = false;
> > > > > dev_priv->fbc.crtc = NULL;
> > > > > }
> > > > > --
> > > > > 2.6.1
> > > > >
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > >
> > > > --
> > > > Daniel Vetter
> > > > Software Engineer, Intel Corporation
> > > > http://blog.ffwll.ch
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > >
> > > --
> > > Ville Syrjälä
> > > Intel OTC
> >
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-22 7:52 ` Maarten Lankhorst
@ 2015-10-22 19:26 ` Zanoni, Paulo R
2015-10-22 19:42 ` Ville Syrjälä
0 siblings, 1 reply; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-22 19:26 UTC (permalink / raw)
To: intel-gfx@lists.freedesktop.org,
maarten.lankhorst@linux.intel.com
Em Qui, 2015-10-22 às 09:52 +0200, Maarten Lankhorst escreveu:
> Op 20-10-15 om 15:49 schreef Paulo Zanoni:
> > We're going to kill intel_fbc_find_crtc(), that's why a big part of
> > the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> > drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
> > 1 file changed, 16 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > b/drivers/gpu/drm/i915/intel_fbc.c
> > index b9cfd16..1162787 100644
> > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > @@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct
> > drm_i915_private *dev_priv,
> > DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> > }
> >
> > +static bool crtc_is_valid(struct intel_crtc *crtc)
> > +{
> > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > >dev_private;
> > + enum pipe pipe = crtc->pipe;
> > +
> > + if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >=
> > 8) &&
> > + pipe != PIPE_A)
> > + return false;
> > +
> > + return intel_crtc_active(&crtc->base) &&
> > + to_intel_plane_state(crtc->base.primary->state)-
> > >visible &&
> > + crtc->base.primary->fb != NULL;
> > +}
> >
> I've been considering something like this, but could it be changed to
> take atomic states as arguments?
I'm not sure. All I know is that this is still (both now and at the end
of the series) being called while the CRTC is already enabled, not
during modeset paths. The visible/invisible case seems to be the most
important check. The other two checks are like this simply because this
code was written a loooong time ago and was never updated while the
rest of the tree evolved.
Since there are so many things to update on the FBC code I was just
trying to move the code around without really over-analyzing it since
it seemed to be working. But I guess these days any line of i915 code
touched on a patch has to be perfect :)
Anyway, I'll try to update this code on this series since you & Chris &
Ville already asked about it.
> That way it will be easier to use when >1 flip depth is allowed in
> the future, and intel_crtc_active is not
> a check that should be used here.
>
> At some point in the near future I want to convert intel_unpin_work
> to take the previous and next crtc/plane
> states, that would become a lot easier if this code would be more
> atomic like. :)
>
> ~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code
2015-10-22 19:26 ` Zanoni, Paulo R
@ 2015-10-22 19:42 ` Ville Syrjälä
0 siblings, 0 replies; 57+ messages in thread
From: Ville Syrjälä @ 2015-10-22 19:42 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Thu, Oct 22, 2015 at 07:26:36PM +0000, Zanoni, Paulo R wrote:
> Em Qui, 2015-10-22 às 09:52 +0200, Maarten Lankhorst escreveu:
> > Op 20-10-15 om 15:49 schreef Paulo Zanoni:
> > > We're going to kill intel_fbc_find_crtc(), that's why a big part of
> > > the logic moved from intel_fbc_find_crtc() to crtc_is_valid().
> > >
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > ---
> > > drivers/gpu/drm/i915/intel_fbc.c | 26 ++++++++++++++++----------
> > > 1 file changed, 16 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > index b9cfd16..1162787 100644
> > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > @@ -538,27 +538,33 @@ static void set_no_fbc_reason(struct
> > > drm_i915_private *dev_priv,
> > > DRM_DEBUG_KMS("Disabling FBC: %s\n", reason);
> > > }
> > >
> > > +static bool crtc_is_valid(struct intel_crtc *crtc)
> > > +{
> > > + struct drm_i915_private *dev_priv = crtc->base.dev-
> > > >dev_private;
> > > + enum pipe pipe = crtc->pipe;
> > > +
> > > + if ((IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >=
> > > 8) &&
> > > + pipe != PIPE_A)
> > > + return false;
> > > +
> > > + return intel_crtc_active(&crtc->base) &&
> > > + to_intel_plane_state(crtc->base.primary->state)-
> > > >visible &&
> > > + crtc->base.primary->fb != NULL;
> > > +}
> > >
> > I've been considering something like this, but could it be changed to
> > take atomic states as arguments?
>
> I'm not sure. All I know is that this is still (both now and at the end
> of the series) being called while the CRTC is already enabled, not
> during modeset paths. The visible/invisible case seems to be the most
> important check. The other two checks are like this simply because this
> code was written a loooong time ago and was never updated while the
> rest of the tree evolved.
You know, fbc_score could be correctly calculated when we are
calculating the rest of the primary plane state ;)
>
> Since there are so many things to update on the FBC code I was just
> trying to move the code around without really over-analyzing it since
> it seemed to be working. But I guess these days any line of i915 code
> touched on a patch has to be perfect :)
>
> Anyway, I'll try to update this code on this series since you & Chris &
> Ville already asked about it.
>
> > That way it will be easier to use when >1 flip depth is allowed in
> > the future, and intel_crtc_active is not
> > a check that should be used here.
> >
> > At some point in the near future I want to convert intel_unpin_work
> > to take the previous and next crtc/plane
> > states, that would become a lot easier if this code would be more
> > atomic like. :)
> >
> > ~Maarten
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 13/18] drm/i915: remove too-frequent FBC debug message
2015-10-21 18:19 ` Zanoni, Paulo R
@ 2015-10-22 19:52 ` chris
0 siblings, 0 replies; 57+ messages in thread
From: chris @ 2015-10-22 19:52 UTC (permalink / raw)
To: Zanoni, Paulo R; +Cc: intel-gfx@lists.freedesktop.org
On Wed, Oct 21, 2015 at 06:19:23PM +0000, Zanoni, Paulo R wrote:
> Em Qua, 2015-10-21 às 14:01 +0100, Chris Wilson escreveu:
> > On Tue, Oct 20, 2015 at 11:49:59AM -0200, Paulo Zanoni wrote:
> > > If we run igt/kms_frontbuffer_tracking, this message will appear
> > > thousands of times, eating a significant part of our dmesg buffer.
> > > It's part of the expected FBC behavior, so let's just silence it.
> > >
> > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > Looks fine. Out of curiosity what metrics do we have for FBC
> > activity? I
> > presume we have tracepoints for activate/deactivate. and perhaps a sw
> > timer, and a hw debug register?
>
> The most important metric is PC state residency, but that requires the
> machine to be properly configured: if SATA is preventing our machine
> from going deeper than PC3, FBC won't change PC state residencies.
> Also, our public processor datasheet docs mention the maximum expected
> PC states for the most common screen resolutions.
>
> We can work on adding more things later, such as the tracepoints or
> software timer you mentioned. I've been 100% focused on getting the
> bugs out first. Is there anything specific you think you could use?
The tracepoints are primarily a debug tool, effectively less noisy
printks that can be easily hooked up to a bit of python for processing
(if just read huge logs isn't satisfying).
For monitoring efficacy, I had in mode a timer for fbc active and
perhaps one for timing compression (ideally the active timer would only
start when the compressed frame was complete, but that may be too much).
That should get us to the point where we can quickly see if we are
enabling FBC for significant periods. Now, this can be done with good
tracepoints and a userspace script. So really just planning good
coverage of tracepoints is the starting point.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments
2015-10-21 17:38 ` chris
@ 2015-10-22 20:15 ` Zanoni, Paulo R
0 siblings, 0 replies; 57+ messages in thread
From: Zanoni, Paulo R @ 2015-10-22 20:15 UTC (permalink / raw)
To: chris@chris-wilson.co.uk; +Cc: intel-gfx@lists.freedesktop.org
Em Qua, 2015-10-21 às 18:38 +0100, chris@chris-wilson.co.uk escreveu:
> On Wed, Oct 21, 2015 at 05:32:16PM +0000, Zanoni, Paulo R wrote:
> > Em Qua, 2015-10-21 às 13:37 +0100, Chris Wilson escreveu:
> > > On Tue, Oct 20, 2015 at 11:49:53AM -0200, Paulo Zanoni wrote:
> > > > Don't try to list in comments the cases where we should enable
> > > > or
> > > > disable FBC: it varies a lot with the hardware generations and
> > > > the
> > > > code should be the documentation. Also notice that there's
> > > > already
> > > > a
> > > > huge gap between the comments and what's in the code.
> > > >
> > > > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > > > ---
> > > > drivers/gpu/drm/i915/intel_fbc.c | 26 ++--------------------
> > > > ----
> > > > 1 file changed, 2 insertions(+), 24 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_fbc.c
> > > > b/drivers/gpu/drm/i915/intel_fbc.c
> > > > index e856304..5fa4ce4 100644
> > > > --- a/drivers/gpu/drm/i915/intel_fbc.c
> > > > +++ b/drivers/gpu/drm/i915/intel_fbc.c
> > > > @@ -853,20 +853,8 @@ static bool
> > > > intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
> > > > * __intel_fbc_update - enable/disable FBC as needed, unlocked
> > > > * @dev_priv: i915 device instance
> > > > *
> > > > - * Set up the framebuffer compression hardware at mode set
> > > > time. We
> > > > - * enable it if possible:
> > > > - * - plane A only (on pre-965)
> > > > - * - no pixel mulitply/line duplication
> > > > - * - no alpha buffer discard
> > > > - * - no dual wide
> > > > - * - framebuffer <= max_hdisplay in width, max_vdisplay in
> > > > height
> > > > - *
> > > > - * We can't assume that any compression will take place (worst
> > > > case),
> > > > - * so the compressed buffer has to be the same size as the
> > > > uncompressed
> > > > - * one. It also must reside (along with the line length
> > > > buffer)
> > > > in
> > > > - * stolen memory.
> > > > - *
> > > > - * We need to enable/disable FBC on a global basis.
> > > > + * This function completely reevaluates the status of FBC,
> > > > then
> > > > enables,
> > > > + * disables or maintains it on the same state.
> > >
> > > By the end, this comment is not strictly true ,right? Since you
> > > move
> > > some of the status checking into modeset enable paths. Could you
> > > refine
> > > the function comment?
> >
> > I only move the status checking into modeset enable paths on patch
> > 12.
> > The comment above is modified on patch 12 to reflect
> > activate/deactivate instead of enable/disable.
>
> Honestly, I would just squash this patch, or apply it after the
> moving
> the code to correctly reflect the split in work between
> update/enable.
The way I see, removing obsolete comments that list the reasons to
enable/disable FBC is orthogonal to the changes regarding
enable/disable/deactivate/activate.
Changing the patch order as you suggested will cause some rebase pain
just to achieve the same end result later, so unless there's some
strong objection I'll spare myself the pain.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 57+ messages in thread
end of thread, other threads:[~2015-10-22 20:15 UTC | newest]
Thread overview: 57+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-20 13:49 [PATCH 00/18] Yet another FBC series Paulo Zanoni
2015-10-20 13:49 ` [PATCH 01/18] drm/i915: change no_fbc_reason from enum to string Paulo Zanoni
2015-10-21 6:52 ` Daniel Vetter
2015-10-20 13:49 ` [PATCH 02/18] drm/i915: don't stop+start FBC at every flip Paulo Zanoni
2015-10-21 7:04 ` Daniel Vetter
2015-10-21 7:12 ` Ville Syrjälä
2015-10-21 7:40 ` Ville Syrjälä
2015-10-20 13:49 ` [PATCH 03/18] drm/i915: only nuke FBC when a drawing operation triggers a flush Paulo Zanoni
2015-10-20 15:59 ` Chris Wilson
2015-10-21 17:08 ` Zanoni, Paulo R
2015-10-21 17:31 ` chris
2015-10-21 17:51 ` Zanoni, Paulo R
2015-10-20 13:49 ` [PATCH 04/18] drm/i915: extract crtc_is_valid() on the FBC code Paulo Zanoni
2015-10-20 15:52 ` Chris Wilson
2015-10-21 17:16 ` Zanoni, Paulo R
2015-10-21 17:28 ` chris
2015-10-22 7:52 ` Maarten Lankhorst
2015-10-22 19:26 ` Zanoni, Paulo R
2015-10-22 19:42 ` Ville Syrjälä
2015-10-20 13:49 ` [PATCH 05/18] drm/i915: set dev_priv->fbc.crtc before scheduling the enable work Paulo Zanoni
2015-10-20 16:03 ` Chris Wilson
2015-10-21 17:27 ` Zanoni, Paulo R
2015-10-21 18:15 ` chris
2015-10-20 13:49 ` [PATCH 06/18] drm/i915: use struct intel_crtc *crtc at __intel_fbc_update() Paulo Zanoni
2015-10-20 13:49 ` [PATCH 07/18] drm/i915: fix the __intel_fbc_update() comments Paulo Zanoni
2015-10-21 12:37 ` Chris Wilson
2015-10-21 17:32 ` Zanoni, Paulo R
2015-10-21 17:38 ` chris
2015-10-22 20:15 ` Zanoni, Paulo R
2015-10-20 13:49 ` [PATCH 08/18] drm/i915: pass the crtc as an argument to intel_fbc_update() Paulo Zanoni
2015-10-20 13:49 ` [PATCH 09/18] drm/i915: don't disable_fbc() if FBC is already disabled Paulo Zanoni
2015-10-20 13:49 ` [PATCH 10/18] drm/i915: introduce is_active/activate/deactivate to the FBC terminology Paulo Zanoni
2015-10-21 12:34 ` Chris Wilson
2015-10-21 17:45 ` Zanoni, Paulo R
2015-10-21 17:55 ` chris
2015-10-20 13:49 ` [PATCH 11/18] drm/i915: refactor FBC deactivation at init Paulo Zanoni
2015-10-21 12:59 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 12/18] drm/i915: introduce intel_fbc_{enable, disable} Paulo Zanoni
2015-10-20 15:55 ` Chris Wilson
2015-10-20 13:49 ` [PATCH 13/18] drm/i915: remove too-frequent FBC debug message Paulo Zanoni
2015-10-21 13:01 ` Chris Wilson
2015-10-21 18:19 ` Zanoni, Paulo R
2015-10-22 19:52 ` chris
2015-10-20 13:50 ` [PATCH 14/18] drm/i915: fix the CFB size check Paulo Zanoni
2015-10-20 13:50 ` [PATCH 15/18] drm/i915: alloc/free the FBC CFB during enable/disable Paulo Zanoni
2015-10-21 7:11 ` Daniel Vetter
2015-10-21 7:20 ` Ville Syrjälä
2015-10-21 7:24 ` Daniel Vetter
2015-10-21 18:30 ` Zanoni, Paulo R
2015-10-22 7:59 ` Daniel Vetter
2015-10-20 13:50 ` [PATCH 16/18] drm/i915: move adjusted_mode checks from fbc_update to fbc_enable Paulo Zanoni
2015-10-20 13:50 ` [PATCH 17/18] drm/i915: move clock frequency " Paulo Zanoni
2015-10-20 13:50 ` [PATCH 18/18] drm/i915: check for FBC planes in the same place as the pipes Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 1/4] kms_frontbuffer_tracking: unset crtcs after getting the base blue CRC Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 2/4] kms_frontbuffer_tracking: add flag to not assert feature status Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 3/4] kms_frontbuffer_tracking: add stridechange subtest Paulo Zanoni
2015-10-20 21:22 ` [PATCH igt 4/4] kms_frontbuffer_tracking: remove opt.only_feature Paulo Zanoni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox