All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip
@ 2015-10-07  0:02 Matt Roper
  2015-10-07  0:04 ` [PATCH i-g-t] kms_universal_plane: Add gen9-specific test Matt Roper
  2015-10-07 12:02 ` [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip Ville Syrjälä
  0 siblings, 2 replies; 4+ messages in thread
From: Matt Roper @ 2015-10-07  0:02 UTC (permalink / raw)
  To: intel-gfx

The legacy pageflip ioctl calls drm_crtc_check_viewport() to determine
whether the framebuffer being flipped is big enough to fill the display
it is being flipped to.  However some drivers support "windowing" of
their primary planes (i.e., a primary plane that does not cover the
entire CRTC dimensions); in such situations we can wind up rejecting
valid pageflips of buffers that are smaller than the display mode, but
still large enough to fill the entire primary plane.

What we really want to be comparing against for pageflips is the size of
the primary plane, which can be found in crtc->primary->state for atomic
drivers (and drivers in the process of transitioning to atomic).  There
are no non-atomic drivers that support primary plane windowing at the
moment, so we'll continue to use the current behavior of looking at the
CRTC mode size on drivers that don't have a crtc->primary->state.  We'll
also continue to use the existing logic for SetCrtc, which is the other
callsite for drm_crtc_check_viewport(), since legacy modesets reprogram
the primary plane and remove windowing.

Note that the existing code was checking a crtc->invert_dimensions field
to determine whether the width/height of the mode needed to be swapped.
A bonus of checking plane size is that the source width/height we get
already take rotation into account so that check is no longer necessary
when using the plane size.

Testcase: igt/universal-plane-gen9-features-pipe-#
Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/drm_crtc.c | 87 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e600a5f..35cd4dc 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2534,9 +2534,76 @@ void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
 }
 EXPORT_SYMBOL(drm_crtc_get_hv_timing);
 
