drm: Add a new plane property to send damage during plane update
Subsystems (4)
PATCH 1/18 drm: Add a new plane property to send damage during plane update
From: Lukasz Spintzyk <[email protected]>
FB_DAMAGE_CLIPS is an optional plane property to mark damaged regions on the plane in framebuffer coordinates of the framebuffer attached to the plane.
The layout of blob data is simply an array of "struct drm_mode_rect". Unlike plane src coordinates, damage clips are not in 16.16 fixed point. As plane src in framebuffer cannot be negative so are damage clips. In damage clip, x1/y1 are inclusive and x2/y2 are exclusive.
This patch also exports the kernel internal drm_rect to userspace as drm_mode_rect. This is because "struct drm_clip_rect" is not sufficient to represent damage for current plane size.
Driver which are interested in enabling FB_DAMAGE_CLIPS property for a plane should enable this property using drm_plane_enable_damage_clips.
v2:
- Input validation on damage clips against framebuffer size.
- Doc update, other minor changes.
--- Documentation/gpu/drm-kms.rst | 12 +++++ drivers/gpu/drm/Makefile | 3 +- drivers/gpu/drm/drm_atomic.c | 22 ++++++++ drivers/gpu/drm/drm_atomic_helper.c | 3 ++ drivers/gpu/drm/drm_atomic_uapi.c | 13 +++++ drivers/gpu/drm/drm_damage_helper.c | 83 +++++++++++++++++++++++++++++ drivers/gpu/drm/drm_mode_config.c | 6 +++ include/drm/drm_damage_helper.h | 39 ++++++++++++++ include/drm/drm_mode_config.h | 9 ++++ include/drm/drm_plane.h | 40 ++++++++++++++ include/uapi/drm/drm_mode.h | 19 +++++++ 11 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/drm_damage_helper.c create mode 100644 include/drm/drm_damage_helper.h
Documentation/gpu/drm-kms.rst +12 -0
@@ -554,6 +554,18 @@ Plane Composition Properties .. kernel-doc:: drivers/gpu/drm/drm_blend.c :export: +FB_DAMAGE_CLIPS +~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c + :export: + +.. kernel-doc:: include/drm/drm_damage_helper.h + :internal: + Color Management Properties ---------------------------
drivers/gpu/drm/Makefile +2 -1
@@ -36,7 +36,8 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ drm_simple_kms_helper.o drm_modeset_helper.o \ - drm_scdc_helper.o drm_gem_framebuffer_helper.o + drm_scdc_helper.o drm_gem_framebuffer_helper.o \ + drm_damage_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
drivers/gpu/drm/drm_atomic.c +22 -0
@@ -516,6 +516,8 @@ static int drm_atomic_plane_check(struct drm_plane *plane, struct drm_plane_state *state) {unsigned int fb_width, fb_height; +struct drm_mode_rect *clips; +uint32_t num_clips;int ret;/* either *both* CRTC and FB must be set, or neither */
@@ -585,6 +587,26 @@ static int drm_atomic_plane_check(struct drm_plane *plane,return -ENOSPC ; } + clips =drm_plane_get_damage_clips (state); + num_clips =drm_plane_get_damage_clips_count (state); + +/* Make sure damage clips are valid and inside the fb. */ +while (num_clips >0 ) { +if (clips->x1 >= clips->x2 || + clips->y1 >= clips->y2 || + clips->x1 <0 || + clips->y1 <0 || + clips->x2 > fb_width || + clips->y2 > fb_height) { +DRM_DEBUG_ATOMIC ("[PLANE:%d:%s] invalid damage clip %d %d %d %d\n" , + plane->base.id, plane->name, clips->x1, + clips->y1, clips->x2, clips->y2); +return -EINVAL ; + } + clips++; + num_clips--; + } +if (plane_switching_crtc (state->state, plane, state)) {DRM_DEBUG_ATOMIC ("[PLANE:%d:%s] switching CRTC directly\n" , plane->base.id, plane->name);
drivers/gpu/drm/drm_atomic_helper.c +3 -0
@@ -3615,6 +3615,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->fence =NULL ; state->commit =NULL ; + state->fb_damage_clips =NULL ; }EXPORT_SYMBOL (__drm_atomic_helper_plane_duplicate_state);
@@ -3659,6 +3660,8 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)if (state->commit)drm_crtc_commit_put (state->commit); + +drm_property_blob_put (state->fb_damage_clips); }EXPORT_SYMBOL (__drm_atomic_helper_plane_destroy_state);
drivers/gpu/drm/drm_atomic_uapi.c +13 -0
@@ -513,6 +513,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, {struct drm_device *dev = plane->dev;struct drm_mode_config *config = &dev->mode_config; +bool replaced = false; +int ret;if (property == config->prop_fb_id) {struct drm_framebuffer *fb =drm_framebuffer_lookup (dev,NULL , val);
@@ -566,6 +568,14 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->color_encoding = val; }else if (property == plane->color_range_property) { state->color_range = val; + }else if (property == config->prop_fb_damage_clips) { + ret =drm_atomic_replace_property_blob_from_id (dev, + &state->fb_damage_clips, + val, +-1 , +sizeof (struct drm_rect ), + &replaced); +return ret; }else if (plane->funcs->atomic_set_property) {return plane->funcs->atomic_set_property (plane, state, property, val);
@@ -621,6 +631,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->color_encoding; }else if (property == plane->color_range_property) { *val = state->color_range; + }else if (property == config->prop_fb_damage_clips) { + *val = (state->fb_damage_clips) ? + state->fb_damage_clips->base.id :0 ; }else if (plane->funcs->atomic_get_property) {return plane->funcs->atomic_get_property (plane, state, property, val); }else {
drivers/gpu/drm/drm_damage_helper.c new file +83 -0
83 lines not on this page · raw message
drivers/gpu/drm/drm_mode_config.c +6 -0
@@ -297,6 +297,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)return -ENOMEM ; dev->mode_config.prop_crtc_id = prop; + prop =drm_property_create (dev,DRM_MODE_PROP_BLOB ,"FB_DAMAGE_CLIPS" , +0 ); +if (!prop) +return -ENOMEM ; + dev->mode_config.prop_fb_damage_clips = prop; + prop =drm_property_create_bool (dev,DRM_MODE_PROP_ATOMIC ,"ACTIVE" );if (!prop)
include/drm/drm_damage_helper.h new file +39 -0
@@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/************************************************************************** +* +* Copyright (c) 2018 VMware, Inc., Palo Alto, CA., USA +* All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sub license, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice (including the +* next paragraph) shall be included in all copies or substantial portions +* of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* USE OR OTHER DEALINGS IN THE SOFTWARE. +* +* Authors: +* Deepak Rawat <[email protected]> +* +**************************************************************************/ + +#ifndef DRM_DAMAGE_HELPER_H_ +#define DRM_DAMAGE_HELPER_H_ + +#include <drm/drm_atomic_helper.h> + +void drm_plane_enable_fb_damage_clips (struct drm_plane *plane); + +#endif
include/drm/drm_mode_config.h +9 -0
@@ -627,6 +627,15 @@ struct drm_mode_config {* &drm_crtc. */ struct drm_property *prop_crtc_id; +/** +* @prop_fb_damage_clips: Optional plane property to mark damaged +* regions on the plane in framebuffer coordinates of the framebuffer +* attached to the plane. +* +* The layout of blob data is simply an array of &drm_mode_rect. Unlike +* plane src coordinates, damage clips are not in 16.16 fixed point. +*/ +struct drm_property *prop_fb_damage_clips;/** * @prop_active: Default atomic CRTC property to control the active * state, which is the simplified implementation for DPMS in atomic
include/drm/drm_plane.h +40 -0
@@ -173,6 +173,16 @@ struct drm_plane_state {*/ enum drm_color_range color_range; +/** +* @fb_damage_clips: +* +* Blob representing damage (area in plane framebuffer that changed +* since last plane update) as an array of &drm_mode_rect in framebuffer +* coodinates of the attached framebuffer. Note that unlike plane src, +* damage clips are not in 16.16 fixed point. +*/ +struct drm_property_blob *fb_damage_clips; +/** @src: clipped source coordinates of the plane (in 16.16) */ /** @dst: clipped destination coordinates of the plane */ struct drm_rect src, dst;
@@ -798,5 +808,35 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev,#define drm_for_each_plane (plane, dev) \ list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) +/** +* drm_plane_get_damage_clips_count - Returns damage clips count. +* @state: Plane state. +* +* Simple helper to get the number of &drm_mode_rect clips set by user-space +* during plane update. +* +* Returns: Number of clips in plane fb_damage_clips blob property. +*/ +static inline unsigned int +drm_plane_get_damage_clips_count (const struct drm_plane_state *state) +{ +return (state && state->fb_damage_clips) ? + state->fb_damage_clips->length/sizeof (struct drm_mode_rect ) :0 ; +} + +/** +* drm_plane_get_damage_clips - Returns damage clips. +* @state: Plane state. +* +* Note that this function returns uapi type &drm_mode_rect. +* +* Returns: Damage clips in plane fb_damage_clips blob property. +*/ +static inline struct drm_mode_rect * +drm_plane_get_damage_clips (const struct drm_plane_state *state) +{ +return (struct drm_mode_rect *)((state && state->fb_damage_clips) ? + state->fb_damage_clips->data :NULL ); +}#endif
include/uapi/drm/drm_mode.h +19 -0
@@ -888,6 +888,25 @@ struct drm_mode_revoke_lease {__u32 lessee_id; }; +/** +* struct drm_mode_rect - Two dimensional rectangle. +* @x1: Horizontal starting coordinate (inclusive). +* @y1: Vertical starting coordinate (inclusive). +* @x2: Horizontal ending coordinate (exclusive). +* @y2: Vertical ending coordinate (exclusive). +* +* With drm subsystem using struct drm_rect to manage rectangular area this +* export it to user-space. +* +* Currently used by drm_mode_atomic blob property FB_DAMAGE_CLIPS. +*/ +struct drm_mode_rect { +__s32 x1; +__s32 y1; +__s32 x2; +__s32 y2; +}; +#if defined(__cplusplus) }#endif
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/18 drm: Add a new helper to validate damage during atomic_check
This helper function makes sure that damage from plane state is discarded for full modeset cycle. For some reason, which makes damage irrelevant, driver might want to do a full plane update for e.g. full modeset. Such cases must be checked here.
Note: In the previous version of the patch the name was clear damage. IMO the new name check_plane_damage() make more sense as this function really will be validating if need to discard damage.
--- drivers/gpu/drm/drm_atomic_helper.c | 3 +++ drivers/gpu/drm/drm_damage_helper.c | 38 +++++++++++++++++++++++++++++ include/drm/drm_damage_helper.h | 2 ++ 3 files changed, 43 insertions(+)
drivers/gpu/drm/drm_atomic_helper.c +3 -0
@@ -32,6 +32,7 @@#include <drm/drm_crtc_helper.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_writeback.h> +#include <drm/drm_damage_helper.h> #include <linux/dma-fence.h> #include "drm_crtc_helper_internal.h"
@@ -828,6 +829,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev,drm_atomic_helper_plane_changed (state, old_plane_state, new_plane_state, plane); +drm_atomic_helper_check_plane_damage (state, new_plane_state); +if (!funcs || !funcs->atomic_check)continue ;
drivers/gpu/drm/drm_damage_helper.c +38 -0
@@ -29,6 +29,7 @@* **************************************************************************/ +#include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> /**
@@ -81,3 +82,40 @@ void drm_plane_enable_fb_damage_clips(struct drm_plane *plane) 0); }EXPORT_SYMBOL (drm_plane_enable_fb_damage_clips); + +/** +* drm_atomic_helper_check_plane_damage - Verify plane damage on atomic_check. +* @state: The driver state object. +* @plane_state: Plane state for which to verify damage. +* +* This helper function makes sure that damage from plane state is discarded +* for full modeset cycle. For some reason, which makes damage irrelevant, +* driver might want to do a full plane update for e.g. full modeset. Such +* cases must be checked here. Note that NULL &drm_plane_state.fb_damage_clips +* in plane state means that full update should happen. It also ensue helper +* iterator to return &drm_plane_state.src as damage. +* +* Currently this helper discard damage during full modeset only. This is +* because, presently only vmwgfx exposes damage interface, which need full +* plane update during full modeset only. As more driver add damage support, +* should any state change need full plane update, must be added here. +*/ +void drm_atomic_helper_check_plane_damage (struct drm_atomic_state *state, +struct drm_plane_state *plane_state) +{ +struct drm_crtc_state *crtc_state; + +if (plane_state->crtc) { + crtc_state =drm_atomic_get_new_crtc_state (state, + plane_state->crtc); + +if (WARN_ON (!crtc_state)) +return ; + +if (drm_atomic_crtc_needs_modeset (crtc_state)) { +drm_property_blob_put (plane_state->fb_damage_clips); + plane_state->fb_damage_clips =NULL ; + } + } +} +EXPORT_SYMBOL (drm_atomic_helper_check_plane_damage);
include/drm/drm_damage_helper.h +2 -0
@@ -35,5 +35,7 @@#include <drm/drm_atomic_helper.h> void drm_plane_enable_fb_damage_clips (struct drm_plane *plane); +void drm_atomic_helper_check_plane_damage (struct drm_atomic_state *state, +struct drm_plane_state *plane_state);#endif
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 3/18 drm: Add helper iterator functions for plane fb_damage_clips blob
In reply to Deepak RawatWith fb_damage_clips blob property in drm_plane_state, this patch adds helper iterator to traverse the damage clips that lie inside plane src. Iterator will return full plane src as damage in case need full plane update or damage is not specified.
v2:
- Plane src clipping correction
- Handle no plane update case in iter_next
--- drivers/gpu/drm/drm_damage_helper.c | 91 +++++++++++++++++++++++++++++ include/drm/drm_damage_helper.h | 54 +++++++++++++++++ include/drm/drm_plane.h | 4 +- 3 files changed, 148 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_damage_helper.c +91 -0
@@ -65,6 +65,9 @@* * Drivers that are interested in damage interface for plane should enable * FB_DAMAGE_CLIPS property by calling drm_plane_enable_fb_damage_clips(). +* Drivers implementing damage can use drm_atomic_helper_damage_iter_init() and +* drm_atomic_helper_damage_iter_next() helper iterator function to get damage +* rectangles clipped to &drm_plane_state.src. */ /**
@@ -119,3 +122,91 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, } }EXPORT_SYMBOL (drm_atomic_helper_check_plane_damage); + +/** +* drm_atomic_helper_damage_iter_init - Initialize the damage iterator. +* @iter: The iterator to initialize. +* @old_state: Old plane state for validation. +* @new_state: Plane state from which to iterate the damage clips. +* +* Initialize an iterator, which clips plane damage +* &drm_plane_state.fb_damage_clips to plane &drm_plane_state.src. This iterator +* returns full plane src in case damage is not present because either +* user-space didn't sent or driver discarded it (it want to do full plane +* update). Currently this iterator returns full plane src in case plane src +* changed but that can be changed in future to return damage. +* +* For the case when plane is not visible or plane update should not happen the +* first call to iter_next will return false. Note that this helper use clipped +* &drm_plane_state.src, so driver calling this helper should have called +* drm_atomic_helper_check_plane_state() earlier. +*/ +void +drm_atomic_helper_damage_iter_init (struct drm_atomic_helper_damage_iter *iter, +const struct drm_plane_state *old_state, +const struct drm_plane_state *state) +{ +memset (iter,0 ,sizeof (*iter)); + +if (!state || !state->crtc || !state->fb || !state->visible) { +return ; + } + + iter->clips =drm_helper_get_plane_damage_clips (state); + iter->num_clips =drm_plane_get_damage_clips_count (state); + +/* Round down for x1/y1 and round up for x2/y2 to catch all pixels */ + iter->plane_src.x1 = state->src.x1 >>16 ; + iter->plane_src.y1 = state->src.y1 >>16 ; + iter->plane_src.x2 = (state->src.x2 >>16 ) + !!(state->src.x2 &0xFFFF ); + iter->plane_src.y2 = (state->src.y2 >>16 ) + !!(state->src.y2 &0xFFFF ); + +if (!iter->clips || !drm_rect_equals (&state->src, &old_state->src)) { + iter->clips =0 ; + iter->num_clips =0 ; + iter->full_update = true; + } +} +EXPORT_SYMBOL (drm_atomic_helper_damage_iter_init); + +/** +* drm_atomic_helper_damage_iter_next - Advance the damage iterator. +* @iter: The iterator to advance. +* @rect: Return a rectangle in fb coordinate clipped to plane src. +* +* Since plane src is in 16.16 fixed point and damage clips are whole number, +* this iterator round off clips that intersect with plane src. Round down for +* x1/y1 and round up for x2/y2 for the intersected coordinate. Similar rounding +* off for full plane src, in case it's returned as damage. This iterator will +* skip damage clips outside of plane src. +* +* Returns: True if the output is valid, false if reached the end. +* +* If the first call to iterator next returns false then it means no need to +* update the plane. +*/ +bool +drm_atomic_helper_damage_iter_next (struct drm_atomic_helper_damage_iter *iter, +struct drm_rect *rect) +{ +bool ret = false; + +if (iter->full_update) { + *rect = iter->plane_src; + iter->full_update = false; +return true; + } + +while (iter->curr_clip < iter->num_clips) { + *rect = iter->clips[iter->curr_clip]; + iter->curr_clip++; + +if (drm_rect_intersect (rect, &iter->plane_src)) { + ret = true; +break ; + } + } + +return ret; +} +EXPORT_SYMBOL (drm_atomic_helper_damage_iter_next);
include/drm/drm_damage_helper.h +54 -0
62 lines not on this page · raw message
include/drm/drm_plane.h +3 -1
@@ -828,7 +828,9 @@ drm_plane_get_damage_clips_count(const struct drm_plane_state *state)* drm_plane_get_damage_clips - Returns damage clips. * @state: Plane state. * -* Note that this function returns uapi type &drm_mode_rect. +* Note that this function returns uapi type &drm_mode_rect. Drivers might +* instead be interested in internal &drm_rect which can be obtained by calling +* drm_helper_get_plane_damage_clips(). * * Returns: Damage clips in plane fb_damage_clips blob property. */
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 4/18 drm/selftest: Add drm damage helper selftest
In reply to Deepak RawatSelftest for drm damage helper iterator functions.
--- drivers/gpu/drm/selftests/Makefile | 3 +- .../selftests/drm_damage_helper_selftests.h | 22 + .../drm/selftests/test-drm_damage_helper.c | 844 ++++++++++++++++++ 3 files changed, 868 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/selftests/drm_damage_helper_selftests.h create mode 100644 drivers/gpu/drm/selftests/test-drm_damage_helper.c
drivers/gpu/drm/selftests/Makefile +2 -1
@@ -1 +1,2 @@ -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o \ + test-drm_damage_helper.o
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +22 -0
@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +selftest(damage_iter_no_damage, igt_damage_iter_no_damage) +selftest(damage_iter_no_damage_fractional_src, igt_damage_iter_no_damage_fractional_src) +selftest(damage_iter_no_damage_src_moved, igt_damage_iter_no_damage_src_moved) +selftest(damage_iter_no_damage_fractional_src_moved, igt_damage_iter_no_damage_fractional_src_moved) +selftest(damage_iter_no_damage_not_visible, igt_damage_iter_no_damage_not_visible) +selftest(damage_iter_no_damage_no_crtc, igt_damage_iter_no_damage_no_crtc) +selftest(damage_iter_no_damage_no_fb, igt_damage_iter_no_damage_no_fb) +selftest(damage_iter_simple_damage, igt_damage_iter_simple_damage) +selftest(damage_iter_single_damage, igt_damage_iter_single_damage) +selftest(damage_iter_single_damage_intersect_src, igt_damage_iter_single_damage_intersect_src) +selftest(damage_iter_single_damage_outside_src, igt_damage_iter_single_damage_outside_src) +selftest(damage_iter_single_damage_fractional_src, igt_damage_iter_single_damage_fractional_src) +selftest(damage_iter_single_damage_intersect_fractional_src, igt_damage_iter_single_damage_intersect_fractional_src) +selftest(damage_iter_single_damage_outside_fractional_src, igt_damage_iter_single_damage_outside_fractional_src) +selftest(damage_iter_single_damage_src_moved, igt_damage_iter_single_damage_src_moved) +selftest(damage_iter_single_damage_fractional_src_moved, igt_damage_iter_single_damage_fractional_src_moved) +selftest(damage_iter_damage, igt_damage_iter_damage) +selftest(damage_iter_damage_one_intersect, igt_damage_iter_damage_one_intersect) +selftest(damage_iter_damage_one_outside, igt_damage_iter_damage_one_outside) +selftest(damage_iter_damage_src_moved, igt_damage_iter_damage_src_moved) +selftest (damage_iter_damage_not_visible, igt_damage_iter_damage_not_visible)
drivers/gpu/drm/selftests/test-drm_damage_helper.c new file +844 -0
844 lines not on this page · raw message
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 04/18] drm/selftest: Add drm damage helper selftest
Quoted 19 lines · Deepak Rawat
Selftest for drm damage helper iterator functions.
Cc Daniel Vetter <[email protected]>Cc Pekka Paalanen <[email protected]>Signed-off-by Deepak Rawat <[email protected]>--- drivers/gpu/drm/selftests/Makefile | 3 +- .../selftests/drm_damage_helper_selftests.h | 22 + .../drm/selftests/test-drm_damage_helper.c | 844 ++++++++++++++++++ 3 files changed, 868 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/selftests/drm_damage_helper_selftests.h create mode 100644 drivers/gpu/drm/selftests/test-drm_damage_helper.cdrivers/gpu/drm/selftests/Makefile +0
-0
drivers/gpu/drm/selftests/Makefile line 2
Quoted 3 lines
drivers/gpu/drm/selftests/Makefile +2
-1@@ -1 +1,2 @@ -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o \ + test-drm_damage_helper.o
I think it'd be better to add the damage tests to the existing drm-helper selftest (but as a separate file ofc), using the
test-drm-helper-$(CONFIG_DRM_DEBUG_SELFTEST) +=
syntax. That avoids having to write yet another igt wrapper test for this. Also, if you cc [email protected] with this our CI will run the new tests for you automatically.
Cheers, Daniel
Quoted 881 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +22
-0@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +selftest(damage_iter_no_damage, igt_damage_iter_no_damage) +selftest(damage_iter_no_damage_fractional_src, igt_damage_iter_no_damage_fractional_src) +selftest(damage_iter_no_damage_src_moved, igt_damage_iter_no_damage_src_moved) +selftest(damage_iter_no_damage_fractional_src_moved, igt_damage_iter_no_damage_fractional_src_moved) +selftest(damage_iter_no_damage_not_visible, igt_damage_iter_no_damage_not_visible) +selftest(damage_iter_no_damage_no_crtc, igt_damage_iter_no_damage_no_crtc) +selftest(damage_iter_no_damage_no_fb, igt_damage_iter_no_damage_no_fb) +selftest(damage_iter_simple_damage, igt_damage_iter_simple_damage) +selftest(damage_iter_single_damage, igt_damage_iter_single_damage) +selftest(damage_iter_single_damage_intersect_src, igt_damage_iter_single_damage_intersect_src) +selftest(damage_iter_single_damage_outside_src, igt_damage_iter_single_damage_outside_src) +selftest(damage_iter_single_damage_fractional_src, igt_damage_iter_single_damage_fractional_src) +selftest(damage_iter_single_damage_intersect_fractional_src, igt_damage_iter_single_damage_intersect_fractional_src) +selftest(damage_iter_single_damage_outside_fractional_src, igt_damage_iter_single_damage_outside_fractional_src) +selftest(damage_iter_single_damage_src_moved, igt_damage_iter_single_damage_src_moved) +selftest(damage_iter_single_damage_fractional_src_moved, igt_damage_iter_single_damage_fractional_src_moved) +selftest(damage_iter_damage, igt_damage_iter_damage) +selftest(damage_iter_damage_one_intersect, igt_damage_iter_damage_one_intersect) +selftest(damage_iter_damage_one_outside, igt_damage_iter_damage_one_outside) +selftest(damage_iter_damage_src_moved, igt_damage_iter_damage_src_moved) +selftest (damage_iter_damage_not_visible, igt_damage_iter_damage_not_visible)drivers/gpu/drm/selftests/test-drm_damage_helper.c new file +844
-0@@ -0,0 +1,844 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Test case for drm_damage_helper functions +*/ + +#define pr_fmt (fmt) "drm_damage_helper: " fmt + +#include <linux/module.h> +#include <drm/drm_damage_helper.h> + +#define TESTS "drm_damage_helper_selftests.h" +#include "drm_selftest.h" + +#define FAIL (test, msg, ...) \ + do { \ + if (test) { \ + pr_err("%s/%u: " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + return -EINVAL; \ + } \ + } while (0) + +#define FAIL_ON (x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") + +static void set_plane_src (struct drm_plane_state *state,int x1,int y1,int x2, +int y2) +{ + state->src.x1 = x1; + state->src.y1 = y1; + state->src.x2 = x2; + state->src.y2 = y2; +} + +static void set_damage_clip (struct drm_mode_rect *r,int x1,int y1,int x2, +int y2) +{ + r->x1 = x1; + r->y1 = y1; + r->x2 = x2; + r->y2 = y2; +} + +static void set_damage_blob (struct drm_property_blob *damage_blob, +struct drm_mode_rect *r,uint32_t size) +{ + damage_blob->length = size; + damage_blob->data = r; +} + +static void set_plane_damage (struct drm_plane_state *state, +struct drm_property_blob *damage_blob) +{ + state->fb_damage_clips = damage_blob; +} + +static bool check_damage_clip (struct drm_plane_state *state,struct drm_rect *r, +int x1,int y1,int x2,int y2) +{ +/* +* Round down x1/y1 and round up x2/y2. This is because damage is not in +* 16.16 fixed point so to catch all pixels. +*/ +int src_x1 = state->src.x1 >>16 ; +int src_y1 = state->src.y1 >>16 ; +int src_x2 = (state->src.x2 >>16 ) + !!(state->src.x2 &0xFFFF ); +int src_y2 = (state->src.y2 >>16 ) + !!(state->src.y2 &0xFFFF ); + +if (x1 >= x2 || y1 >= y2) { +pr_err ("Cannot have damage clip with no dimention.\n" ); +return false; + } + +if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) { +pr_err ("Damage cannot be outside rounded plane src.\n" ); +return false; + } + +if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) { +pr_err ("Damage = %d %d %d %d\n" , r->x1, r->y1, r->x2, r->y2); +return false; + } + +return true; +} + +static int igt_damage_iter_no_damage (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src same as fb size. */ +set_plane_src (&old_state,0 ,0 , fb.width <<16 , fb.height <<16 ); +set_plane_src (&state,0 ,0 , fb.width <<16 , fb.height <<16 ); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,0 ,0 ,2048 ,2048 )); + +return 0 ; +} + +static int igt_damage_iter_no_damage_fractional_src (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src has fractional part. */ +set_plane_src (&old_state,0x3fffe ,0x3fffe , +0x3fffe + (1024 <<16 ),0x3fffe + (768 <<16 )); +set_plane_src (&state,0x3fffe ,0x3fffe , +0x3fffe + (1024 <<16 ),0x3fffe + (768 <<16 )); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return rounded off plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,3 ,3 ,1028 ,772 )); + +return 0 ; +} + +static int igt_damage_iter_no_damage_src_moved (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src moved since old plane state. */ +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,10 <<16 ,10 <<16 , + (10 +1024 ) <<16 , (10 +768 ) <<16 ); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,10 ,10 ,1034 ,778 )); + +return 0 ; +} + +static int igt_damage_iter_no_damage_fractional_src_moved (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src has fractional part and it moved since old plane state. */ +set_plane_src (&old_state,0x3fffe ,0x3fffe , +0x3fffe + (1024 <<16 ),0x3fffe + (768 <<16 )); +set_plane_src (&state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,4 ,4 ,1029 ,773 )); + +return 0 ; +} + +static int igt_damage_iter_no_damage_not_visible (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = false, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=0 ,"Should have no damage." ); + +return 0 ; +} + +static int igt_damage_iter_no_damage_no_crtc (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =0 , + .fb = &fb, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=0 ,"Should have no damage." ); + +return 0 ; +} + +static int igt_damage_iter_no_damage_no_fb (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb =0 , + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=0 ,"Should have no damage." ); + +return 0 ; +} + +static int igt_damage_iter_simple_damage (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +/* Damage set to plane src */ +set_damage_clip (&damage,0 ,0 ,1024 ,768 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return damage when set." ); +FAIL_ON (!check_damage_clip (&state, &clip,0 ,0 ,1024 ,768 )); + +return 0 ; +} + +static int igt_damage_iter_single_damage (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_damage_clip (&damage,256 ,192 ,768 ,576 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return damage when set." ); +FAIL_ON (!check_damage_clip (&state, &clip,256 ,192 ,768 ,576 )); + +return 0 ; +} + +static int igt_damage_iter_single_damage_intersect_src (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +/* Damage intersect with plane src. */ +set_damage_clip (&damage,256 ,192 ,1360 ,768 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return damage clipped to src." ); +FAIL_ON (!check_damage_clip (&state, &clip,256 ,192 ,1024 ,768 )); + +return 0 ; +} + +static int igt_damage_iter_single_damage_outside_src (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +/* Damage clip outside plane src */ +set_damage_clip (&damage,1360 ,1360 ,1380 ,1380 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=0 ,"Should have no damage." ); + +return 0 ; +} + +static int igt_damage_iter_single_damage_fractional_src (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src has fractional part. */ +set_plane_src (&old_state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_plane_src (&state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_damage_clip (&damage,10 ,10 ,256 ,330 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return damage when set." ); +FAIL_ON (!check_damage_clip (&state, &clip,10 ,10 ,256 ,330 )); + +return 0 ; +} + +static int igt_damage_iter_single_damage_intersect_fractional_src (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src has fractional part. */ +set_plane_src (&old_state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_plane_src (&state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +/* Damage intersect with plane src. */ +set_damage_clip (&damage,10 ,1 ,1360 ,330 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return damage clipped to rounded off src." ); +FAIL_ON (!check_damage_clip (&state, &clip,10 ,4 ,1029 ,330 )); + +return 0 ; +} + +static int igt_damage_iter_single_damage_outside_fractional_src (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src has fractional part. */ +set_plane_src (&old_state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_plane_src (&state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +/* Damage clip outside plane src */ +set_damage_clip (&damage,1360 ,1360 ,1380 ,1380 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=0 ,"Should have no damage." ); + +return 0 ; +} + +static int igt_damage_iter_single_damage_src_moved (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src moved since old plane state. */ +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,10 <<16 ,10 <<16 , + (10 +1024 ) <<16 , (10 +768 ) <<16 ); +set_damage_clip (&damage,20 ,30 ,256 ,256 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,10 ,10 ,1034 ,778 )); + +return 0 ; +} + +static int igt_damage_iter_single_damage_fractional_src_moved (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +/* Plane src with fractional part moved since old plane state. */ +set_plane_src (&old_state,0x3fffe ,0x3fffe , +0x3fffe + (1024 <<16 ),0x3fffe + (768 <<16 )); +set_plane_src (&state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +/* Damage intersect with plane src. */ +set_damage_clip (&damage,20 ,30 ,1360 ,256 ); +set_damage_blob (&damage_blob, &damage,sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return rounded off plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,4 ,4 ,1029 ,773 )); + +return 0 ; +} + +static int igt_damage_iter_damage (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage[2 ]; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +/* 2 damage clips. */ +set_damage_clip (&damage[0 ],20 ,30 ,200 ,180 ); +set_damage_clip (&damage[1 ],240 ,200 ,280 ,250 ); +set_damage_blob (&damage_blob, &damage[0 ],sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) { +if (num_hits ==0 ) +FAIL_ON (!check_damage_clip (&state, &clip,20 ,30 ,200 ,180 )); +if (num_hits ==1 ) +FAIL_ON (!check_damage_clip (&state, &clip,240 ,200 ,280 ,250 )); + num_hits++; + } + +FAIL (num_hits !=2 ,"Should return damage when set." ); + +return 0 ; +} + +static int igt_damage_iter_damage_one_intersect (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage[2 ]; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_plane_src (&state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +/* 2 damage clips, one intersect plane src. */ +set_damage_clip (&damage[0 ],20 ,30 ,200 ,180 ); +set_damage_clip (&damage[1 ],2 ,2 ,1360 ,1360 ); +set_damage_blob (&damage_blob, &damage[0 ],sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) { +if (num_hits ==0 ) +FAIL_ON (!check_damage_clip (&state, &clip,20 ,30 ,200 ,180 )); +if (num_hits ==1 ) +FAIL_ON (!check_damage_clip (&state, &clip,4 ,4 ,1029 ,773 )); + num_hits++; + } + +FAIL (num_hits !=2 ,"Should return damage when set." ); + +return 0 ; +} + +static int igt_damage_iter_damage_one_outside (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage[2 ]; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0 ,0 ,1024 <<16 ,768 <<16 ); +set_plane_src (&state,0 ,0 ,1024 <<16 ,768 <<16 ); +/* 2 damage clips, one outside plane src. */ +set_damage_clip (&damage[0 ],1360 ,1360 ,1380 ,1380 ); +set_damage_clip (&damage[1 ],240 ,200 ,280 ,250 ); +set_damage_blob (&damage_blob, &damage[0 ],sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return damage when set." ); +FAIL_ON (!check_damage_clip (&state, &clip,240 ,200 ,280 ,250 )); + +return 0 ; +} + +static int igt_damage_iter_damage_src_moved (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage[2 ]; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = true, + }; + +set_plane_src (&old_state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_plane_src (&state,0x3fffe ,0x3fffe , +0x3fffe + (1024 <<16 ),0x3fffe + (768 <<16 )); +/* 2 damage clips, one outside plane src. */ +set_damage_clip (&damage[0 ],1360 ,1360 ,1380 ,1380 ); +set_damage_clip (&damage[1 ],240 ,200 ,280 ,250 ); +set_damage_blob (&damage_blob, &damage[0 ],sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=1 ,"Should return round off plane src as damage." ); +FAIL_ON (!check_damage_clip (&state, &clip,3 ,3 ,1028 ,772 )); + +return 0 ; +} + +static int igt_damage_iter_damage_not_visible (void *ignored) +{ +struct drm_atomic_helper_damage_iter iter; +struct drm_plane_state old_state; +struct drm_property_blob damage_blob; +struct drm_mode_rect damage[2 ]; +struct drm_rect clip; +uint32_t num_hits =0 ; + +struct drm_framebuffer fb = { + .width =2048 , + .height =2048 + }; + +struct drm_plane_state state = { + .crtc =ZERO_SIZE_PTR , + .fb = &fb, + .visible = false, + }; + +set_plane_src (&old_state,0x40002 ,0x40002 , +0x40002 + (1024 <<16 ),0x40002 + (768 <<16 )); +set_plane_src (&state,0x3fffe ,0x3fffe , +0x3fffe + (1024 <<16 ),0x3fffe + (768 <<16 )); +/* 2 damage clips, one outside plane src. */ +set_damage_clip (&damage[0 ],1360 ,1360 ,1380 ,1380 ); +set_damage_clip (&damage[1 ],240 ,200 ,280 ,250 ); +set_damage_blob (&damage_blob, &damage[0 ],sizeof (damage)); +set_plane_damage (&state, &damage_blob); +drm_atomic_helper_damage_iter_init (&iter, &old_state, &state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +FAIL (num_hits !=0 ,"Should not return any damage." ); + +return 0 ; +} + +#include "drm_selftest.c" + +static int __init test_drm_damage_helper_init (void ) +{ +int err; + + err =run_selftests (selftests,ARRAY_SIZE (selftests),NULL ); + +return err >0 ?0 : err; +} + +static void __exit test_drm_damage_helper_exit(void) +{ +} + +module_init (test_drm_damage_helper_init); +module_exit (test_drm_damage_helper_exit); + +MODULE_AUTHOR ("VMware Inc." ); +MODULE_LICENSE ("GPL" );Signature · 1 line
2.17.1
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
RE: [PATCH 04/18] drm/selftest: Add drm damage helper selftest
Quoted 19 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.hQuoted 1 line
create mode 100644 drivers/gpu/drm/selftests/test-
drm_damage_helper.cReview
Quoted 2 lines
(quoted diff) +0
-0b/drivers/gpu/drm/selftests/Makefile
drivers/gpu/drm/selftests/Makefile line 1
Quoted 5 lines
index
9fc349fa18e9..88ac216f5962100644drivers/gpu/drm/selftests/Makefile +0
-1@@ -1 +1,2 @@ -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o
drivers/gpu/drm/selftests/Makefile line 1
Quoted 1 line
drivers/gpu/drm/selftests/Makefile +1
-0+obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o \
drivers/gpu/drm/selftests/Makefile line 2
Quoted 1 line
drivers/gpu/drm/selftests/Makefile +1
-0+ test-drm_damage_helper.oI think it'd be better to add the damage tests to the existing drm-helper selftest (but as a separate file ofc), using the
Quoted 7 lines
test-drm-helper-$(CONFIG_DRM_DEBUG_SELFTEST) +=
syntax. That avoids having to write yet another igt wrapper test for this. Also, if you cc [email protected] with this our CI will run the new tests for you automatically.
Cheers, Daniel
Hi Daniel, thanks for the review.
It looks like adding the damage tests to existing drm-helper-selftest need either renaming the module name (test-drm-helper.ko) or change the filename of test-drm-helper.c. This is because now test-drm-helper.c and test-drm-damage-helper.c have to link together and kernel module is of same name which is causing circular dependency. Both of which looks overkill to me.
If it is alright with you can we have separate test module. I already had a patch to integrate the damage test module with igt.
Thanks,
Deepak
Quoted 43 lines
Review
Quoted 3 lines
(quoted diff) +0
-0
b/drivers/gpu/drm/selftests/drm_damage_helper_selftests.hdrivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 3
Quoted 8 lines
new file mode 100644
index 000000000000..3a1cbe05bef0drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +3
-0@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +selftest(damage_iter_no_damage, igt_damage_iter_no_damage) +selftest(damage_iter_no_damage_fractional_src,
igt_damage_iter_no_damage_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 4
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_src_moved,
igt_damage_iter_no_damage_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 5
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_fractional_src_moved,
igt_damage_iter_no_damage_fractional_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 6
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_not_visible,
igt_damage_iter_no_damage_not_visible)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 7
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_no_crtc,
igt_damage_iter_no_damage_no_crtc)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 8
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_no_fb,
igt_damage_iter_no_damage_no_fb)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 9
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_simple_damage,
igt_damage_iter_simple_damage)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 11
Quoted 2 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +2
-0+selftest(damage_iter_single_damage, igt_damage_iter_single_damage) +selftest(damage_iter_single_damage_intersect_src,
igt_damage_iter_single_damage_intersect_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 12
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_outside_src,
igt_damage_iter_single_damage_outside_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 13
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_fractional_src,
igt_damage_iter_single_damage_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 14
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_intersect_fractional_src,
igt_damage_iter_single_damage_intersect_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 15
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_outside_fractional_src,
igt_damage_iter_single_damage_outside_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 16
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_src_moved,
igt_damage_iter_single_damage_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 17
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_fractional_src_moved,
igt_damage_iter_single_damage_fractional_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 19
Quoted 2 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +2
-0+selftest(damage_iter_damage, igt_damage_iter_damage) +selftest(damage_iter_damage_one_intersect,
igt_damage_iter_damage_one_intersect)
Quoted 6 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 20
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_damage_one_outside,
igt_damage_iter_damage_one_outside)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 21
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_damage_src_moved,
igt_damage_iter_damage_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 22
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_damage_not_visible,
igt_damage_iter_damage_not_visible)
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 04/18] drm/selftest: Add drm damage helper selftest
Quoted 27 lines · Deepak Singh Rawat
Quoted 19 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.hQuoted 1 line
create mode 100644 drivers/gpu/drm/selftests/test-
drm_damage_helper.cReview
Quoted 2 lines
(quoted diff) +0
-0b/drivers/gpu/drm/selftests/Makefile
drivers/gpu/drm/selftests/Makefile line 1
Quoted 5 lines
index
9fc349fa18e9..88ac216f5962100644drivers/gpu/drm/selftests/Makefile +0
-1@@ -1 +1,2 @@ -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o
drivers/gpu/drm/selftests/Makefile line 1
Quoted 1 line
drivers/gpu/drm/selftests/Makefile +1
-0+obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm-helper.o \
drivers/gpu/drm/selftests/Makefile line 2
Quoted 1 line
drivers/gpu/drm/selftests/Makefile +1
-0+ test-drm_damage_helper.oI think it'd be better to add the damage tests to the existing drm-helper selftest (but as a separate file ofc), using the
Quoted 7 lines
test-drm-helper-$(CONFIG_DRM_DEBUG_SELFTEST) +=
syntax. That avoids having to write yet another igt wrapper test for this. Also, if you cc [email protected] with this our CI will run the new tests for you automatically.
Cheers, Daniel
Quoted 7 lines
Hi Daniel, thanks for the review.
It looks like adding the damage tests to existing drm-helper-selftest need either renaming the module name (test-drm-helper.ko) or change the filename of
test-drm-helper.c. This is because nowtest-drm-helper.candtest-drm-damage-helper.chave to link together and kernel module is of same name which is causing circular dependency. Both of which looks overkill to me.
I think this is actually the right thing to do here. Sorry for not being clear.
Quoted 2 lines
If it is alright with you can we have separate test module. I already had a patch to integrate the damage test module with igt.
Yeah that needs to be adjusted too. Kinda wondering why we don't yet have an igt wrapper for the existing drm-helper stuff ...
-Daniel
Quoted 53 lines
Thanks,
DeepakQuoted 49 lines
Review
Quoted 3 lines
(quoted diff) +0
-0
b/drivers/gpu/drm/selftests/drm_damage_helper_selftests.hdrivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 3
Quoted 8 lines
new file mode 100644
index 000000000000..3a1cbe05bef0drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +3
-0@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +selftest(damage_iter_no_damage, igt_damage_iter_no_damage) +selftest(damage_iter_no_damage_fractional_src,
igt_damage_iter_no_damage_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 4
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_src_moved,
igt_damage_iter_no_damage_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 5
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_fractional_src_moved,
igt_damage_iter_no_damage_fractional_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 6
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_not_visible,
igt_damage_iter_no_damage_not_visible)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 7
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_no_crtc,
igt_damage_iter_no_damage_no_crtc)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 8
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_no_damage_no_fb,
igt_damage_iter_no_damage_no_fb)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 9
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_simple_damage,
igt_damage_iter_simple_damage)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 11
Quoted 2 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +2
-0+selftest(damage_iter_single_damage, igt_damage_iter_single_damage) +selftest(damage_iter_single_damage_intersect_src,
igt_damage_iter_single_damage_intersect_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 12
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_outside_src,
igt_damage_iter_single_damage_outside_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 13
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_fractional_src,
igt_damage_iter_single_damage_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 14
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_intersect_fractional_src,
igt_damage_iter_single_damage_intersect_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 15
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_outside_fractional_src,
igt_damage_iter_single_damage_outside_fractional_src)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 16
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_src_moved,
igt_damage_iter_single_damage_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 17
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_single_damage_fractional_src_moved,
igt_damage_iter_single_damage_fractional_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 19
Quoted 2 lines
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +2
-0+selftest(damage_iter_damage, igt_damage_iter_damage) +selftest(damage_iter_damage_one_intersect,
igt_damage_iter_damage_one_intersect)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 20
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_damage_one_outside,
igt_damage_iter_damage_one_outside)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 21
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_damage_src_moved,
igt_damage_iter_damage_src_moved)drivers/gpu/drm/selftests/drm_damage_helper_selftests.h line 22
Quoted 1 line
drivers/gpu/drm/selftests/drm_damage_helper_selftests.h new file +1
-0+selftest(damage_iter_damage_not_visible,
igt_damage_iter_damage_not_visible)
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 5/18 drm: Add helper to implement legacy dirtyfb
In reply to Deepak RawatFrom: Rob Clark <[email protected]>
Add an atomic helper to implement dirtyfb support. This is needed to support DSI command-mode panels with x11 userspace (ie. when we can't rely on pageflips to trigger a flush to the panel).
v2: Modified the helper to use plane fb_damage_clips property and removed plane_state::dirty flag.
v3:
- Use uapi drm_mode_rect.
- Support annotate flags.
--- drivers/gpu/drm/drm_damage_helper.c | 121 ++++++++++++++++++++++++++++ include/drm/drm_damage_helper.h | 4 + 2 files changed, 125 insertions(+)
drivers/gpu/drm/drm_damage_helper.c +121 -0
@@ -26,6 +26,7 @@* * Authors: * Deepak Rawat <[email protected]> +* Rob Clark <[email protected]> * **************************************************************************/
@@ -70,6 +71,21 @@* rectangles clipped to &drm_plane_state.src. */ +static void convert_clip_rect_to_rect (const struct drm_clip_rect *src, +struct drm_mode_rect *dest, +uint32_t num_clips,uint32_t src_inc) +{ +while (num_clips >0 ) { + dest->x1 = src->x1; + dest->y1 = src->y1; + dest->x2 = src->x2; + dest->y2 = src->y2; + src += src_inc; + dest++; + num_clips--; + } +} +/** * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property. * @plane: Plane on which to enable damage clips property.
@@ -123,6 +139,111 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, }EXPORT_SYMBOL (drm_atomic_helper_check_plane_damage); +/** +* drm_atomic_helper_dirtyfb - Helper for dirtyfb. +* @fb: DRM framebuffer. +* @file_priv: Drm file for the ioctl call. +* @flags: Dirty fb annotate flags. +* @color: Color for annotate fill. +* @clips: Dirty region. +* @num_clips: Count of clip in clips. +* +* A helper to implement &drm_framebuffer_funcs::dirty using damage interface +* during plane update. Similar to ioctl, this helper do a full plane update +* when no clips are provided. +* +* Returns: Zero on success, negative errno on failure. +*/ +int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips) +{ +struct drm_modeset_acquire_ctx ctx; +struct drm_property_blob *damage =NULL ; +struct drm_mode_rect *rects =NULL ; +struct drm_atomic_state *state; +struct drm_plane *plane; +int ret =0 ; + +/* +* When called from ioctl, we are interruptable, but not when called +* internally (ie. defio worker) +*/ +drm_modeset_acquire_init (&ctx, + file_priv ?DRM_MODESET_ACQUIRE_INTERRUPTIBLE :0 ); + + state =drm_atomic_state_alloc (fb->dev); +if (!state) { + ret = -ENOMEM ; + goto out; + } + state->acquire_ctx = &ctx; + +if (clips) { +uint32_t inc =1 ; + +if (flags &DRM_MODE_FB_DIRTY_ANNOTATE_COPY ) { + inc =2 ; + num_clips /=2 ; + } + + rects =kcalloc (num_clips,sizeof (*rects),GFP_KERNEL ); +if (!rects) { + ret = -ENOMEM ; + goto out; + } + +convert_clip_rect_to_rect (clips, rects, num_clips, inc); + damage =drm_property_create_blob (fb->dev, + num_clips *sizeof (*rects), + rects); +if (IS_ERR (damage)) { + ret =PTR_ERR (damage); + damage =NULL ; + goto out; + } + } + +retry: +drm_for_each_plane (plane, fb->dev) { +struct drm_plane_state *plane_state; + +if (plane->state->fb != fb) +continue ; + + plane_state =drm_atomic_get_plane_state (state, plane); +if (IS_ERR (plane_state)) { + ret =PTR_ERR (plane_state); + goto out; + } + +drm_property_replace_blob (&plane_state->fb_damage_clips, + damage); + } + + ret =drm_atomic_commit (state); + +out: +if (ret == -EDEADLK ) { +drm_atomic_state_clear (state); + ret =drm_modeset_backoff (&ctx); +if (!ret) + goto retry; + } + +drm_property_blob_put (damage); +kfree (rects); +drm_atomic_state_put (state); + +drm_modeset_drop_locks (&ctx); +drm_modeset_acquire_fini (&ctx); + +return ret; + +} +EXPORT_SYMBOL (drm_atomic_helper_dirtyfb); +/** * drm_atomic_helper_damage_iter_init - Initialize the damage iterator. * @iter: The iterator to initialize.
include/drm/drm_damage_helper.h +4 -0
@@ -67,6 +67,10 @@ struct drm_atomic_helper_damage_iter {void drm_plane_enable_fb_damage_clips (struct drm_plane *plane);void drm_atomic_helper_check_plane_damage (struct drm_atomic_state *state,struct drm_plane_state *plane_state); +int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips); void drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, const struct drm_plane_state *old_state,
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 05/18] drm: Add helper to implement legacy dirtyfb
Quoted 63 lines · Deepak Rawat
From: Rob Clark <[email protected]>
Add an atomic helper to implement dirtyfb support. This is needed to support DSI command-mode panels with x11 userspace (ie. when we can't rely on pageflips to trigger a flush to the panel).
v2: Modified the helper to use plane
fb_damage_clipsproperty and removedplane_state::dirtyflag.v3:
- Use uapidrm_mode_rect.
- Support annotate flags.Cc Daniel Vetter <[email protected]>Cc Pekka Paalanen <[email protected]>Signed-off-by Rob Clark <[email protected]>Signed-off-by Deepak Rawat <[email protected]>--- drivers/gpu/drm/drm_damage_helper.c | 121 ++++++++++++++++++++++++++++ include/drm/drm_damage_helper.h | 4 + 2 files changed, 125 insertions(+)drivers/gpu/drm/drm_damage_helper.c +18
-0@@ -26,6 +26,7 @@* * Authors: * Deepak Rawat <[email protected]> +* Rob Clark <[email protected]> * **************************************************************************/ @@ -70,6 +71,21 @@* rectangles clipped to &drm_plane_state.src. */ +static void convert_clip_rect_to_rect (const struct drm_clip_rect *src, +struct drm_mode_rect *dest, +uint32_t num_clips,uint32_t src_inc) +{ +while (num_clips >0 ) { + dest->x1 = src->x1; + dest->y1 = src->y1; + dest->x2 = src->x2; + dest->y2 = src->y2; + src += src_inc; + dest++; + num_clips--; + } +} +/** * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property. * @plane: Plane on which to enable damage clips property. @@ -123,6 +139,111 @@ void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, }EXPORT_SYMBOL (drm_atomic_helper_check_plane_damage); +/** +* drm_atomic_helper_dirtyfb - Helper for dirtyfb.
drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, · line 153
Quoted 10 lines
drivers/gpu/drm/drm_damage_helper.c +10
-0+* @fb: DRM framebuffer. +* @file_priv: Drm file for the ioctl call. +* @flags: Dirty fb annotate flags. +* @color: Color for annotate fill. +* @clips: Dirty region. +* @num_clips: Count of clip in clips. +* +* A helper to implement &drm_framebuffer_funcs::dirty using damage interface +* during plane update. Similar to ioctl, this helper do a full plane update +* when no clips are provided.
The above kerneldoc doesn't make sense to me ... we do have clips provided here, it's just a different layout.
Quoted 62 lines
drivers/gpu/drm/drm_damage_helper.c +62
-0+* +* Returns: Zero on success, negative errno on failure. +*/ +int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips) +{ +struct drm_modeset_acquire_ctx ctx; +struct drm_property_blob *damage =NULL ; +struct drm_mode_rect *rects =NULL ; +struct drm_atomic_state *state; +struct drm_plane *plane; +int ret =0 ; + +/* +* When called from ioctl, we are interruptable, but not when called +* internally (ie. defio worker) +*/ +drm_modeset_acquire_init (&ctx, + file_priv ?DRM_MODESET_ACQUIRE_INTERRUPTIBLE :0 ); + + state =drm_atomic_state_alloc (fb->dev); +if (!state) { + ret = -ENOMEM ; + goto out; + } + state->acquire_ctx = &ctx; + +if (clips) { +uint32_t inc =1 ; + +if (flags &DRM_MODE_FB_DIRTY_ANNOTATE_COPY ) { + inc =2 ; + num_clips /=2 ; + } + + rects =kcalloc (num_clips,sizeof (*rects),GFP_KERNEL ); +if (!rects) { + ret = -ENOMEM ; + goto out; + } + +convert_clip_rect_to_rect (clips, rects, num_clips, inc); + damage =drm_property_create_blob (fb->dev, + num_clips *sizeof (*rects), + rects); +if (IS_ERR (damage)) { + ret =PTR_ERR (damage); + damage =NULL ; + goto out; + } + } + +retry: +drm_for_each_plane (plane, fb->dev) { +struct drm_plane_state *plane_state; + +if (plane->state->fb != fb) +continue ; + + plane_state =drm_atomic_get_plane_state (state, plane);
drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, · line 225
Quoted 10 lines
drivers/gpu/drm/drm_damage_helper.c +10
-0+if (IS_ERR (plane_state)) { + ret =PTR_ERR (plane_state); + goto out; + } + +drm_property_replace_blob (&plane_state->fb_damage_clips, + damage); + } + + ret =drm_atomic_commit (state);
This blocks, which matches what udl does (one of the very first implementations of the fb->dirty callback). I got lost a bit in the vmwgfx dirty implementation, so no idea whether that one blocked or not.
If the blocking here is a problem, then we need a separate worker similarly to what the fbdev worker does (since using the atomic nonblocking stuff has uapi side-effects).
Either way, probably something we need to document in the kernel-doc. -Daniel
Quoted 42 lines
drivers/gpu/drm/drm_damage_helper.c +21
-0+ +out: +if (ret == -EDEADLK ) { +drm_atomic_state_clear (state); + ret =drm_modeset_backoff (&ctx); +if (!ret) + goto retry; + } + +drm_property_blob_put (damage); +kfree (rects); +drm_atomic_state_put (state); + +drm_modeset_drop_locks (&ctx); +drm_modeset_acquire_fini (&ctx); + +return ret; + +} +EXPORT_SYMBOL (drm_atomic_helper_dirtyfb); +/** * drm_atomic_helper_damage_iter_init - Initialize the damage iterator. * @iter: The iterator to initialize. include/drm/drm_damage_helper.h +4
-0@@ -67,6 +67,10 @@ struct drm_atomic_helper_damage_iter {void drm_plane_enable_fb_damage_clips (struct drm_plane *plane);void drm_atomic_helper_check_plane_damage (struct drm_atomic_state *state,struct drm_plane_state *plane_state); +int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips); void drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, const struct drm_plane_state *old_state,Signature · 1 line
2.17.1
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
RE: [PATCH 05/18] drm: Add helper to implement legacy dirtyfb
Quoted 78 lines · Deepak Rawat
Quoted 13 lines
From: Rob Clark <[email protected]>
Add an atomic helper to implement dirtyfb support. This is needed to support DSI command-mode panels with x11 userspace (ie. when we can't rely on pageflips to trigger a flush to the panel).
v2: Modified the helper to use plane
fb_damage_clipsproperty and removedplane_state::dirtyflag.v3:
- Use uapidrm_mode_rect.
- Support annotate flags.Quoted 7 lines
Cc Daniel Vetter <[email protected]>Cc Pekka Paalanen <[email protected]>Signed-off-by Rob Clark <[email protected]>Signed-off-by Deepak Rawat <[email protected]>--- drivers/gpu/drm/drm_damage_helper.c | 121++++++++++++++++++++++++++++
Review
Quoted 4 lines
include/drm/drm_damage_helper.h | 4 + 2 files changed, 125 insertions(+)(quoted diff) +0
-0
b/drivers/gpu/drm/drm_damage_helper.cdrivers/gpu/drm/drm_damage_helper.c line 31
Quoted 10 lines
index
bc734ddaf180..ecf26275543f100644drivers/gpu/drm/drm_damage_helper.c +1
-0@@ -26,6 +26,7 @@* * Authors: * Deepak Rawat <[email protected]> +* Rob Clark <[email protected]> * **********************************************************
****************/Quoted 12 lines
drivers/gpu/drm/drm_damage_helper.c +7
-0@@ -70,6 +71,21 @@* rectangles clipped to &drm_plane_state.src. */ +static void convert_clip_rect_to_rect (const struct drm_clip_rect *src, +struct drm_mode_rect *dest, +uint32_t num_clips,uint32_t src_inc) +{ +while (num_clips >0 ) { + dest->x1 = src->x1; + dest->y1 = src->y1;drivers/gpu/drm/drm_damage_helper.c line 90
Quoted 10 lines
drivers/gpu/drm/drm_damage_helper.c +8
-0+ dest->x2 = src->x2; + dest->y2 = src->y2; + src += src_inc; + dest++; + num_clips--; + } +} +/** * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property.
drivers/gpu/drm/drm_damage_helper.c void
Quoted 2 lines
drivers/gpu/drm/drm_damage_helper.c +0
-0* @plane: Plane on which to enable damage clips property. @@ -123,6 +139,111 @@ voiddrm_atomic_helper_check_plane_damage(struct
drm_atomic_state*state,drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state,
Quoted 13 lines
drivers/gpu/drm/drm_damage_helper.c +10
-0}EXPORT_SYMBOL (drm_atomic_helper_check_plane_damage); +/** +* drm_atomic_helper_dirtyfb - Helper for dirtyfb. +* @fb: DRM framebuffer. +* @file_priv: Drm file for the ioctl call. +* @flags: Dirty fb annotate flags. +* @color: Color for annotate fill. +* @clips: Dirty region. +* @num_clips: Count of clip in clips. +* +* A helper to implement &drm_framebuffer_funcs::dirty using damage
Quoted 6 lines
interface
drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, · line 153
Quoted 2 lines
drivers/gpu/drm/drm_damage_helper.c +2
-0+* during plane update. Similar to ioctl, this helper do a full plane update +* when no clips are provided. The above kerneldoc doesn't make sense to me ... we do have clips provided here, it's just a different layout.
Thanks Daniel for the review. I meant if clips are NULL, which is possible.
Quoted 79 lines
Quoted 64 lines
drivers/gpu/drm/drm_damage_helper.c +63
-0+* +* Returns: Zero on success, negative errno on failure. +*/ +int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips) +{ +struct drm_modeset_acquire_ctx ctx; +struct drm_property_blob *damage =NULL ; +struct drm_mode_rect *rects =NULL ; +struct drm_atomic_state *state; +struct drm_plane *plane; +int ret =0 ; + +/* +* When called from ioctl, we are interruptable, but not when called +* internally (ie. defio worker) +*/ +drm_modeset_acquire_init (&ctx, + file_priv ?DRM_MODESET_ACQUIRE_INTERRUPTIBLE :0 ); + + state =drm_atomic_state_alloc (fb->dev); +if (!state) { + ret = -ENOMEM ; + goto out; + } + state->acquire_ctx = &ctx; + +if (clips) { +uint32_t inc =1 ; + +if (flags &DRM_MODE_FB_DIRTY_ANNOTATE_COPY ) { + inc =2 ; + num_clips /=2 ; + } + + rects =kcalloc (num_clips,sizeof (*rects),GFP_KERNEL ); +if (!rects) { + ret = -ENOMEM ; + goto out; + } + +convert_clip_rect_to_rect (clips, rects, num_clips, inc); + damage =drm_property_create_blob (fb->dev, + num_clips *sizeof (*rects), + rects); +if (IS_ERR (damage)) { + ret =PTR_ERR (damage); + damage =NULL ; + goto out; + } + } + +retry: +drm_for_each_plane (plane, fb->dev) { +struct drm_plane_state *plane_state; + +if (plane->state->fb != fb) +continue ; + + plane_state =drm_atomic_get_plane_state (state, plane); +if (IS_ERR (plane_state)) {drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, · line 225
Quoted 10 lines
drivers/gpu/drm/drm_damage_helper.c +9
-0+ ret =PTR_ERR (plane_state); + goto out; + } + +drm_property_replace_blob (&plane_state- fb_damage_clips, + damage); + } + + ret =drm_atomic_commit (state);This blocks, which matches what udl does (one of the very first implementations of the
fb->dirtycallback). I got lost a bit in the vmwgfx dirty implementation, so no idea whether that one blocked or not.
Quoted 6 lines
If the blocking here is a problem, then we need a separate worker similarly to what the fbdev worker does (since using the atomic nonblocking stuff has uapi side-effects).
Either way, probably something we need to document in the kernel-doc. -Daniel
IIUC vmwgfx dirty implementation also block. vmwgfx dirty implementation will make sure that commands are flushed to virtual device and all the mutex lock are held until then.
With my testing on vmwgfx software only VM I see that non-blocking will cause rendering issues with so many dirty_fb ioctl()'s and kernel returns EBUSY(?).
Yes I agree I can update the kernel-doc to specify blocking and if someone need non-blocking version in future that can be easily done.
Thanks,
Deepak
Quoted 48 lines
Quoted 25 lines
drivers/gpu/drm/drm_damage_helper.c +21
-0+ +out: +if (ret == -EDEADLK ) { +drm_atomic_state_clear (state); + ret =drm_modeset_backoff (&ctx); +if (!ret) + goto retry; + } + +drm_property_blob_put (damage); +kfree (rects); +drm_atomic_state_put (state); + +drm_modeset_drop_locks (&ctx); +drm_modeset_acquire_fini (&ctx); + +return ret; + +} +EXPORT_SYMBOL (drm_atomic_helper_dirtyfb); +/** * drm_atomic_helper_damage_iter_init - Initialize the damage iterator. * @iter: The iterator to initialize.
Review
Quoted 1 line
(quoted diff) +0
-0
b/include/drm/drm_damage_helper.hinclude/drm/drm_damage_helper.h struct drm_atomic_helper_damage_iter { · line 68
Quoted 6 lines
index
af188799820f..e4fe7036cab2100644include/drm/drm_damage_helper.h +0
-0@@ -67,6 +67,10 @@ struct drm_atomic_helper_damage_iter {void drm_plane_enable_fb_damage_clips (struct drm_plane *plane); void drm_atomic_helper_check_plane_damage(struct drm_atomic_state*state,
include/drm/drm_damage_helper.h struct drm_atomic_helper_damage_iter { · line 69
Quoted 1 line
include/drm/drm_damage_helper.h +0
-0struct drm_plane_state
*plane_state);include/drm/drm_damage_helper.h struct drm_atomic_helper_damage_iter {
Quoted 6 lines
include/drm/drm_damage_helper.h +4
-0+int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips); void drm_atomic_helper_damage_iter_init(struct
drm_atomic_helper_damage_iter*iter,Quoted 4 lines
include/drm/drm_damage_helper.h +0
-1const struct drm_plane_state *old_state, --2.17.1
Quoted 8 lines
--
Daniel Vetter
Software Engineer, Intel Corporation
https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.ff
wll.ch&data=02%7C01%7Cdrawat%40vmware.com%7C0835e0509d8849 89c6c208d6277513ae%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7 C636739781135270102&sdata=6%2Fr%2FS%2B3k7nJDZKNd9tRnmofCGf CG2TKqDy4tG6lojsA%3D&reserved=0
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 05/18] drm: Add helper to implement legacy dirtyfb
Quoted 78 lines · Deepak Singh Rawat
Quoted 78 lines · Deepak Rawat
Quoted 13 lines
From: Rob Clark <[email protected]>
Add an atomic helper to implement dirtyfb support. This is needed to support DSI command-mode panels with x11 userspace (ie. when we can't rely on pageflips to trigger a flush to the panel).
v2: Modified the helper to use plane
fb_damage_clipsproperty and removedplane_state::dirtyflag.v3:
- Use uapidrm_mode_rect.
- Support annotate flags.Quoted 7 lines
Cc Daniel Vetter <[email protected]>Cc Pekka Paalanen <[email protected]>Signed-off-by Rob Clark <[email protected]>Signed-off-by Deepak Rawat <[email protected]>--- drivers/gpu/drm/drm_damage_helper.c | 121++++++++++++++++++++++++++++
Review
Quoted 4 lines
include/drm/drm_damage_helper.h | 4 + 2 files changed, 125 insertions(+)(quoted diff) +0
-0
b/drivers/gpu/drm/drm_damage_helper.cdrivers/gpu/drm/drm_damage_helper.c line 31
Quoted 10 lines
index
bc734ddaf180..ecf26275543f100644drivers/gpu/drm/drm_damage_helper.c +1
-0@@ -26,6 +26,7 @@* * Authors: * Deepak Rawat <[email protected]> +* Rob Clark <[email protected]> * **********************************************************
****************/Quoted 12 lines
drivers/gpu/drm/drm_damage_helper.c +7
-0@@ -70,6 +71,21 @@* rectangles clipped to &drm_plane_state.src. */ +static void convert_clip_rect_to_rect (const struct drm_clip_rect *src, +struct drm_mode_rect *dest, +uint32_t num_clips,uint32_t src_inc) +{ +while (num_clips >0 ) { + dest->x1 = src->x1; + dest->y1 = src->y1;drivers/gpu/drm/drm_damage_helper.c line 90
Quoted 10 lines
drivers/gpu/drm/drm_damage_helper.c +8
-0+ dest->x2 = src->x2; + dest->y2 = src->y2; + src += src_inc; + dest++; + num_clips--; + } +} +/** * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property.
drivers/gpu/drm/drm_damage_helper.c void
Quoted 2 lines
drivers/gpu/drm/drm_damage_helper.c +0
-0* @plane: Plane on which to enable damage clips property. @@ -123,6 +139,111 @@ voiddrm_atomic_helper_check_plane_damage(struct
drm_atomic_state*state,Quoted 13 lines
drivers/gpu/drm/drm_damage_helper.c +10
-0}EXPORT_SYMBOL (drm_atomic_helper_check_plane_damage); +/** +* drm_atomic_helper_dirtyfb - Helper for dirtyfb. +* @fb: DRM framebuffer. +* @file_priv: Drm file for the ioctl call. +* @flags: Dirty fb annotate flags. +* @color: Color for annotate fill. +* @clips: Dirty region. +* @num_clips: Count of clip in clips. +* +* A helper to implement &drm_framebuffer_funcs::dirty using damage
Quoted 8 lines
Quoted 6 lines
interface
drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, · line 153
Quoted 2 lines
drivers/gpu/drm/drm_damage_helper.c +2
-0+* during plane update. Similar to ioctl, this helper do a full plane update +* when no clips are provided. The above kerneldoc doesn't make sense to me ... we do have clips provided here, it's just a different layout.
Thanks Daniel for the review. I meant if clips are NULL, which is possible.
Ah right, I've forgotten that the dirty ioctl allows num_clips == 0 iff clips == NULL. Might be good to document that, for people like me :-)
Quoted 85 lines
Quoted 78 lines
Quoted 63 lines
drivers/gpu/drm/drm_damage_helper.c +63
-0+* +* Returns: Zero on success, negative errno on failure. +*/ +int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips) +{ +struct drm_modeset_acquire_ctx ctx; +struct drm_property_blob *damage =NULL ; +struct drm_mode_rect *rects =NULL ; +struct drm_atomic_state *state; +struct drm_plane *plane; +int ret =0 ; + +/* +* When called from ioctl, we are interruptable, but not when called +* internally (ie. defio worker) +*/ +drm_modeset_acquire_init (&ctx, + file_priv ?DRM_MODESET_ACQUIRE_INTERRUPTIBLE :0 ); + + state =drm_atomic_state_alloc (fb->dev); +if (!state) { + ret = -ENOMEM ; + goto out; + } + state->acquire_ctx = &ctx; + +if (clips) { +uint32_t inc =1 ; + +if (flags &DRM_MODE_FB_DIRTY_ANNOTATE_COPY ) { + inc =2 ; + num_clips /=2 ; + } + + rects =kcalloc (num_clips,sizeof (*rects),GFP_KERNEL ); +if (!rects) { + ret = -ENOMEM ; + goto out; + } + +convert_clip_rect_to_rect (clips, rects, num_clips, inc); + damage =drm_property_create_blob (fb->dev, + num_clips *sizeof (*rects), + rects); +if (IS_ERR (damage)) { + ret =PTR_ERR (damage); + damage =NULL ; + goto out; + } + } + +retry: +drm_for_each_plane (plane, fb->dev) { +struct drm_plane_state *plane_state; + +if (plane->state->fb != fb) +continue ; + + plane_state =drm_atomic_get_plane_state (state, plane); +if (IS_ERR (plane_state)) {drivers/gpu/drm/drm_damage_helper.c void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state, · line 225
Quoted 10 lines
drivers/gpu/drm/drm_damage_helper.c +9
-0+ ret =PTR_ERR (plane_state); + goto out; + } + +drm_property_replace_blob (&plane_state- fb_damage_clips, + damage); + } + + ret =drm_atomic_commit (state);This blocks, which matches what udl does (one of the very first implementations of the
fb->dirtycallback). I got lost a bit in the vmwgfx dirty implementation, so no idea whether that one blocked or not.Quoted 6 lines
If the blocking here is a problem, then we need a separate worker similarly to what the fbdev worker does (since using the atomic nonblocking stuff has uapi side-effects).
Either way, probably something we need to document in the kernel-doc. -Daniel
Quoted 6 lines
IIUC vmwgfx dirty implementation also block. vmwgfx dirty implementation will make sure that commands are flushed to virtual device and all the mutex lock are held until then.
With my testing on vmwgfx software only VM I see that non-blocking will cause rendering issues with so many
dirty_fbioctl()'s and kernel returns EBUSY(?).
Yup, drm_atomic_commit_nonblocking will not work here, wrong semantics. As I mentioned, we'd need a separate struct_work and similar logic like in the fbdev defio support in drm_fb_helper.c.
Quoted 2 lines
Yes I agree I can update the kernel-doc to specify blocking and if someone need non-blocking version in future that can be easily done.
Sounds good, and much less work :-)
-Daniel
Quoted 59 lines
Thanks,
DeepakQuoted 56 lines
Quoted 25 lines
drivers/gpu/drm/drm_damage_helper.c +21
-0+ +out: +if (ret == -EDEADLK ) { +drm_atomic_state_clear (state); + ret =drm_modeset_backoff (&ctx); +if (!ret) + goto retry; + } + +drm_property_blob_put (damage); +kfree (rects); +drm_atomic_state_put (state); + +drm_modeset_drop_locks (&ctx); +drm_modeset_acquire_fini (&ctx); + +return ret; + +} +EXPORT_SYMBOL (drm_atomic_helper_dirtyfb); +/** * drm_atomic_helper_damage_iter_init - Initialize the damage iterator. * @iter: The iterator to initialize.
Review
Quoted 1 line
(quoted diff) +0
-0
b/include/drm/drm_damage_helper.hinclude/drm/drm_damage_helper.h struct drm_atomic_helper_damage_iter { · line 68
Quoted 6 lines
index
af188799820f..e4fe7036cab2100644include/drm/drm_damage_helper.h +0
-0@@ -67,6 +67,10 @@ struct drm_atomic_helper_damage_iter {void drm_plane_enable_fb_damage_clips (struct drm_plane *plane); void drm_atomic_helper_check_plane_damage(struct drm_atomic_state*state,
include/drm/drm_damage_helper.h struct drm_atomic_helper_damage_iter { · line 69
Quoted 1 line
include/drm/drm_damage_helper.h +0
-0struct drm_plane_state
*plane_state);include/drm/drm_damage_helper.h struct drm_atomic_helper_damage_iter {
Quoted 6 lines
include/drm/drm_damage_helper.h +4
-0+int drm_atomic_helper_dirtyfb (struct drm_framebuffer *fb, +struct drm_file *file_priv,unsigned flags, +unsigned color,struct drm_clip_rect *clips, +unsigned num_clips); void drm_atomic_helper_damage_iter_init(struct
drm_atomic_helper_damage_iter*iter,Quoted 4 lines
include/drm/drm_damage_helper.h +0
-1const struct drm_plane_state *old_state, --2.17.1
--
Daniel Vetter
Software Engineer, Intel Corporation
https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.ff
wll.ch&data=02%7C01%7Cdrawat%40vmware.com%7C0835e0509d8849 89c6c208d6277513ae%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7 C636739781135270102&sdata=6%2Fr%2FS%2B3k7nJDZKNd9tRnmofCGf CG2TKqDy4tG6lojsA%3D&reserved=0
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 6/18 drm/vmwgfx: Add a new interface for plane update on a display unit
In reply to Deepak RawatAdd a new struct vmw_du_update_plane similar to vmw_kms_dirty which represent the flow of operations needed to update a display unit from surface or bo (blit a new framebuffer).
v2:
- Kernel doc correction.
- Rebase.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 99 ++++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 125 ++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +99 -0
@@ -30,6 +30,7 @@#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_rect.h> +#include <drm/drm_damage_helper.h> /* Might need a hrtimer here? */ #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
@@ -3092,3 +3093,101 @@ void vmw_kms_lost_device(struct drm_device *dev) {drm_atomic_helper_shutdown (dev); } + +/** +* vmw_du_helper_plane_update - Helper to do plane update on a display unit. +* @update: The closure structure. +* +* Call this helper after setting callbacks in &vmw_du_update_plane to do plane +* update on display unit. +* +* RETURNS: 0 on success or a negative error code on failure. +*/ +int vmw_du_helper_plane_update (struct vmw_du_update_plane *update) +{ +struct drm_plane_state *state = update->plane->state; +struct drm_plane_state *old_state = update->old_state; +struct drm_atomic_helper_damage_iter iter; +struct drm_rect clip; +struct drm_rect bb; +uint32_t reserved_size =0 ; +uint32_t submit_size =0 ; +uint32_t curr_size =0 ; +uint32_t num_hits =0 ; +void *cmd_start; +char *cmd_next; +int ret; + +/* +* Iterate in advance to check if really need plane update and find the +* number of clips that actually are in plane src for fifo allocation. +*/ +drm_atomic_helper_damage_iter_init (&iter, old_state, state); +drm_atomic_for_each_plane_damage (&iter, &clip) + num_hits++; + +if (num_hits ==0 ) +return 0 ; + + ret = update->prepare (update); +if (ret) { +DRM_ERROR ("Failed to validate FB for command submission\n" ); +return ret; + } + + reserved_size = update->calc_fifo_size (update, num_hits); + cmd_start =vmw_fifo_reserve (update->dev_priv, reserved_size); +if (!cmd_start) { +DRM_ERROR ("Failed to allocate FIFO space for plane update\n" ); + update->revert (update); +return -ENOMEM ; + } + cmd_next = cmd_start; + +if (update->post_prepare) { + curr_size = update->post_prepare (update, cmd_next); + cmd_next += curr_size; + submit_size += curr_size; + } + +if (update->pre_clip) { + curr_size = update->pre_clip (update, cmd_next, num_hits); + cmd_next += curr_size; + submit_size += curr_size; + } + + bb.x1 =INT_MAX ; + bb.y1 =INT_MAX ; + bb.x2 =INT_MIN ; + bb.y2 =INT_MIN ; + +drm_atomic_helper_damage_iter_init (&iter, old_state, state); +drm_atomic_for_each_plane_damage (&iter, &clip) { +uint32_t fb_x = clip.x1; +uint32_t fb_y = clip.y1; + +vmw_du_translate_to_crtc (state, &clip); +if (update->clip) { + curr_size = update->clip (update, cmd_next, &clip, fb_x, + fb_y); + cmd_next += curr_size; + submit_size += curr_size; + } + bb.x1 =min_t (int, bb.x1, clip.x1); + bb.y1 =min_t (int, bb.y1, clip.y1); + bb.x2 =max_t (int, bb.x2, clip.x2); + bb.y2 =max_t (int, bb.y2, clip.y2); + } + + curr_size = update->post_clip (update, cmd_next, &bb); + submit_size += curr_size; + +if (reserved_size < submit_size) + submit_size =0 ; + +vmw_fifo_commit (update->dev_priv, submit_size); + + update->finish (update); + +return ret; +}
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +125 -0
136 lines not on this page · raw message
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 7/18 drm/vmwgfx: Implement STDU plane update for surface backed fb
In reply to Deepak RawatUsing the new interface implement STDU plane update for surface backed fb.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 10 ++ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 207 ++++++++++++++++++++++++++- 2 files changed, 216 insertions(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +10 -0
@@ -143,6 +143,16 @@ struct vmw_du_update_plane {struct vmw_fence_obj **out_fence; }; +/** +* struct vmw_du_update_plane_surface - closure structure for surface +* @base: base closure structure. +* @ctx: validation context. +*/ +struct vmw_du_update_plane_surface { +struct vmw_du_update_plane base; +struct vmw_validation_ctx *ctx; +}; +/** * struct vmw_kms_dirty - closure structure for the vmw_kms_helper_dirty * function.
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +206 -1
226 lines not on this page · raw message
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 8/18 drm/vmwgfx: Implement STDU plane update for BO backed fb
In reply to Deepak RawatUsing the new interface implement STDU plane update for BO backed fb.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 13 ++ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 233 +++++++++++++++++++++++++++ 2 files changed, 246 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +13 -0
@@ -153,6 +153,19 @@ struct vmw_du_update_plane_surface {struct vmw_validation_ctx *ctx; }; +/** +* struct vmw_du_update_plane_buffer - Closure structure for buffer object +* @base: Base closure structure. +* @fb_left: x1 for fb damage bounding box. +* @fb_top: y1 for fb damage bounding box. +* @cpu_blit: True if need cpu blit. +*/ +struct vmw_du_update_plane_buffer { +struct vmw_du_update_plane base; +int fb_left, fb_top; +bool cpu_blit; +}; +/** * struct vmw_kms_dirty - closure structure for the vmw_kms_helper_dirty * function.
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +233 -0
239 lines not on this page · raw message
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 9/18 drm/vmwgfx: Use the new interface for STDU plane update
In reply to Deepak RawatWith new interface to do plane update on STDU available, use that instead of old kms_dirty.
--- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +5 -12
@@ -1709,7 +1709,6 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,if (crtc && plane->state->fb) {struct vmw_framebuffer *vfb =vmw_framebuffer_to_vfb (plane->state->fb); -struct drm_vmw_rect vclips; stdu =vmw_crtc_to_stdu (crtc); dev_priv =vmw_priv (crtc->dev);
@@ -1717,23 +1716,17 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane, stdu->content_fb_type = vps->content_fb_type; stdu->cpp = vps->cpp; - vclips.x = crtc->x; - vclips.y = crtc->y; - vclips.w = crtc->mode.hdisplay; - vclips.h = crtc->mode.vdisplay; - ret =vmw_stdu_bind_st (dev_priv, stdu, &stdu->display_srf->res);if (ret)DRM_ERROR ("Failed to bind surface to STDU.\n" );if (vfb->bo) - ret =vmw_kms_stdu_dma (dev_priv,NULL , vfb,NULL ,NULL , - &vclips,1 ,1 , true, false, - crtc); + ret =vmw_stdu_plane_update_bo (dev_priv, plane, + old_state, vfb);else - ret =vmw_kms_stdu_surface_dirty (dev_priv, vfb,NULL , - &vclips,NULL ,0 ,0 , -1 ,1 ,NULL , crtc); + ret =vmw_stdu_plane_update_surface (dev_priv, plane, + old_state, vfb, +NULL );if (ret)DRM_ERROR ("Failed to update STDU.\n" ); }else {
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 10/18 drm/vmwgfx: Updated comment for stdu plane update
In reply to Deepak RawatUpdate the comment to sync with code.
--- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +4 -18
@@ -1682,7 +1682,6 @@ static int vmw_stdu_plane_update_surface(struct vmw_private *dev_priv,/** * vmw_stdu_primary_plane_atomic_update - formally switches STDU to new plane -* * @plane: display plane * @old_state: Only used to get crtc info *
@@ -1702,10 +1701,7 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,struct vmw_private *dev_priv;int ret; -/* -* We cannot really fail this function, so if we do, then output an -* error and maintain consistent atomic state. -*/ +/* If somehow gets a device error, maintain consistent atomic state */ if (crtc && plane->state->fb) {struct vmw_framebuffer *vfb =vmw_framebuffer_to_vfb (plane->state->fb);
@@ -1734,12 +1730,7 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane, stdu =vmw_crtc_to_stdu (crtc); dev_priv =vmw_priv (crtc->dev); -/* -* When disabling a plane, CRTC and FB should always be NULL -* together, otherwise it's an error. -* Here primary plane is being disable so blank the screen -* target display unit, if not already done. -*/ +/* Blank STDU when fb and crtc are NULL */ if (!stdu->defined)return ;
@@ -1754,20 +1745,15 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,return ; } +/* In case of error vblank event is sent in vmw_du_crtc_atomic_flush */ event = crtc->state->event; -/* -* In case of failure and other cases, vblank event will be sent in -* vmw_du_crtc_atomic_flush. -*/ if (event && (ret ==0 )) {struct vmw_fence_obj *fence =NULL ;struct drm_file *file_priv = event->base.file_priv;vmw_execbuf_fence_commands (NULL , dev_priv, &fence,NULL ); -/* -* If fence is NULL, then already sync. -*/ +/* If fence is NULL, then already sync. */ if (fence) { ret = vmw_event_fence_action_queue( file_priv, fence, &event->base,
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 11/18 drm/vmwgfx: Enable FB_DAMAGE_CLIPS property for STDU primary plane
In reply to Deepak RawatSTDU primary plane now support damage clips, enable it for user-space.
--- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +1 -0
@@ -1878,6 +1878,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) }drm_plane_helper_add (primary, &vmw_stdu_primary_plane_helper_funcs); +drm_plane_enable_fb_damage_clips (primary);/* Initialize cursor plane */ vmw_du_plane_reset (cursor);
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 12/18 drm/vmwgfx: Implement SOU plane update for surface backed fb
In reply to Deepak RawatUsing the new interface implement SOU plane update for surface backed fb.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 3 + drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 185 +++++++++++++++++++++++++++ 2 files changed, 188 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +3 -0
@@ -147,10 +147,13 @@ struct vmw_du_update_plane {* struct vmw_du_update_plane_surface - closure structure for surface * @base: base closure structure. * @ctx: validation context. +* @cmd_start: FIFO command start address (used by SOU only). */ struct vmw_du_update_plane_surface {struct vmw_du_update_plane base;struct vmw_validation_ctx *ctx; +/* This member is to handle special case SOU surface update */ +void *cmd_start; };/**
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +185 -0
191 lines not on this page · raw message
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 13/18 drm/vmwgfx: Implement SOU plane update for BO backed fb
In reply to Deepak RawatUsing the new interface implement SOU plane update for BO backed fb.
--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 132 +++++++++++++++++++++++++++ 1 file changed, 132 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +132 -0
@@ -76,6 +76,11 @@ struct vmw_kms_sou_dirty_cmd {SVGA3dCmdBlitSurfaceToScreen body; }; +struct vmw_kms_sou_define_gmrfb { +uint32_t header; +SVGAFifoCmdDefineGMRFB body; +}; +/** * Display unit using screen objects. */
@@ -499,6 +504,133 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,return vmw_bo_pin_in_vram (dev_priv, vps->bo, true); } +static int vmw_sou_bo_prepare (struct vmw_du_update_plane *update) +{ +struct vmw_du_update_plane_buffer *bo_update; +struct vmw_framebuffer_bo *vfbbo; + + bo_update =container_of (update,typeof (*bo_update), base); + vfbbo =container_of (update->vfb,typeof (*vfbbo), base); + +return vmw_kms_helper_buffer_prepare (update->dev_priv, vfbbo->buffer, + true, false, bo_update->cpu_blit); +} + +static uint32_t vmw_sou_bo_fifo_size (struct vmw_du_update_plane *update, +uint32_t num_hits) +{ +return sizeof (struct vmw_kms_sou_define_gmrfb ) + +sizeof (struct vmw_kms_sou_bo_blit ) * num_hits; +} + +static uint32_t vmw_sou_bo_define_gmrfb (struct vmw_du_update_plane *update, +void *cmd) +{ +struct vmw_framebuffer_bo *vfbbo = +container_of (update->vfb,typeof (*vfbbo), base); +struct vmw_kms_sou_define_gmrfb *gmr = cmd; +int depth = update->vfb->base.format->depth; + +/* Emulate RGBA support, contrary to svga_reg.h this is not +* supported by hosts. This is only a problem if we are reading +* this value later and expecting what we uploaded back. +*/ +if (depth ==32 ) + depth =24 ; + + gmr->header =SVGA_CMD_DEFINE_GMRFB ; + + gmr->body.format.bitsPerPixel = update->vfb->base.format->cpp[0 ] *8 ; + gmr->body.format.colorDepth = depth; + gmr->body.format.reserved =0 ; + gmr->body.bytesPerLine = update->vfb->base.pitches[0 ]; +vmw_bo_get_guest_ptr (&vfbbo->buffer->base, &gmr->body.ptr); + +return sizeof (*gmr); +} + +static uint32_t vmw_sou_bo_populate_clip (struct vmw_du_update_plane *update, +void *cmd,struct drm_rect *clip, +uint32_t fb_x,uint32_t fb_y) +{ +struct vmw_kms_sou_bo_blit *blit = cmd; + + blit->header =SVGA_CMD_BLIT_GMRFB_TO_SCREEN ; + blit->body.destScreenId = update->du->unit; + blit->body.srcOrigin.x = fb_x; + blit->body.srcOrigin.y = fb_y; + blit->body.destRect.left = clip->x1; + blit->body.destRect.top = clip->y1; + blit->body.destRect.right = clip->x2; + blit->body.destRect.bottom = clip->y2; + +return sizeof (*blit); +} + +static uint32_t vmw_stud_bo_post_clip (struct vmw_du_update_plane *update, +void *cmd,struct drm_rect *bb) +{ +return 0 ; +} + +static void vmw_sou_bo_finish (struct vmw_du_update_plane *update) +{ +struct vmw_framebuffer_bo *vfbbo = +container_of (update->vfb,typeof (*vfbbo), base); + +vmw_kms_helper_buffer_finish (update->dev_priv,NULL , vfbbo->buffer, + update->out_fence,NULL ); +} + +static void vmw_sou_bo_revert (struct vmw_du_update_plane *update) +{ +struct vmw_framebuffer_bo *vfbbo = +container_of (update->vfb,typeof (*vfbbo), base); + +vmw_kms_helper_buffer_revert (vfbbo->buffer); +} + +/** +* vmw_sou_plane_update_bo - Update display unit for bo backed fb. +* @dev_priv: Device private. +* @plane: Plane state. +* @old_state: Old plane state. +* @vfb: Framebuffer which is blitted to display unit. +* @out_fence: If non-NULL, will return a ref-counted pointer to vmw_fence_obj. +* The returned fence pointer may be NULL in which case the device +* has already synchronized. +* +* RETURNS: 0 on success or a negative error code on failure. +*/ +static int vmw_sou_plane_update_bo (struct vmw_private *dev_priv, +struct drm_plane *plane, +struct drm_plane_state *old_state, +struct vmw_framebuffer *vfb, +struct vmw_fence_obj **out_fence) +{ +struct vmw_du_update_plane_buffer bo_update; + +memset (&bo_update,0 ,sizeof (struct vmw_du_update_plane_buffer )); + bo_update.base.plane = plane; + bo_update.base.old_state = old_state; + bo_update.base.dev_priv = dev_priv; + bo_update.base.du =vmw_crtc_to_du (plane->state->crtc); + bo_update.base.vfb = vfb; + bo_update.base.out_fence = out_fence; + + bo_update.cpu_blit = false; + + bo_update.base.prepare = vmw_sou_bo_prepare; + bo_update.base.calc_fifo_size = vmw_sou_bo_fifo_size; + bo_update.base.post_prepare = vmw_sou_bo_define_gmrfb; + bo_update.base.clip = vmw_sou_bo_populate_clip; + bo_update.base.post_clip = vmw_stud_bo_post_clip; + bo_update.base.finish = vmw_sou_bo_finish; + bo_update.base.revert = vmw_sou_bo_revert; + +return vmw_du_helper_plane_update (&bo_update.base); +} +static int vmw_sou_surface_prepare (struct vmw_du_update_plane *update) {struct vmw_du_update_plane_surface *srf_update;
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 14/18 drm/vmwgfx: Use the new interface for SOU plane update
In reply to Deepak RawatWith new interface to do plane update on SOU available, use that instead of old kms_dirty.
--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +5 -12
@@ -830,21 +830,14 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,struct vmw_private *dev_priv =vmw_priv (crtc->dev);struct vmw_framebuffer *vfb =vmw_framebuffer_to_vfb (plane->state->fb); -struct drm_vmw_rect vclips; - - vclips.x = crtc->x; - vclips.y = crtc->y; - vclips.w = crtc->mode.hdisplay; - vclips.h = crtc->mode.vdisplay;if (vfb->bo) - ret =vmw_kms_sou_do_bo_dirty (dev_priv, vfb,NULL , - &vclips,1 ,1 , true, - &fence, crtc); + ret =vmw_sou_plane_update_bo (dev_priv, plane, + old_state, vfb, &fence);else - ret =vmw_kms_sou_do_surface_dirty (dev_priv, vfb,NULL , - &vclips,NULL ,0 ,0 , -1 ,1 , &fence, crtc); + ret =vmw_sou_plane_update_surface (dev_priv, plane, + old_state, vfb, + &fence);/* * We cannot really fail this function, so if we do, then output
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 15/18 drm/vmwgfx: Update comments for sou plane update function
In reply to Deepak RawatUpdate comments to sync with code.
--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +3 -15
@@ -826,6 +826,7 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,struct vmw_fence_obj *fence =NULL ;int ret; +/* If somehow gets a device error maintain consistent atomic state */ if (crtc && plane->state->fb) {struct vmw_private *dev_priv =vmw_priv (crtc->dev); struct vmw_framebuffer *vfb =
@@ -838,28 +839,15 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane, ret =vmw_sou_plane_update_surface (dev_priv, plane, old_state, vfb, &fence); - -/* -* We cannot really fail this function, so if we do, then output -* an error and maintain consistent atomic state. -*/ if (ret !=0 )DRM_ERROR ("Failed to update screen.\n" ); }else { -/* -* When disabling a plane, CRTC and FB should always be NULL -* together, otherwise it's an error. -* Here primary plane is being disable so should really blank -* the screen object display unit, if not already done. -*/ +/* Do nothing when fb and crtc is NULL (blank crtc) */ return ; } +/* For error case vblank event is sent from vmw_du_crtc_atomic_flush */ event = crtc->state->event; -/* -* In case of failure and other cases, vblank event will be sent in -* vmw_du_crtc_atomic_flush. -*/ if (event && fence) {struct drm_file *file_priv = event->base.file_priv;
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 16/18 drm/vmwgfx: Enable FB_DAMAGE_CLIPS property for SOU primary plane
In reply to Deepak RawatSOU primary plane now support damage clips, enable it for user-space.
--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +2 -0
@@ -29,6 +29,7 @@#include <drm/drm_plane_helper.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_damage_helper.h> #define vmw_crtc_to_sou (x) \
@@ -964,6 +965,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) }drm_plane_helper_add (primary, &vmw_sou_primary_plane_helper_funcs); +drm_plane_enable_fb_damage_clips (primary);/* Initialize cursor plane */ vmw_du_plane_reset (cursor);
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 17/18 drm/vmwgfx: Use atomic helper function for dirty fb IOCTL
In reply to Deepak RawatUSe new atomic helper for dirty fb IOCTL which make use of damage interface. Note that this is only done for STDU and SOU, for legacy display unit still using old interface.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 82 +++++++---------------------- 1 file changed, 18 insertions(+), 64 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +18 -64
@@ -847,58 +847,6 @@ static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)kfree (vfbs); } -static int vmw_framebuffer_surface_dirty (struct drm_framebuffer *framebuffer, -struct drm_file *file_priv, -unsigned flags,unsigned color, -struct drm_clip_rect *clips, -unsigned num_clips) -{ -struct vmw_private *dev_priv =vmw_priv (framebuffer->dev); -struct vmw_framebuffer_surface *vfbs = -vmw_framebuffer_to_vfbs (framebuffer); -struct drm_clip_rect norect; -int ret, inc =1 ; - -/* Legacy Display Unit does not support 3D */ -if (dev_priv->active_display_unit == vmw_du_legacy) -return -EINVAL ; - -drm_modeset_lock_all (dev_priv->dev); - - ret =ttm_read_lock (&dev_priv->reservation_sem, true); -if (unlikely (ret !=0 )) { -drm_modeset_unlock_all (dev_priv->dev); -return ret; - } - -if (!num_clips) { - num_clips =1 ; - clips = &norect; - norect.x1 = norect.y1 =0 ; - norect.x2 = framebuffer->width; - norect.y2 = framebuffer->height; - }else if (flags &DRM_MODE_FB_DIRTY_ANNOTATE_COPY ) { - num_clips /=2 ; - inc =2 ;/* skip source rects */ - } - -if (dev_priv->active_display_unit == vmw_du_screen_object) - ret =vmw_kms_sou_do_surface_dirty (dev_priv, &vfbs->base, - clips,NULL ,NULL ,0 ,0 , - num_clips, inc,NULL ,NULL ); -else - ret =vmw_kms_stdu_surface_dirty (dev_priv, &vfbs->base, - clips,NULL ,NULL ,0 ,0 , - num_clips, inc,NULL ,NULL ); - -vmw_fifo_flush (dev_priv, false); -ttm_read_unlock (&dev_priv->reservation_sem); - -drm_modeset_unlock_all (dev_priv->dev); - -return 0 ; -} -/** * vmw_kms_readback - Perform a readback from the screen system to * a buffer-object backed framebuffer.
@@ -942,7 +890,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = { .destroy = vmw_framebuffer_surface_destroy, - .dirty = vmw_framebuffer_surface_dirty, + .dirty = drm_atomic_helper_dirtyfb, }; static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
@@ -1085,16 +1033,6 @@ static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer, }switch (dev_priv->active_display_unit) { -case vmw_du_screen_target: - ret =vmw_kms_stdu_dma (dev_priv,NULL , &vfbd->base,NULL , - clips,NULL , num_clips, increment, - true, true,NULL ); -break ; -case vmw_du_screen_object: - ret =vmw_kms_sou_do_bo_dirty (dev_priv, &vfbd->base, - clips,NULL , num_clips, - increment, true,NULL ,NULL ); -break ;case vmw_du_legacy: ret =vmw_kms_ldu_do_bo_dirty (dev_priv, &vfbd->base,0 ,0 , clips, num_clips, increment);
@@ -1113,9 +1051,25 @@ static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer,return ret; } +static int vmw_framebuffer_bo_dirty_ext (struct drm_framebuffer *framebuffer, +struct drm_file *file_priv, +unsigned int flags,unsigned int color, +struct drm_clip_rect *clips, +unsigned int num_clips) +{ +struct vmw_private *dev_priv =vmw_priv (framebuffer->dev); + +if (dev_priv->active_display_unit == vmw_du_legacy) +return vmw_framebuffer_bo_dirty (framebuffer, file_priv, flags, + color, clips, num_clips); + +return drm_atomic_helper_dirtyfb (framebuffer, file_priv, flags, color, + clips, num_clips); +} +static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = { .destroy = vmw_framebuffer_bo_destroy, - .dirty = vmw_framebuffer_bo_dirty, + .dirty = vmw_framebuffer_bo_dirty_ext, };/**
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 18/18 drm/vmwgfx: Don't clear mode::type anymore
In reply to Deepak RawatWith kernel commit 4f09c77b5c3b7, no need to clear mode::type for user-space bug.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 22 ---------------------- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 3 --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 2 +- 5 files changed, 3 insertions(+), 28 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +0 -22
@@ -2969,28 +2969,6 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv, } - -/** -* vmw_kms_set_config - Wrapper around drm_atomic_helper_set_config -* -* @set: The configuration to set. -* -* The vmwgfx Xorg driver doesn't assign the mode::type member, which -* when drm_mode_set_crtcinfo is called as part of the configuration setting -* causes it to return incorrect crtc dimensions causing severe problems in -* the vmwgfx modesetting. So explicitly clear that member before calling -* into drm_atomic_helper_set_config. -*/ -int vmw_kms_set_config (struct drm_mode_set *set, -struct drm_modeset_acquire_ctx *ctx) -{ -if (set && set->mode) - set->mode->type =0 ; - -return drm_atomic_helper_set_config (set, ctx); -} - -/** * vmw_kms_suspend - Save modesetting state and turn modesetting off. *
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +0 -3
@@ -602,9 +602,6 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,bool interruptible, struct drm_crtc *crtc); -int vmw_kms_set_config (struct drm_mode_set *set, -struct drm_modeset_acquire_ctx *ctx); -int vmw_du_helper_plane_update (struct vmw_du_update_plane *update);/**
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +1 -1
@@ -233,7 +233,7 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { .reset = vmw_du_crtc_reset, .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, - .set_config = vmw_kms_set_config, + .set_config = drm_atomic_helper_set_config, };
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +1 -1
@@ -353,7 +353,7 @@ static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { .reset = vmw_du_crtc_reset, .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, - .set_config = vmw_kms_set_config, + .set_config = drm_atomic_helper_set_config, .page_flip = vmw_sou_crtc_page_flip, };
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +1 -1
@@ -973,7 +973,7 @@ static const struct drm_crtc_funcs vmw_stdu_crtc_funcs = { .reset = vmw_du_crtc_reset, .atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_destroy_state = vmw_du_crtc_destroy_state, - .set_config = vmw_kms_set_config, + .set_config = drm_atomic_helper_set_config, .page_flip = vmw_stdu_crtc_page_flip, };
Signature · 6 lines
2.17.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel