Re: [PATCH RFC v6 01/10] drm: Introduce pixel_source DRM plane property

2023-09-24 Thread Dmitry Baryshkov

On 29/08/2023 03:05, Jessica Zhang wrote:

Add support for pixel_source property to drm_plane and related
documentation. In addition, force pixel_source to
DRM_PLANE_PIXEL_SOURCE_FB in DRM_IOCTL_MODE_SETPLANE as to not break
legacy userspace.

This enum property will allow user to specify a pixel source for the
plane. Possible pixel sources will be defined in the
drm_plane_pixel_source enum.

Currently, the only pixel sources are DRM_PLANE_PIXEL_SOURCE_FB (the
default value) and DRM_PLANE_PIXEL_SOURCE_NONE.

Signed-off-by: Jessica Zhang 


Acked-by: Dmitry Baryshkov 

Minor question below


---
  drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++
  drivers/gpu/drm/drm_blend.c   | 90 +++
  drivers/gpu/drm/drm_plane.c   | 19 +--
  include/drm/drm_blend.h   |  2 +
  include/drm/drm_plane.h   | 21 
  6 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 784e63d70a42..01638c51ce0a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct 
drm_plane_state *plane_state,
  
  	plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;

plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
+   plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
  
  	if (plane->color_encoding_property) {

if (!drm_object_property_get_default_value(&plane->base,
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d867e7f9f2cd..454f980e16c9 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -544,6 +544,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
state->src_w = val;
} else if (property == config->prop_src_h) {
state->src_h = val;
+   } else if (property == plane->pixel_source_property) {
+   state->pixel_source = val;
} else if (property == plane->alpha_property) {
state->alpha = val;
} else if (property == plane->blend_mode_property) {
@@ -616,6 +618,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
*val = state->src_w;
} else if (property == config->prop_src_h) {
*val = state->src_h;
+   } else if (property == plane->pixel_source_property) {
+   *val = state->pixel_source;
} else if (property == plane->alpha_property) {
*val = state->alpha;
} else if (property == plane->blend_mode_property) {
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 6e74de833466..c3c57bae06b7 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -185,6 +185,21 @@
   * plane does not expose the "alpha" property, then this is
   * assumed to be 1.0
   *
+ * pixel_source:
+ * pixel_source is set up with drm_plane_create_pixel_source_property().
+ * It is used to toggle the active source of pixel data for the plane.
+ * The plane will only display data from the set pixel_source -- any
+ * data from other sources will be ignored.
+ *
+ * Possible values:
+ *
+ * "NONE":
+ * No active pixel source.
+ * Committing with a NONE pixel source will disable the plane.
+ *
+ * "FB":
+ * Framebuffer source set by the "FB_ID" property.
+ *
   * Note that all the property extensions described here apply either to the
   * plane or the CRTC (e.g. for the background color, which currently is not
   * exposed and assumed to be black).
@@ -615,3 +630,78 @@ int drm_plane_create_blend_mode_property(struct drm_plane 
*plane,
return 0;
  }
  EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
+
+static const struct drm_prop_enum_list drm_pixel_source_enum_list[] = {
+   { DRM_PLANE_PIXEL_SOURCE_NONE, "NONE" },
+   { DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
+};
+
+/**
+ * drm_plane_create_pixel_source_property - create a new pixel source property
+ * @plane: DRM plane
+ * @extra_sources: Bitmask of additional supported pixel_sources for the 
driver.
+ *DRM_PLANE_PIXEL_SOURCE_FB and DRM_PLANE_PIXEL_SOURCE_NONE 
will
+ *always be enabled as supported sources.
+ *
+ * This creates a new property describing the current source of pixel data for 
the
+ * plane. The pixel_source will be initialized as DRM_PLANE_PIXEL_SOURCE_FB by 
default.
+ *
+ * Drivers can set a custom default source by overriding the pixel_source 
value in
+ * drm_plane_funcs.reset()
+ *
+ * The property is exposed to userspace as an enumeration property called
+ * "pixel_source" and has the following enumeration values:
+ *
+ * "NONE":
+ *  No active pixel source
+ *
+ * 

Re: [PATCH RFC v6 04/10] drm/atomic: Add pixel source to plane state dump

2023-09-24 Thread Dmitry Baryshkov

On 29/08/2023 03:05, Jessica Zhang wrote:

Add pixel source to the atomic plane state dump

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic.c| 1 +
  drivers/gpu/drm/drm_blend.c | 1 +
  drivers/gpu/drm/drm_crtc_internal.h | 1 +
  3 files changed, 3 insertions(+)


Reviewed-by: Dmitry Baryshkov 


--
With best wishes
Dmitry



Re: [PATCH RFC v6 05/10] drm/atomic: Add solid fill data to plane state dump

2023-09-24 Thread Dmitry Baryshkov

On 29/08/2023 03:05, Jessica Zhang wrote:

Add solid_fill property data to the atomic plane state dump.

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic.c | 4 
  drivers/gpu/drm/drm_plane.c  | 8 
  include/drm/drm_plane.h  | 3 +++
  3 files changed, 15 insertions(+)


Reviewed-by: Dmitry Baryshkov 


--
With best wishes
Dmitry



Re: [PATCH RFC v6 07/10] drm/atomic: Loosen FB atomic checks

2023-09-24 Thread Dmitry Baryshkov

On 29/08/2023 03:05, Jessica Zhang wrote:

Loosen the requirements for atomic and legacy commit so that, in cases
where pixel_source != FB, the commit can still go through.

This includes adding framebuffer NULL checks in other areas to account for
FB being NULL when non-FB pixel sources are enabled.

To disable a plane, the pixel_source must be NONE or the FB must be NULL
if pixel_source == FB.

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic.c| 20 +++-
  drivers/gpu/drm/drm_atomic_helper.c | 36 
  include/drm/drm_atomic_helper.h |  4 ++--
  include/drm/drm_plane.h | 29 +
  4 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index cc0e93d19e15..cdc6cfedd433 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct 
drm_plane_state *old_plane_state,
const struct drm_framebuffer *fb = new_plane_state->fb;
int ret;
  
-	/* either *both* CRTC and FB must be set, or neither */

-   if (crtc && !fb) {
-   drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
+   /* either *both* CRTC and pixel source must be set, or neither */
+   if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
+   drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no visible 
data\n",
   plane->base.id, plane->name);
return -EINVAL;
-   } else if (fb && !crtc) {
-   drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
-  plane->base.id, plane->name);
+   } else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
+   drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has visible data 
but no CRTC\n",
+  plane->base.id, plane->name, 
new_plane_state->pixel_source);
return -EINVAL;
}
  