+static int check_viewport(int hdisplay,
+			  int vdisplay,
+			  int x,
+			  int y,
+			  bool invert_dimensions,
+			  const struct drm_framebuffer *fb)
+{
+	if (invert_dimensions)
+		swap(hdisplay, vdisplay);
+
+	if (hdisplay > fb->width ||
+	    vdisplay > fb->height ||
+	    x > fb->width - hdisplay ||
+	    y > fb->height - vdisplay) {
+		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+			      fb->width, fb->height, hdisplay, vdisplay, x, y,
+			      invert_dimensions ? " (inverted)" : "");
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+
+/**
+ * drm_plane_check_viewport - Checks that a framebuffer is big enough for the
+ *     plane's viewport
+ * @plane: Plane that framebuffer will be displayed on
+ * @x: x panning
+ * @y: y panning
+ * @fb: framebuffer to check size of
+ *
+ * Atomic drivers (or transitioning drivers that support proper plane state)
+ * may call this function on any plane.  Non-atomic drivers may only call this
+ * for the primary plane while the CRTC is active (we'll assume that the
+ * primary plane covers the entire CRTC in that case).
+ */
+int drm_plane_check_viewport(const struct drm_plane *plane,
+			     int x,
+			     int y,
+			     const struct drm_framebuffer *fb)
+
+{
+	struct drm_crtc *crtc = plane->crtc;
+	int hdisplay, vdisplay;
+
+	if (WARN_ON(plane->state == NULL &&
+		    plane->type != DRM_PLANE_TYPE_PRIMARY))
+		return -EINVAL;
+
+	/*
+	 * Non-atomic drivers may not have valid plane state to look at.  But
+	 * those drivers also don't support windowing of the primary plane, so
+	 * we can fall back to looking at the mode of the owning CRTC.
+	 */
+	if (plane->state) {
+		hdisplay = plane->state->src_w >> 16;
+		vdisplay = plane->state->src_h >> 16;
+	} else if (WARN_ON(!crtc)) {
+		hdisplay = vdisplay = 0;
+	} else {
+		drm_crtc_get_hv_timing(&crtc->mode, &hdisplay, &vdisplay);
+	}
+
+	return check_viewport(hdisplay, vdisplay, x, y, false, fb);
+}
+EXPORT_SYMBOL(drm_plane_check_viewport);
+
 /**
  * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
- *     CRTC viewport
+ *     CRTC viewport when running in the specified mode
  * @crtc: CRTC that framebuffer will be displayed on
  * @x: x panning
  * @y: y panning
@@ -2553,20 +2620,8 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
 
 	drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
 
-	if (crtc->invert_dimensions)
-		swap(hdisplay, vdisplay);
-
-	if (hdisplay > fb->width ||
-	    vdisplay > fb->height ||
-	    x > fb->width - hdisplay ||
-	    y > fb->height - vdisplay) {
-		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
-			      fb->width, fb->height, hdisplay, vdisplay, x, y,
-			      crtc->invert_dimensions ? " (inverted)" : "");
-		return -ENOSPC;
-	}
-
-	return 0;
+	return check_viewport(hdisplay, vdisplay, x, y,
+			      crtc->invert_dimensions, fb);
 }
 EXPORT_SYMBOL(drm_crtc_check_viewport);
 
@@ -5181,7 +5236,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 		goto out;
 	}
 
-	ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
+	ret = drm_plane_check_viewport(crtc->primary, crtc->x, crtc->y, fb);
 	if (ret)
 		goto out;
 
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH i-g-t] kms_universal_plane: Add gen9-specific test
  2015-10-07  0:02 [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip Matt Roper
@ 2015-10-07  0:04 ` Matt Roper
  2015-10-07 12:02 ` [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip Ville Syrjälä
  1 sibling, 0 replies; 4+ messages in thread
From: Matt Roper @ 2015-10-07  0:04 UTC (permalink / raw)
  To: intel-gfx

Gen9 adds some new capabilities not present on previous platforms
(primary plane windowing, 90/270 rotation, etc.).  Add a new subtest to
check how these new features interact with the use of the universal
plane API.

For now we just check whether pageflips work as expected in a windowed
setting.  We may want to add some rotation testing in future patches.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 tests/kms_universal_plane.c | 107 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/tests/kms_universal_plane.c b/tests/kms_universal_plane.c
index b233166..b06b51e 100644
--- a/tests/kms_universal_plane.c
+++ b/tests/kms_universal_plane.c
@@ -54,6 +54,13 @@ typedef struct {
 	struct igt_fb red_fb, blue_fb;
 } pageflip_test_t;
 
+typedef struct {
+	data_t *data;
+	int x, y;
+	int w, h;
+	struct igt_fb biggreen_fb, smallred_fb, smallblue_fb;
+} gen9_test_t;
+
 static void
 functional_test_init(functional_test_t *test, igt_output_t *output, enum pipe pipe)
 {
@@ -637,6 +644,101 @@ cursor_leak_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
 }
 
 static void
+gen9_test_init(gen9_test_t *test, igt_output_t *output, enum pipe pipe)
+{
+	data_t *data = test->data;
+	drmModeModeInfo *mode;
+
+	igt_output_set_pipe(output, pipe);
+
+	mode = igt_output_get_mode(output);
+	test->w = mode->hdisplay / 2;
+	test->h = mode->vdisplay / 2;
+	test->x = mode->hdisplay / 4;
+	test->y = mode->vdisplay / 4;
+
+	/* Initial framebuffer of full CRTC size */
+	igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
+			    DRM_FORMAT_XRGB8888,
+			    LOCAL_DRM_FORMAT_MOD_NONE,
+			    0.0, 1.0, 0.0,
+			    &test->biggreen_fb);
+
+	/* Framebuffers that only cover a quarter of the CRTC size */
+	igt_create_color_fb(data->drm_fd, test->w, test->h,
+			    DRM_FORMAT_XRGB8888,
+			    LOCAL_DRM_FORMAT_MOD_NONE,
+			    1.0, 0.0, 0.0,
+			    &test->smallred_fb);
+	igt_create_color_fb(data->drm_fd, test->w, test->h,
+			    DRM_FORMAT_XRGB8888,
+			    LOCAL_DRM_FORMAT_MOD_NONE,
+			    0.0, 0.0, 1.0,
+			    &test->smallblue_fb);
+}
+
+static void
+gen9_test_fini(gen9_test_t *test, igt_output_t *output)
+{
+	igt_remove_fb(test->data->drm_fd, &test->biggreen_fb);
+	igt_remove_fb(test->data->drm_fd, &test->smallred_fb);
+	igt_remove_fb(test->data->drm_fd, &test->smallblue_fb);
+
+	igt_output_set_pipe(output, PIPE_ANY);
+	igt_display_commit2(&test->data->display, COMMIT_LEGACY);
+}
+
+/*
+ * Test features specific to gen9+ platforms (i.e., primary plane
+ * windowing)
+ */
+static void
+gen9_test_pipe(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+	gen9_test_t test = { .data = data };
+	igt_plane_t *primary;
+
+	int ret = 0;
+
+	igt_skip_on(data->gen < 9);
+	igt_skip_on(pipe >= data->display.n_pipes);
+
+	igt_output_set_pipe(output, pipe);
+
+	gen9_test_init(&test, output, pipe);
+
+	primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
+
+	/* Start with a full-screen primary plane */
+	igt_plane_set_fb(primary, &test.biggreen_fb);
+	igt_display_commit2(&data->display, COMMIT_LEGACY);
+
+	/* Set primary to windowed size/position */
+	igt_plane_set_fb(primary, &test.smallblue_fb);
+	igt_plane_set_position(primary, test.x, test.y);
+	igt_plane_set_size(primary, test.w, test.h);
+	igt_display_commit2(&data->display, COMMIT_UNIVERSAL);
+
+	/*
+	 * SetPlane update to another framebuffer of the same size
+	 * should succeed
+	 */
+	igt_plane_set_fb(primary, &test.smallred_fb);
+	igt_plane_set_position(primary, test.x, test.y);
+	igt_plane_set_size(primary, test.w, test.h);
+	igt_display_commit2(&data->display, COMMIT_UNIVERSAL);
+
+	/* PageFlip should also succeed */
+	ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id,
+			      test.smallblue_fb.fb_id, 0, NULL);
+	igt_assert_eq(ret, 0);
+
+	igt_plane_set_fb(primary, NULL);
+	igt_plane_set_position(primary, 0, 0);
+	gen9_test_fini(&test, output);
+}
+
+static void
 run_tests_for_pipe(data_t *data, enum pipe pipe)
 {
 	igt_output_t *output;
@@ -660,6 +762,11 @@ run_tests_for_pipe(data_t *data, enum pipe pipe)
 		      kmstest_pipe_name(pipe))
 		for_each_connected_output(&data->display, output)
 			cursor_leak_test_pipe(data, pipe, output);
+
+	igt_subtest_f("universal-plane-gen9-features-pipe-%s",
+		      kmstest_pipe_name(pipe))
+		for_each_connected_output(&data->display, output)
+			gen9_test_pipe(data, pipe, output);
 }
 
 static data_t data;
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip
  2015-10-07  0:02 [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip Matt Roper
  2015-10-07  0:04 ` [PATCH i-g-t] kms_universal_plane: Add gen9-specific test Matt Roper
@ 2015-10-07 12:02 ` Ville Syrjälä
  1 sibling, 0 replies; 4+ messages in thread
From: Ville Syrjälä @ 2015-10-07 12:02 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Tue, Oct 06, 2015 at 05:02:47PM -0700, Matt Roper wrote:
> The legacy pageflip ioctl calls drm_crtc_check_viewport() to determine
> whether the framebuffer being flipped is big enough to fill the display
> it is being flipped to.  However some drivers support "windowing" of
> their primary planes (i.e., a primary plane that does not cover the
> entire CRTC dimensions); in such situations we can wind up rejecting
> valid pageflips of buffers that are smaller than the display mode, but
> still large enough to fill the entire primary plane.
> 
> What we really want to be comparing against for pageflips is the size of
> the primary plane, which can be found in crtc->primary->state for atomic
> drivers (and drivers in the process of transitioning to atomic).  There
> are no non-atomic drivers that support primary plane windowing at the
> moment, so we'll continue to use the current behavior of looking at the
> CRTC mode size on drivers that don't have a crtc->primary->state.  We'll
> also continue to use the existing logic for SetCrtc, which is the other
> callsite for drm_crtc_check_viewport(), since legacy modesets reprogram
> the primary plane and remove windowing.
> 
> Note that the existing code was checking a crtc->invert_dimensions field
> to determine whether the width/height of the mode needed to be swapped.
> A bonus of checking plane size is that the source width/height we get
> already take rotation into account so that check is no longer necessary
> when using the plane size.
> 
> Testcase: igt/universal-plane-gen9-features-pipe-#
> Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>  drivers/gpu/drm/drm_crtc.c | 87 +++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 71 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index e600a5f..35cd4dc 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -2534,9 +2534,76 @@ void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
>  }
>  EXPORT_SYMBOL(drm_crtc_get_hv_timing);
>  
> +static int check_viewport(int hdisplay,
> +			  int vdisplay,
> +			  int x,
> +			  int y,
> +			  bool invert_dimensions,
> +			  const struct drm_framebuffer *fb)
> +{
> +	if (invert_dimensions)
> +		swap(hdisplay, vdisplay);
> +
> +	if (hdisplay > fb->width ||
> +	    vdisplay > fb->height ||
> +	    x > fb->width - hdisplay ||
> +	    y > fb->height - vdisplay) {
> +		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
> +			      fb->width, fb->height, hdisplay, vdisplay, x, y,
> +			      invert_dimensions ? " (inverted)" : "");
> +		return -ENOSPC;
> +	}
> +
> +	return 0;
> +}

