Re: [RFC PATCH v4 09/42] drm/colorop: Introduce new drm_colorop mode object

2024-05-21 Thread Melissa Wen
On 02/26, Harry Wentland wrote:
> This patches introduces a new drm_colorop mode object. This
> object represents color transformations and can be used to
> define color pipelines.
> 
> We also introduce the drm_colorop_state here, as well as
> various helpers and state tracking bits.
> 
> v4:
>  - Drop IOCTL definitions (Pekka)
>  - add missing declaration (Chaitanya Kumar Borah)
> 
> v3:
>  - Drop TODO for lock (it's handled in drm_modeset_drop_locks)
>(Melissa)
>  - Don't get plane state when getting colorop state
>  - Make some functions static (kernel test robot)
> 
> Signed-off-by: Harry Wentland 
> ---
>  drivers/gpu/drm/Makefile|   1 +
>  drivers/gpu/drm/drm_atomic.c|  70 
>  drivers/gpu/drm/drm_atomic_helper.c |  12 +++
>  drivers/gpu/drm/drm_atomic_uapi.c   |  48 +
>  drivers/gpu/drm/drm_colorop.c   | 152 ++
>  drivers/gpu/drm/drm_mode_config.c   |   7 ++
>  include/drm/drm_atomic.h|  82 +++
>  include/drm/drm_atomic_uapi.h   |   1 +
>  include/drm/drm_colorop.h   | 158 
>  include/drm/drm_mode_config.h   |  18 
>  include/drm/drm_plane.h |   2 +
>  include/uapi/drm/drm_mode.h |   1 +
>  12 files changed, 552 insertions(+)
>  create mode 100644 drivers/gpu/drm/drm_colorop.c
>  create mode 100644 include/drm/drm_colorop.h
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 104b42df2e95..4b14dcbb6117 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -16,6 +16,7 @@ drm-y := \
>   drm_client.o \
>   drm_client_modeset.o \
>   drm_color_mgmt.o \
> + drm_colorop.o \
>   drm_connector.o \
>   drm_crtc.o \
>   drm_displayid.o \
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index a91737adf8e7..62e87e6a9653 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -42,6 +42,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "drm_crtc_internal.h"
>  #include "drm_internal.h"
> @@ -108,6 +109,7 @@ void drm_atomic_state_default_release(struct 
> drm_atomic_state *state)
>   kfree(state->connectors);
>   kfree(state->crtcs);
>   kfree(state->planes);
> + kfree(state->colorops);
>   kfree(state->private_objs);
>  }
>  EXPORT_SYMBOL(drm_atomic_state_default_release);
> @@ -139,6 +141,10 @@ drm_atomic_state_init(struct drm_device *dev, struct 
> drm_atomic_state *state)
>   sizeof(*state->planes), GFP_KERNEL);
>   if (!state->planes)
>   goto fail;
> + state->colorops = kcalloc(dev->mode_config.num_colorop,
> +   sizeof(*state->colorops), GFP_KERNEL);
> + if (!state->colorops)
> + goto fail;
>  
>   /*
>* Because drm_atomic_state can be committed asynchronously we need our
> @@ -250,6 +256,20 @@ void drm_atomic_state_default_clear(struct 
> drm_atomic_state *state)
>   state->planes[i].new_state = NULL;
>   }
>  
> + for (i = 0; i < config->num_colorop; i++) {
> + struct drm_colorop *colorop = state->colorops[i].ptr;
> +
> + if (!colorop)
> + continue;
> +
> + drm_colorop_atomic_destroy_state(colorop,
> +  state->colorops[i].state);
> + state->colorops[i].ptr = NULL;
> + state->colorops[i].state = NULL;
> + state->colorops[i].old_state = NULL;
> + state->colorops[i].new_state = NULL;
> + }
> +
>   for (i = 0; i < state->num_private_objs; i++) {
>   struct drm_private_obj *obj = state->private_objs[i].ptr;
>  
> @@ -571,6 +591,56 @@ drm_atomic_get_plane_state(struct drm_atomic_state 
> *state,
>  }
>  EXPORT_SYMBOL(drm_atomic_get_plane_state);
>  
> +
> +/**
> + * drm_atomic_get_colorop_state - get colorop state
> + * @state: global atomic state object
> + * @colorop: colorop to get state object for
> + *
> + * This function returns the colorop state for the given colorop, allocating 
> it
> + * if needed. It will also grab the relevant plane lock to make sure that the
> + * state is consistent.
> + *
> + * Returns:
> + *
> + * Either the allocated state or the error code encoded into the pointer. 
> When
> + * the error is EDEADLK then the w/w mutex code has detected a deadlock and 
> the
> + * entire atomic sequence must be restarted. All other errors are fatal.
> + */
> +struct drm_colorop_state *
> +drm_atomic_get_colorop_state(struct drm_atomic_state *state,
> +  struct drm_colorop *colorop)
> +{
> + int ret, index = drm_colorop_index(colorop);
> + struct drm_colorop_state *colorop_state;
> +
> + WARN_ON(!state->acquire_ctx);
> +
> + colorop_state = drm_atomic_get_existing_colorop_state(state, colorop);
> + if (colorop_state)
> +  

Re: [RFC PATCH v4 41/42] drm/colorop: Add mutliplier type

2024-05-21 Thread Melissa Wen
On 02/26, Harry Wentland wrote:
> From: Alex Hung 
> 
> This introduces a new drm_colorop_type: DRM_COLOROP_MULTIPLIER.
> 
> It's a simple multiplier to all pixel values. The value is
> specified via a S31.32 fixed point provided via the
> "MULTIPLIER" property.
> 
> Signed-off-by: Alex Hung 
> ---
>  drivers/gpu/drm/drm_atomic.c  |  3 +++
>  drivers/gpu/drm/drm_atomic_uapi.c |  4 
>  drivers/gpu/drm/drm_colorop.c | 29 +++--
>  include/drm/drm_colorop.h | 16 
>  include/uapi/drm/drm_mode.h   |  1 +
>  5 files changed, 51 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index f7d51839ca03..af0b6338a55c 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -806,6 +806,9 @@ static void drm_atomic_colorop_print_state(struct 
> drm_printer *p,
>   case DRM_COLOROP_CTM_3X4:
>   drm_printf(p, "\tdata blob id=%d\n", state->data ? 
> state->data->base.id : 0);
>   break;
> + case DRM_COLOROP_MULTIPLIER:
> + drm_printf(p, "\tmultiplier=%u\n", state->multiplier);

Compiler complains of unsigned int instead of llu.

> + break;
>   default:
>   break;
>   }
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> b/drivers/gpu/drm/drm_atomic_uapi.c
> index 6bfe857720cd..b4ecda563728 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -727,6 +727,8 @@ static int drm_atomic_colorop_set_property(struct 
> drm_colorop *colorop,
>   state->bypass = val;
>   } else if (property == colorop->curve_1d_type_property) {
>   state->curve_1d_type = val;
> + } else if (property == colorop->multiplier_property) {
> + state->multiplier = val;
>   } else if (property == colorop->data_property) {
>   return drm_atomic_color_set_data_property(colorop,
>   state, property, val);
> @@ -752,6 +754,8 @@ drm_atomic_colorop_get_property(struct drm_colorop 
> *colorop,
>   *val = state->bypass;
>   } else if (property == colorop->curve_1d_type_property) {
>   *val = state->curve_1d_type;
> + } else if (property == colorop->multiplier_property) {
> + *val = state->multiplier;
>   } else if (property == colorop->size_property) {
>   *val = state->size;
>   } else if (property == colorop->data_property) {
> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
> index 4452eaeeb242..c6cdd743de51 100644
> --- a/drivers/gpu/drm/drm_colorop.c
> +++ b/drivers/gpu/drm/drm_colorop.c
> @@ -35,7 +35,8 @@
>  static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
>   { DRM_COLOROP_1D_CURVE, "1D Curve" },
>   { DRM_COLOROP_1D_LUT, "1D Curve Custom LUT" },
> - { DRM_COLOROP_CTM_3X4, "3x4 Matrix"}
> + { DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
> + { DRM_COLOROP_MULTIPLIER, "Multiplier"},
>  };
>  
>  static const char * const colorop_curve_1d_type_names[] = {
> @@ -231,6 +232,29 @@ int drm_colorop_ctm_3x4_init(struct drm_device *dev, 
> struct drm_colorop *colorop
>  }
>  EXPORT_SYMBOL(drm_colorop_ctm_3x4_init);
>  
> +int drm_colorop_mult_init(struct drm_device *dev, struct drm_colorop 
> *colorop,
> +   struct drm_plane *plane)
> +{
> + struct drm_property *prop;
> + int ret;
> +
> + ret = drm_colorop_init(dev, colorop, plane, DRM_COLOROP_MULTIPLIER);
> + if (ret)
> + return ret;
> +
> + prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, 
> "MULTIPLIER", 0, U64_MAX);
> + if (!prop)
> + return -ENOMEM;
> +
> + colorop->multiplier_property = prop;
> + drm_object_attach_property(&colorop->base, 
> colorop->multiplier_property, 0);
> +
> + drm_colorop_reset(colorop);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_colorop_mult_init);
> +
>  static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop 
> *colorop,
>   struct 
> drm_colorop_state *state)
>  {
> @@ -333,7 +357,8 @@ EXPORT_SYMBOL(drm_colorop_reset);
>  static const char * const colorop_type_name[] = {
>   [DRM_COLOROP_1D_CURVE] = "1D Curve",
>   [DRM_COLOROP_1D_LUT] = "1D Curve Custom LUT",
> - [DRM_COLOROP_CTM_3X4] = "3x4 Matrix"
> + [DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
> + [DRM_COLOROP_MULTIPLIER] = "Multiplier",
>  };
>  
>  /**
> diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
> index 8adc7ece3bd1..f9f83644cc9f 100644
> --- a/include/drm/drm_colorop.h
> +++ b/include/drm/drm_colorop.h
> @@ -64,6 +64,13 @@ struct drm_colorop_state {
>*/
>   enum drm_colorop_curve_1d_type curve_1d_type;
>  
> + /**
> +  * @multiplier:
> +  *
> +  * Multiplier to 'gain' the plane. Format is S31.32 sign-magnitude.
> + 

Re: [RFC PATCH v4 31/42] drm/amd/display: Add support for sRGB EOTF in DEGAM block

2024-05-21 Thread Melissa Wen
On 02/26, Harry Wentland wrote:
> From: Alex Hung 
> 
> Expose one 1D curve colorop with support for
> DRM_COLOROP_1D_CURVE_SRGB_EOTF and program HW to perform
> the sRGB transform when the colorop is not in bypass.
> 
> With this change the following IGT test passes:
> kms_colorop --run plane-XR30-XR30-srgb_eotf
> 
> The color pipeline now consists of a single colorop:
> 1. 1D curve colorop w/ sRGB EOTF
> 
> Signed-off-by: Alex Hung 
> Signed-off-by: Harry Wentland 
> Co-developed-by: Harry Wentland 
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/Makefile|  3 +-
>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 88 +++
>  .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 58 
>  .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h | 34 +++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 10 +++
>  5 files changed, 192 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
>  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> index ab2a97e354da..46158d67ab12 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> @@ -38,7 +38,8 @@ AMDGPUDM = \
>   amdgpu_dm_pp_smu.o \
>   amdgpu_dm_psr.o \
>   amdgpu_dm_replay.o \
> - amdgpu_dm_wb.o
> + amdgpu_dm_wb.o \
> + amdgpu_dm_colorop.o
>  
>  ifdef CONFIG_DRM_AMD_DC_FP
>  AMDGPUDM += dc_fpu.o
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> index 9b527bffe11a..3ec759934669 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> @@ -668,6 +668,19 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
>   }
>  }
>  
> +static enum dc_transfer_func_predefined
> +amdgpu_colorop_tf_to_dc_tf(enum drm_colorop_curve_1d_type tf)
> +{
> + switch (tf)
> + {
> + case DRM_COLOROP_1D_CURVE_SRGB_EOTF:
> + case DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF:
> + return TRANSFER_FUNCTION_SRGB;
> + default:
> + return TRANSFER_FUNCTION_LINEAR;;
> + }
> +}
> +
>  static void __to_dc_lut3d_color(struct dc_rgb *rgb,
>   const struct drm_color_lut lut,
>   int bit_precision)
> @@ -1137,6 +1150,59 @@ __set_dm_plane_degamma(struct drm_plane_state 
> *plane_state,
>   return 0;
>  }
>  
> +static int
> +__set_colorop_in_tf_1d_curve(struct dc_plane_state *dc_plane_state,
> +struct drm_colorop_state *colorop_state)
> +{
> + struct dc_transfer_func *tf = dc_plane_state->in_transfer_func;

For this patch and the next two, it ^ should be:
`&dc_plane_state->in_transfer_func` (same for shape and blend), right?

> + struct drm_colorop *colorop = colorop_state->colorop;
> + struct drm_device *drm = colorop->dev;
> +
> + if (colorop->type != DRM_COLOROP_1D_CURVE &&
> + colorop_state->curve_1d_type != DRM_COLOROP_1D_CURVE_SRGB_EOTF)
> + return -EINVAL;
> +
> + if (colorop_state->bypass) {
> + tf->type = TF_TYPE_BYPASS;
> + tf->tf = TRANSFER_FUNCTION_LINEAR;
> + return 0;
> + }
> +
> + drm_dbg(drm, "Degamma colorop with ID: %d\n", colorop->base.id);
> +
> + tf->type = TF_TYPE_PREDEFINED;
> + tf->tf = amdgpu_colorop_tf_to_dc_tf(colorop_state->curve_1d_type);
> +
> + return 0;
> +}
> +
> +static int
> +__set_dm_plane_colorop_degamma(struct drm_plane_state *plane_state,
> +struct dc_plane_state *dc_plane_state,
> +struct drm_colorop *colorop)
> +{
> + struct drm_colorop *old_colorop;
> + struct drm_colorop_state *colorop_state = NULL, *new_colorop_state;
> + struct drm_atomic_state *state = plane_state->state;
> + int i = 0;
> +
> + old_colorop = colorop;
> +
> + /* 1st op: 1d curve - degamma */
> + for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
> + if (new_colorop_state->colorop == old_colorop &&
> + new_colorop_state->curve_1d_type == 
> DRM_COLOROP_1D_CURVE_SRGB_EOTF) {
> + colorop_state = new_colorop_state;
> + break;
> + }
> + }
> +
> + if (!colorop_state)
> + return -EINVAL;
> +
> + return __set_colorop_in_tf_1d_curve(dc_plane_state, colorop_state);
> +}
> +
>  static int
>  amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
>struct dc_plane_state *dc_plane_state)
> @@ -1187,6 +1253,25 @@ amdgpu_dm_plane_set_color_properties(struct 
> drm_plane_state *plane_state,
>   return 0;
>  }
>  
> +static int
> +amdgpu_dm_plane_set_colorop_properties(struct d

Re: [RFC PATCH v4 00/42] Color Pipeline API w/ VKMS

2024-05-21 Thread Melissa Wen
On 02/26, Harry Wentland wrote:
> This is an RFC set for a color pipeline API, along with a sample
> implementation in VKMS. All the key API bits are here. VKMS now
> supports two named transfer function colorops and two matrix
> colorops. We have IGT tests that check all four of these colorops
> with a pixel-by-pixel comparison that checks that these colorops
> do what we expect them to do with a +/- 1 8 bpc code point margin.
> 
> The big new change with v4 is the addition of an amdgpu color
> pipeline, for all AMD GPUs with DCN 3 and newer. Amdgpu now support
> the following:
> 
> 1. 1D Curve EOTF
> 2. 3x4 CTM
> 3. Multiplier
> 4. 1D Curve Inverse EOTF
> 5. 1D LUT
> 6. 1D Curve EOTF
> 7. 1D LUT
> 
> The supported curves for the 1D Curve type are:
> - sRGB EOTF and its inverse
> - PQ EOTF, scaled to [0.0, 125.0] and its inverse
> - BT.2020/BT.709 OETF and its inverse
> 
> Note that the 1st and 5th colorops take the EOTF or Inverse
> OETF while the 3rd colorop takes the Inverse EOTF or OETF.
> 
> We are working on two more ops for amdgpu, the HDR multiplier
> and the 3DLUT, which will give us this:
> 
> 1. 1D Curve EOTF
> 2. 3x4 CTM
> 3. HDR Multiplier
> 4. 1D Curve Inverse EOTF
> 5. 1D LUT
> 6. 3D LUT
> 7. 1D Curve EOTF
> 8. 1D LUT
> 
> This, essentially mirrors the color pipeline used by gamescope
> and presented by Melissa Wen, with the exception of the DEGAM
> LUT, which is not currently used. See
> [1] 
> https://indico.freedesktop.org/event/4/contributions/186/attachments/138/218/xdc2023-TheRainbowTreasureMap-MelissaWen.pdf
> 
> After this we'd like to also add the following ops:
> - Scaler (Informational only)
> - Color Encoding, to replace drm_plane's COLOR_ENCODING
> - Color Range, to replace drm_plane's COLOR_RANGE
> 
> This patchset is grouped as follows:
>  - Patches 1-3: couple general patches/fixes
>  - Patches 4-7: introduce kunit to VKMS
>  - Patch 7: description of motivation and details behind the
> Color Pipeline API. If you're reading nothing else
> but are interested in the topic I highly recommend
> you take a look at this.
>  - Patches 7-27: DRM core and VKMS changes for color pipeline API
>  - Patches 28-40: DRM core and amdgpu changes for color pipeline API
> 
> VKMS patches could still be improved in a few ways, though the
> payoff might be limited and I would rather focus on other work
> at the moment. The most obvious thing to improve would be to
> eliminate the hard-coded LUTs for identity, and sRGB, and replace
> them with fixed-point math instead.
> 
> There are plenty of things that I would like to see here but
> haven't had a chance to look at. These will (hopefully) be
> addressed in future iterations, either in VKMS or amdgpu:
>  - Clear documentation for each drm_colorop_type
>  - Add custom LUT colorops to VKMS
>  - Add pre-blending 3DLUT
>  - How to support HW which can't bypass entire pipeline?
>  - Add ability to create colorops that don't have BYPASS
>  - Can we do a LOAD / COMMIT model for LUTs (and other properties)?
>  - read-only scaling colorop which defines scaling taps and position
>  - read-only color format colorop to define supported color formats
>for a pipeline
>  - named matrices, for things like converting YUV to RGB
> 
> IGT tests can be found at
> https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/merge_requests/1
> 
> IGT patches are also being sent to the igt-dev mailing list.
> 
> If you prefer a gitlab MR for review you can find it at
> https://gitlab.freedesktop.org/hwentland/linux/-/merge_requests/5
> 
> v4:

Hey,

I'm not sure if this is the latest version, but this is the one I'm
using now. I just pointed out some minor issues that I found when
applying this series for testing, so I won't forget to report. But I'm
still performing tests and validations on my side.

Melissa

>  - Add amdgpu color pipeline (WIP)
>  - Don't block setting of deprecated properties, instead pass client cap
>to atomic check so drivers can ignore these props
>  - Drop IOCTL definitions (Pekka)
>  - Use enum property for colorop TYPE (Pekka)
>  - A few cleanups to the docs (Pekka)
>  - Rework the TYPE enum to name relation to avoid code duplication (Pekka)
>  - Add missing function declarations (Chaitanya Kumar Borah)
>  - Allow setting of NEXT property to NULL in _set_ function (Chaitanya Kumar 
> Borah)
>  - Add helper for creation of pipeline drm_plane property (Pekka)
>  - Always create Bypass pipeline (Pekka)
>  - A bunch of changes to VKMS kunit tests (Pekka)
>  - Fix index in CTM doc (Pekka)
> 
> v3:
>  - Abandon IOCTLs and discover colorops as clients iterate the pipeline
>  - Remove need for libdrm
>  - Add color_pipeline client cap and make mutually exclusive with
>COLOR_RANGE and COLOR_ENCODING properties
>  - add CTM colorop to VKMS
>  - Use include way for kunit testing static functions (Arthur)
>  - Make TYPE a range property
>  - Move enum drm_colorop_type to uapi header
>  - and a bunch of smaller 

Re: [RFC PATCH v4 31/42] drm/amd/display: Add support for sRGB EOTF in DEGAM block

2024-05-21 Thread Melissa Wen
On 05/21, Melissa Wen wrote:
> On 02/26, Harry Wentland wrote:
> > From: Alex Hung 
> > 
> > Expose one 1D curve colorop with support for
> > DRM_COLOROP_1D_CURVE_SRGB_EOTF and program HW to perform
> > the sRGB transform when the colorop is not in bypass.
> > 
> > With this change the following IGT test passes:
> > kms_colorop --run plane-XR30-XR30-srgb_eotf
> > 
> > The color pipeline now consists of a single colorop:
> > 1. 1D curve colorop w/ sRGB EOTF
> > 
> > Signed-off-by: Alex Hung 
> > Signed-off-by: Harry Wentland 
> > Co-developed-by: Harry Wentland 
> > ---
> >  .../gpu/drm/amd/display/amdgpu_dm/Makefile|  3 +-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 88 +++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 58 
> >  .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h | 34 +++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 10 +++
> >  5 files changed, 192 insertions(+), 1 deletion(-)
> >  create mode 100644 
> > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
> >  create mode 100644 
> > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> > index ab2a97e354da..46158d67ab12 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
> > @@ -38,7 +38,8 @@ AMDGPUDM = \
> > amdgpu_dm_pp_smu.o \
> > amdgpu_dm_psr.o \
> > amdgpu_dm_replay.o \
> > -   amdgpu_dm_wb.o
> > +   amdgpu_dm_wb.o \
> > +   amdgpu_dm_colorop.o
> >  
> >  ifdef CONFIG_DRM_AMD_DC_FP
> >  AMDGPUDM += dc_fpu.o
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > index 9b527bffe11a..3ec759934669 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > @@ -668,6 +668,19 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
> > }
> >  }
> >  
> > +static enum dc_transfer_func_predefined
> > +amdgpu_colorop_tf_to_dc_tf(enum drm_colorop_curve_1d_type tf)
> > +{
> > +   switch (tf)
> > +   {
> > +   case DRM_COLOROP_1D_CURVE_SRGB_EOTF:
> > +   case DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF:
> > +   return TRANSFER_FUNCTION_SRGB;
> > +   default:
> > +   return TRANSFER_FUNCTION_LINEAR;;
Nitpick: double `;` 

> > +   }
> > +}
> > +
> >  static void __to_dc_lut3d_color(struct dc_rgb *rgb,
> > const struct drm_color_lut lut,
> > int bit_precision)
> > @@ -1137,6 +1150,59 @@ __set_dm_plane_degamma(struct drm_plane_state 
> > *plane_state,
> > return 0;
> >  }
> >  
> > +static int
> > +__set_colorop_in_tf_1d_curve(struct dc_plane_state *dc_plane_state,
> > +  struct drm_colorop_state *colorop_state)
> > +{
> > +   struct dc_transfer_func *tf = dc_plane_state->in_transfer_func;
> 
> For this patch and the next two, it ^ should be:
> `&dc_plane_state->in_transfer_func` (same for shape and blend), right?
> 
> > +   struct drm_colorop *colorop = colorop_state->colorop;
> > +   struct drm_device *drm = colorop->dev;
> > +
> > +   if (colorop->type != DRM_COLOROP_1D_CURVE &&
> > +   colorop_state->curve_1d_type != DRM_COLOROP_1D_CURVE_SRGB_EOTF)
> > +   return -EINVAL;
> > +
> > +   if (colorop_state->bypass) {
> > +   tf->type = TF_TYPE_BYPASS;
> > +   tf->tf = TRANSFER_FUNCTION_LINEAR;
> > +   return 0;
> > +   }
> > +
> > +   drm_dbg(drm, "Degamma colorop with ID: %d\n", colorop->base.id);
> > +
> > +   tf->type = TF_TYPE_PREDEFINED;
> > +   tf->tf = amdgpu_colorop_tf_to_dc_tf(colorop_state->curve_1d_type);
> > +
> > +   return 0;
> > +}
> > +
> > +static int
> > +__set_dm_plane_colorop_degamma(struct drm_plane_state *plane_state,
> > +  struct dc_plane_state *dc_plane_state,
> > +  struct drm_colorop *colorop)
> > +{
> > +   struct drm_colorop *old_colorop;
> > +   struct drm_colorop_state *colorop_state = NULL, *new_colorop_state;
> > +   struct drm_atomic_state *state = plane_state->state;
> > +   int i = 0;
> > +
> > +   old_colorop = colorop;
> > +
> > +   /* 1st op: 1d curve - degamma */
> > +   for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
> > +   if (new_colorop_state->colorop == old_colorop &&
> > +   new_colorop_state->curve_1d_type == 
> > DRM_COLOROP_1D_CURVE_SRGB_EOTF) {
> > +   colorop_state = new_colorop_state;
> > +   break;
> > +   }
> > +   }
> > +
> > +   if (!colorop_state)
> > +   return -EINVAL;
> > +
> > +   return __set_colorop_in_tf_1d_curve(dc_plane_state, colorop_state);
> > +}
> > +
> >  static int
> >  amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
> >  struct dc_pla