@@ -706,9 +706,11 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,

}
  
  
-	ret = drm_atomic_plane_check_fb(new_plane_state);

-   if (ret)
-   return ret;
+   if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {


Nit: could you please be more specific here? Drop the fb variable and 
use new_plane_state->fb directly.



+   ret = drm_atomic_plane_check_fb(new_plane_state);
+   if (ret)
+   return ret;
+   }
  
  	if (plane_switching_crtc(old_plane_state, new_plane_state)) {

drm_dbg_atomic(plane->dev,
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 41b8066f61ff..a176064ee27e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
*src = drm_plane_state_src(plane_state);
*dst = drm_plane_state_dest(plane_state);
  
-	if (!fb) {

+   if (!drm_plane_has_visible_data(plane_state)) {
plane_state->visible = false;
return 0;
}
@@ -881,25 +881,29 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
return -EINVAL;
}
  
-	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);

+   if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {



And here too. Could you please move fb var into the condition?

Other than that LGTM



+   drm_rect_rotate(src, fb->width << 16, fb->height << 16, 
rotation);
  
-	/* Check scaling */

-   hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
-   vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
-   if (hscale < 0 || vscale < 0) {
-   drm_dbg_kms(plane_state->plane->dev,
-   "Invalid scaling of plane\n");
-   drm_rect_debug_print("src: ", &plane_state->src, true);
-   drm_rect_debug_print("dst: ", &plane_state->dst, false);
-   return -ERANGE;
-   }
+   /* Check scaling */
+   hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+   vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
  
-	if (crtc_state->enable)

-   drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
+   if (hscale < 0 || vscale < 0) {
+   drm_dbg_kms(plane_state->plane->dev,
+   "Invalid scaling of plane\n");
+   drm_rect_debug_print("src: ", &plane_state->src, true);
+   drm_rect_debug_print("dst: ", &plane_state->dst, false);
+   return -ERANGE;
+   

Re: [Freedreno] [PATCH RFC v6 07/10] drm/atomic: Loosen FB atomic checks

2023-09-24 Thread Dmitry Baryshkov

On 22/09/2023 20:49, Jessica Zhang wrote:



On 8/29/2023 1:22 AM, Pekka Paalanen wrote:

On Mon, 28 Aug 2023 17:05:13 -0700
Jessica Zhang  wrote:


Loosen the requirements for atomic and legacy commit so that, in cases
where pixel_source != FB, the commit can still go through.

This includes adding framebuffer NULL checks in other areas to 
account for

FB being NULL when non-FB pixel sources are enabled.

To disable a plane, the pixel_source must be NONE or the FB must be NULL
if pixel_source == FB.

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic.c    | 20 +++-
  drivers/gpu/drm/drm_atomic_helper.c | 36 


  include/drm/drm_atomic_helper.h |  4 ++--
  include/drm/drm_plane.h | 29 +
  4 files changed, 62 insertions(+), 27 deletions(-)


...


diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index a58f84b6bd5e..4c5b7bcdb25c 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -992,6 +992,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_solid_fill_enabled - Check if solid fill is enabled on 
plane

+ * @state: plane state
+ *
+ * Returns:
+ * Whether the plane has been assigned a solid_fill_blob
+ */
+static inline bool drm_plane_solid_fill_enabled(struct 
drm_plane_state *state)

+{
+    if (!state)
+    return false;
+    return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_SOLID_FILL 
&& state->solid_fill_blob;

+}
+
+static inline bool drm_plane_has_visible_data(const struct 
drm_plane_state *state)

+{
+    switch (state->pixel_source) {
+    case DRM_PLANE_PIXEL_SOURCE_NONE:
+    return false;
+    case DRM_PLANE_PIXEL_SOURCE_SOLID_FILL:
+    return state->solid_fill_blob != NULL;


This reminds me, new UAPI docs did not say what the requirements are for
choosing solid fill pixel source. Is the atomic commit rejected if
pixel source is solid fill, but solid_fill property has no blob?


Hi Pekka,

Yes, if pixel_source is solid_fill and the solid_fill property blob 
isn't set, the atomic commit should throw an error.


Will document this in the UAPI.


I don't see a corresponding error check in atomic_check() functions. 
Could you please check that there is one, as you are updating the uAPI.




Thanks,

Jessica Zhang



This should be doc'd.


Thanks,
pq


+    case DRM_PLANE_PIXEL_SOURCE_FB:
+    default:
+    WARN_ON(state->pixel_source != DRM_PLANE_PIXEL_SOURCE_FB);
+    }
+
+    return state->fb != NULL;
+}
+
  bool drm_any_plane_has_format(struct drm_device *dev,
    u32 format, u64 modifier);





--
With best wishes
Dmitry



Re: [PATCH RFC v6 08/10] drm/msm/dpu: Allow NULL FBs in atomic commit

2023-09-24 Thread Dmitry Baryshkov

On 29/08/2023 03:05, Jessica Zhang wrote:

Since solid fill planes allow for a NULL framebuffer in a valid commit,
add NULL framebuffer checks to atomic commit calls within DPU.

Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++-
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 41 ---
  2 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 8ce7586e2ddf..5e845510e8c1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
struct drm_plane_state *state;
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
struct dpu_plane_state *pstate = NULL;
+   const struct msm_format *fmt;
struct dpu_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
  
@@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,

pstate = to_dpu_plane_state(state);
fb = state->fb;
  
-		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));

+   if (drm_plane_solid_fill_enabled(state))
+   fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
+   DRM_FORMAT_ABGR, 0);
+   else
+   fmt = msm_framebuffer_format(pstate->base.fb);
+
+   format = to_dpu_format(fmt);
  
  		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)