I think I'd rather pull the limit check code from the setplane path to a
separate function, and call that with the src coordinates derived from
either the plane state or the mode depending on the use case. That way
the invert_dimensions crap can stay only in the codepath that actually
needs it.

> +
> +/**
> + * drm_plane_check_viewport - Checks that a framebuffer is big enough for the
> + *     plane's viewport
> + * @plane: Plane that framebuffer will be displayed on
> + * @x: x panning
> + * @y: y panning
> + * @fb: framebuffer to check size of
> + *
> + * Atomic drivers (or transitioning drivers that support proper plane state)
> + * may call this function on any plane.  Non-atomic drivers may only call this
> + * for the primary plane while the CRTC is active (we'll assume that the
> + * primary plane covers the entire CRTC in that case).
> + */
> +int drm_plane_check_viewport(const struct drm_plane *plane,
> +			     int x,
> +			     int y,
> +			     const struct drm_framebuffer *fb)
> +
> +{
> +	struct drm_crtc *crtc = plane->crtc;
> +	int hdisplay, vdisplay;
> +
> +	if (WARN_ON(plane->state == NULL &&
> +		    plane->type != DRM_PLANE_TYPE_PRIMARY))
> +		return -EINVAL;
> +
> +	/*
> +	 * Non-atomic drivers may not have valid plane state to look at.  But
> +	 * those drivers also don't support windowing of the primary plane, so
> +	 * we can fall back to looking at the mode of the owning CRTC.
> +	 */
> +	if (plane->state) {
> +		hdisplay = plane->state->src_w >> 16;
> +		vdisplay = plane->state->src_h >> 16;

You shouldn't truncate these.

> +	} else if (WARN_ON(!crtc)) {
> +		hdisplay = vdisplay = 0;
> +	} else {
> +		drm_crtc_get_hv_timing(&crtc->mode, &hdisplay, &vdisplay);
> +	}
> +
> +	return check_viewport(hdisplay, vdisplay, x, y, false, fb);
> +}
> +EXPORT_SYMBOL(drm_plane_check_viewport);
> +
>  /**
>   * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
> - *     CRTC viewport
> + *     CRTC viewport when running in the specified mode
>   * @crtc: CRTC that framebuffer will be displayed on
>   * @x: x panning
>   * @y: y panning
> @@ -2553,20 +2620,8 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
>  
>  	drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
>  
> -	if (crtc->invert_dimensions)
> -		swap(hdisplay, vdisplay);
> -
> -	if (hdisplay > fb->width ||
> -	    vdisplay > fb->height ||
> -	    x > fb->width - hdisplay ||
> -	    y > fb->height - vdisplay) {
> -		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
> -			      fb->width, fb->height, hdisplay, vdisplay, x, y,
> -			      crtc->invert_dimensions ? " (inverted)" : "");
> -		return -ENOSPC;
> -	}
> -
> -	return 0;
> +	return check_viewport(hdisplay, vdisplay, x, y,
> +			      crtc->invert_dimensions, fb);
>  }
>  EXPORT_SYMBOL(drm_crtc_check_viewport);
>  
> @@ -5181,7 +5236,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
>  		goto out;
>  	}
>  
> -	ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
> +	ret = drm_plane_check_viewport(crtc->primary, crtc->x, crtc->y, fb);
>  	if (ret)
>  		goto out;
>  
> -- 
> 2.1.4

-- 
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] 4+ messages in thread

* [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip
@ 2015-10-07  0:02 Matt Roper
  0 siblings, 0 replies; 4+ messages in thread
From: Matt Roper @ 2015-10-07  0:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tvrtko Ursulin

The legacy pageflip ioctl calls drm_crtc_check_viewport() to determine
whether the framebuffer being flipped is big enough to fill the display
it is being flipped to.  However some drivers support "windowing" of
their primary planes (i.e., a primary plane that does not cover the
entire CRTC dimensions); in such situations we can wind up rejecting
valid pageflips of buffers that are smaller than the display mode, but
still large enough to fill the entire primary plane.

What we really want to be comparing against for pageflips is the size of
the primary plane, which can be found in crtc->primary->state for atomic
drivers (and drivers in the process of transitioning to atomic).  There
are no non-atomic drivers that support primary plane windowing at the
moment, so we'll continue to use the current behavior of looking at the
CRTC mode size on drivers that don't have a crtc->primary->state.  We'll
also continue to use the existing logic for SetCrtc, which is the other
callsite for drm_crtc_check_viewport(), since legacy modesets reprogram
the primary plane and remove windowing.

Note that the existing code was checking a crtc->invert_dimensions field
to determine whether the width/height of the mode needed to be swapped.
A bonus of checking plane size is that the source width/height we get
already take rotation into account so that check is no longer necessary
when using the plane size.

Testcase: igt/universal-plane-gen9-features-pipe-#
Reported-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/drm_crtc.c | 87 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e600a5f..35cd4dc 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2534,9 +2534,76 @@ void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
 }
 EXPORT_SYMBOL(drm_crtc_get_hv_timing);
 
+static int check_viewport(int hdisplay,
+			  int vdisplay,
+			  int x,
+			  int y,
+			  bool invert_dimensions,
+			  const struct drm_framebuffer *fb)
+{
+	if (invert_dimensions)
+		swap(hdisplay, vdisplay);
+
+	if (hdisplay > fb->width ||
+	    vdisplay > fb->height ||
+	    x > fb->width - hdisplay ||
+	    y > fb->height - vdisplay) {
+		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
+			      fb->width, fb->height, hdisplay, vdisplay, x, y,
+			      invert_dimensions ? " (inverted)" : "");
+		return -ENOSPC;
+	}
+
+	return 0;
+}
+
+/**
+ * drm_plane_check_viewport - Checks that a framebuffer is big enough for the
+ *     plane's viewport
+ * @plane: Plane that framebuffer will be displayed on
+ * @x: x panning
+ * @y: y panning
+ * @fb: framebuffer to check size of
+ *
+ * Atomic drivers (or transitioning drivers that support proper plane state)
+ * may call this function on any plane.  Non-atomic drivers may only call this
+ * for the primary plane while the CRTC is active (we'll assume that the
+ * primary plane covers the entire CRTC in that case).
+ */
+int drm_plane_check_viewport(const struct drm_plane *plane,
+			     int x,
+			     int y,
+			     const struct drm_framebuffer *fb)
+
+{
+	struct drm_crtc *crtc = plane->crtc;
+	int hdisplay, vdisplay;
+
+	if (WARN_ON(plane->state == NULL &&
+		    plane->type != DRM_PLANE_TYPE_PRIMARY))
+		return -EINVAL;
+
+	/*
+	 * Non-atomic drivers may not have valid plane state to look at.  But
+	 * those drivers also don't support windowing of the primary plane, so
+	 * we can fall back to looking at the mode of the owning CRTC.
+	 */
+	if (plane->state) {
+		hdisplay = plane->state->src_w >> 16;
+		vdisplay = plane->state->src_h >> 16;
+	} else if (WARN_ON(!crtc)) {
+		hdisplay = vdisplay = 0;
+	} else {
+		drm_crtc_get_hv_timing(&crtc->mode, &hdisplay, &vdisplay);
+	}
+
+	return check_viewport(hdisplay, vdisplay, x, y, false, fb);
+}
+EXPORT_SYMBOL(drm_plane_check_viewport);
+
 /**
  * drm_crtc_check_viewport - Checks that a framebuffer is big enough for the
- *     CRTC viewport
+ *     CRTC viewport when running in the specified mode
  * @crtc: CRTC that framebuffer will be displayed on
  * @x: x panning
  * @y: y panning
@@ -2553,20 +2620,8 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
 
 	drm_crtc_get_hv_timing(mode, &hdisplay, &vdisplay);
 
-	if (crtc->invert_dimensions)
-		swap(hdisplay, vdisplay);
-
-	if (hdisplay > fb->width ||
-	    vdisplay > fb->height ||
-	    x > fb->width - hdisplay ||
-	    y > fb->height - vdisplay) {
-		DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
-			      fb->width, fb->height, hdisplay, vdisplay, x, y,
-			      crtc->invert_dimensions ? " (inverted)" : "");
-		return -ENOSPC;
-	}
-
-	return 0;
+	return check_viewport(hdisplay, vdisplay, x, y,
+			      crtc->invert_dimensions, fb);
 }
 EXPORT_SYMBOL(drm_crtc_check_viewport);
 
@@ -5181,7 +5236,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 		goto out;
 	}
 
-	ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
+	ret = drm_plane_check_viewport(crtc->primary, crtc->x, crtc->y, fb);
 	if (ret)
 		goto out;
 
-- 
2.1.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-10-07 12:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-07  0:02 [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip Matt Roper
2015-10-07  0:04 ` [PATCH i-g-t] kms_universal_plane: Add gen9-specific test Matt Roper
2015-10-07 12:02 ` [PATCH] drm: Check fb against plane size rather than CRTC mode for pageflip Ville Syrjälä
2015-10-07  0:02 Matt Roper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.