XDG_decoration protocol questions

2024-05-21 Thread Mariano

I have added to my MGRX Wayland videodriver (mgrx.fgrim.com) support for the
XDG_decoration protocol to have server side window decorations.

After doing the wayland-scanner magic to generate the .h include and the 
.c glue code


Adding the include:

    #include "xdg-decoration-client-protocol.h"

Bind the global register:

    } else if (strcmp(interface, 
zxdg_decoration_manager_v1_interface.name) == 0) {

    state->zxdg_decoration_manager_v1 = wl_registry_bind(
    wl_registry, name, &zxdg_decoration_manager_v1_interface, 1);
    //fprintf(stderr, "zxdg_decoration_manager_v1 detected\n");
    }

After getting the xdg_surface get the zxdg_toplevel_decoration_v1 object 
and add the listener:


    /* if the compositor support it (like the KDE one) ask for server 
side decoration */

    if (_WGrState.zxdg_decoration_manager_v1) {
    _WGrState.zxdg_toplevel_decoration_v1 =
    zxdg_decoration_manager_v1_get_toplevel_decoration(
    _WGrState.zxdg_decoration_manager_v1, 
_WGrState.xdg_toplevel);

zxdg_toplevel_decoration_v1_add_listener(_WGrState.zxdg_toplevel_decoration_v1,
    &zxdg_toplevel_decoration_v1_listener, &_WGrState);
    }

And declare the listener:

    static void toplevel_decoration_v1_configure(void *data,
    struct zxdg_toplevel_decoration_v1 
*zxdg_toplevel_decoration_v1,

    uint32_t mode)
    {
    //fprintf(stderr, "zxdg_decoration_manager_v1 mode %d\n", mode);
    }

    static const struct zxdg_toplevel_decoration_v1_listener
    zxdg_toplevel_decoration_v1_listener = {
    .configure = toplevel_decoration_v1_configure,
    };

After that you have (in KDE) your window magically server side decorated.

My questions are (thinking in servers other than KDE):

1-Can I assume the server will send the configure event even if I have not
sent a set_mode request?

2-If the mode reported by the configure event is not 2, must we need to send
a set_mode(2) request and wait for the next configure event before attaching
the first buffer to the wl_surface?

Thanks
Mariano Alvarez