bg_alpha_enable = true;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c2aaaded07ed..114c803ff99b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -837,8 +837,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
  
  	pipe_cfg->dst_rect = new_plane_state->dst;
  
-	fb_rect.x2 = new_plane_state->fb->width;

-   fb_rect.y2 = new_plane_state->fb->height;
+   if (drm_plane_solid_fill_enabled(new_plane_state))
+   return 0;


This would skip all the width checks, dpu_plane_atomic_check_pipe(), 
etc. Could you please confirm that all of those checks are irrelevant 
for solid fill?



+
+   if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && 
new_plane_state->fb) {
+   fb_rect.x2 = new_plane_state->fb->width;
+   fb_rect.y2 = new_plane_state->fb->height;
+   }
  
  	/* Ensure fb size is supported */

if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
@@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
bool is_rt_pipe;
-   const struct dpu_format *fmt =
-   to_dpu_format(msm_framebuffer_format(fb));
+   const struct dpu_format *fmt;
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
struct msm_gem_address_space *aspace = kms->base.aspace;
struct dpu_hw_fmt_layout layout;
bool layout_valid = false;
-   int ret;
  
-	ret = dpu_format_populate_layout(aspace, fb, &layout);

-   if (ret)
-   DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-   else
-   layout_valid = true;
+   if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+   int ret;
+
+   fmt = to_dpu_format(msm_framebuffer_format(fb));
+
+   ret = dpu_format_populate_layout(aspace, fb, &layout);
+   if (ret)
+   DPU_ERROR_PLANE(pdpu, "failed to get format layout, 
%d\n", ret);
+   else
+   layout_valid = true;
+
+   DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " 
DRM_RECT_FMT
+   ", %4.4s ubwc %d\n", fb->base.id, 
DRM_RECT_FP_ARG(&state->src),
+   crtc->base.id, DRM_RECT_ARG(&state->dst),
+   (char *)&fmt->base.pixel_format, 
DPU_FORMAT_IS_UBWC(fmt));
+   } else {
+   fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR);


#define DPU_SOLID_FILL_FORMAT ?

Also, I don't think that solid_fill planes consume bandwidth, so this 
likely needs to be fixed too.




+   }
  
  	pstate->pending = true;
  
@@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)

pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
pdpu->is_rt_pipe = is_rt_pipe;
  
-	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT

-