Re: [PATCH 1/3] drm/atomic: Improve debug messages
On 2018-06-11 03:34 PM, Ville Syrjala wrote: > From: Ville Syrjälä > > Print the id/name of the object we're dealing with. Makes it easier to > figure out what's going on. Also toss in a few extra debug prints that > might be useful. > > Signed-off-by: Ville Syrjälä Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/drm_atomic.c | 88 > ++-- > 1 file changed, 61 insertions(+), 27 deletions(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index ee4b43b9404e..d7de83a6c1c2 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -339,6 +339,7 @@ static s32 __user *get_out_fence_for_crtc(struct > drm_atomic_state *state, > int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, >const struct drm_display_mode *mode) > { > + struct drm_crtc *crtc = state->crtc; > struct drm_mode_modeinfo umode; > > /* Early return for no change. */ > @@ -359,13 +360,13 @@ int drm_atomic_set_mode_for_crtc(struct drm_crtc_state > *state, > > drm_mode_copy(&state->mode, mode); > state->enable = true; > - DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", > - mode->name, state); > + DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", > + mode->name, crtc->base.id, crtc->name, state); > } else { > memset(&state->mode, 0, sizeof(state->mode)); > state->enable = false; > - DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", > - state); > + DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", > + crtc->base.id, crtc->name, state); > } > > return 0; > @@ -388,6 +389,8 @@ EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc); > int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, >struct drm_property_blob *blob) > { > + struct drm_crtc *crtc = state->crtc; > + > if (blob == state->mode_blob) > return 0; > > @@ -404,12 +407,13 @@ int drm_atomic_set_mode_prop_for_crtc(struct > drm_crtc_state *state, > > state->mode_blob = drm_property_blob_get(blob); > state->enable = true; > - DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", > - state->mode.name, state); > + DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", > + state->mode.name, crtc->base.id, crtc->name, > + state); > } else { > state->enable = false; > - DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", > - state); > + DRM_DEBUG_ATOMIC("Set [NOMODE] for [CRTC:%d:%s] state %p\n", > + crtc->base.id, crtc->name, state); > } > > return 0; > @@ -539,10 +543,14 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, > return -EFAULT; > > set_out_fence_for_crtc(state->state, crtc, fence_ptr); > - } else if (crtc->funcs->atomic_set_property) > + } else if (crtc->funcs->atomic_set_property) { > return crtc->funcs->atomic_set_property(crtc, state, property, > val); > - else > + } else { > + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] unknown property > [PROP:%d:%s]]\n", > + crtc->base.id, crtc->name, > + property->base.id, property->name); > return -EINVAL; > + } > > return 0; > } > @@ -799,8 +807,11 @@ static int drm_atomic_plane_set_property(struct > drm_plane *plane, > } else if (property == plane->alpha_property) { > state->alpha = val; > } else if (property == plane->rotation_property) { > - if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) > + if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) { > + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: > 0x%llx\n", > + plane->base.id, plane->name, val); > return -EINVAL; > + } > state->rotation = val; >
Re: [PATCH 2/3] drm: Print bad user modes
On 2018-06-11 03:34 PM, Ville Syrjala wrote: > From: Ville Syrjälä > > Print out the modeline when we reject a bad user mode. Avoids having to > guess why it was rejected. > > Signed-off-by: Ville Syrjälä Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/drm_atomic.c| 20 +--- > drivers/gpu/drm/drm_crtc.c | 4 +++- > drivers/gpu/drm/drm_crtc_internal.h | 3 +++ > drivers/gpu/drm/drm_modes.c | 2 +- > 4 files changed, 24 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index d7de83a6c1c2..5fe5e06062a9 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -400,10 +400,24 @@ int drm_atomic_set_mode_prop_for_crtc(struct > drm_crtc_state *state, > memset(&state->mode, 0, sizeof(state->mode)); > > if (blob) { > - if (blob->length != sizeof(struct drm_mode_modeinfo) || > - drm_mode_convert_umode(state->crtc->dev, &state->mode, > -blob->data)) > + int ret; > + > + if (blob->length != sizeof(struct drm_mode_modeinfo)) { > + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] bad mode blob length: > %zu\n", > + crtc->base.id, crtc->name, > + blob->length); > + return -EINVAL; > + } > + > + ret = drm_mode_convert_umode(crtc->dev, > + &state->mode, blob->data); > + if (ret) { > + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] invalid mode (ret=%d, > status=%s):\n", > + crtc->base.id, crtc->name, > + ret, > drm_get_mode_status_name(state->mode.status)); > + drm_mode_debug_printmodeline(&state->mode); > return -EINVAL; > + } > > state->mode_blob = drm_property_blob_get(blob); > state->enable = true; > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 53828fc8d911..163d82ac7d76 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -649,7 +649,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, > > ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode); > if (ret) { > - DRM_DEBUG_KMS("Invalid mode\n"); > + DRM_DEBUG_KMS("Invalid mode (ret=%d, status=%s)\n", > + ret, > drm_get_mode_status_name(mode->status)); > + drm_mode_debug_printmodeline(mode); > goto out; > } > > diff --git a/drivers/gpu/drm/drm_crtc_internal.h > b/drivers/gpu/drm/drm_crtc_internal.h > index 5d307b23a4e6..34499800932a 100644 > --- a/drivers/gpu/drm/drm_crtc_internal.h > +++ b/drivers/gpu/drm/drm_crtc_internal.h > @@ -56,6 +56,9 @@ int drm_mode_setcrtc(struct drm_device *dev, > int drm_modeset_register_all(struct drm_device *dev); > void drm_modeset_unregister_all(struct drm_device *dev); > > +/* drm_modes.c */ > +const char *drm_get_mode_status_name(enum drm_mode_status status); > + > /* IOCTLs */ > int drm_mode_getresources(struct drm_device *dev, > void *data, struct drm_file *file_priv); > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c > index c78ca0e84ffd..7f552d5fa88e 100644 > --- a/drivers/gpu/drm/drm_modes.c > +++ b/drivers/gpu/drm/drm_modes.c > @@ -1257,7 +1257,7 @@ static const char * const drm_mode_status_names[] = { > > #undef MODE_STATUS > > -static const char *drm_get_mode_status_name(enum drm_mode_status status) > +const char *drm_get_mode_status_name(enum drm_mode_status status) > { > int index = status + 3; > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: Remove erroneous if statement in gamma set
On 2018-04-26 10:46 AM, sunpeng...@amd.com wrote: > From: "Leo (Sunpeng) Li" > > The lines were removed as part of the original change. They may have > been missed during merge. > > This is a fixup to: > > committ 265083076187e619aa9176aeb05ad630013429b4 > Author: Leo (Sunpeng) Li > Date: Fri Feb 2 10:18:56 2018 -0500 > > drm/amd/display: Hookup color management functions Missing SOB? With that fixed this is Reviewed-by: Harry Wentland I would like Kevin to take a look before merging first. It looks like this line was unintentionally left when merging to amd-mainline-dkms-4.15 but would like to confirm that's the case. Harry > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 -- > 1 file changed, 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index b7265f6..0d4a133 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -2206,11 +2206,9 @@ static int fill_plane_attributes(struct amdgpu_device > *adev, > > dc_plane_state->in_transfer_func = input_tf; > > - /* In case of gamma set, update gamma value */ > #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) || \ > defined(OS_NAME_RHEL_7_3) || \ > defined(OS_NAME_RHEL_7_4_5) > - if (crtc_state->gamma_lut) > /* >* Always set input transfer function, since plane state is refreshed >* every time. > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [REGRESSION] drm/amd/dc: Add dc display driver (v2)
Replied on the ticket. If this is about non-functioning LVDS or VGA I'm aware of it and trying to find time to find a good solution. Harry On 2018-04-30 11:14 AM, Joseph Salisbury wrote: > Hi Harry, > > A kernel bug report was opened against Ubuntu [0]. After a kernel > bisect, it was found the following commit introduced the bug: > > > commit 4562236b3bc0a28aeb6ee93b2d8a849a4c4e1c7c > Author: Harry Wentland > Date: Tue Sep 12 15:58:20 2017 -0400 > > drm/amd/dc: Add dc display driver (v2) > > > The regression was introduced as of v4.15-rc1 and still exists in > current mainline. The commit does not need to be reverted to resolve > the bug. Disabling the CONFIG_DRM_AMD_DC_PRE_VEGA option makes the bug > go away. > > I was hoping to get your feedback, since you are the patch author. Do > you think gathering any additional data will help diagnose this issue? > > > Thanks, > > Joe > > > [0] http://pad.lv/1761751 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: clean up assignment of amdgpu_crtc
On 2018-05-02 10:43 AM, Colin King wrote: > From: Colin Ian King > > The declaration of pointer amdgpu_crtc has a redundant assignment to > amdgpu_crtc. Clean this up by removing it. > > Detected by CoverityScan, CID#1460299 ("Evaluation order violation") > > Signed-off-by: Colin Ian King Looks like i goofed. Thanks for fixing this. Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index 1dd1142246c2..2beb8821e19e 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -3773,7 +3773,7 @@ static void remove_stream(struct amdgpu_device *adev, > static int get_cursor_position(struct drm_plane *plane, struct drm_crtc > *crtc, > struct dc_cursor_position *position) > { > - struct amdgpu_crtc *amdgpu_crtc = amdgpu_crtc = to_amdgpu_crtc(crtc); > + struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); > int x, y; > int xorigin = 0, yorigin = 0; > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/3] drm/connector: Add generic underscan properties
On 2018-05-07 12:19 PM, Boris Brezillon wrote: > On Mon, 7 May 2018 18:01:44 +0300 > Ville Syrjälä wrote: > >> On Mon, May 07, 2018 at 04:44:32PM +0200, Boris Brezillon wrote: >>> We have 3 drivers defining the "underscan", "underscan hborder" and >>> "underscan vborder" properties (radeon, amd and nouveau) and we are >>> about to add the same kind of thing in VC4. >>> >>> Define generic underscan props and add new fields to the drm_connector >>> state so that the property parsing logic can be shared by all DRM >>> drivers. >>> >>> A driver can now attach underscan properties to its connector through >>> the drm_connector_attach_underscan_properties() helper, and can >>> check/apply the underscan setup based on the >>> drm_connector_state->underscan fields. >>> >>> Signed-off-by: Boris Brezillon >>> --- >>> drivers/gpu/drm/drm_atomic.c| 12 >>> drivers/gpu/drm/drm_connector.c | 120 >>> >>> include/drm/drm_connector.h | 78 ++ >>> 3 files changed, 210 insertions(+) >>> >>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c >>> index dc850b4b6e21..b7312bd172c9 100644 >>> --- a/drivers/gpu/drm/drm_atomic.c >>> +++ b/drivers/gpu/drm/drm_atomic.c >>> @@ -1278,6 +1278,12 @@ static int drm_atomic_connector_set_property(struct >>> drm_connector *connector, >>> return -EINVAL; >>> } >>> state->content_protection = val; >>> + } else if (property == connector->underscan_mode_property) { >>> + state->underscan.mode = val; >>> + } else if (property == connector->underscan_hborder_property) { >>> + state->underscan.hborder = val; >>> + } else if (property == connector->underscan_vborder_property) { >>> + state->underscan.vborder = val; >>> } else if (connector->funcs->atomic_set_property) { >>> return connector->funcs->atomic_set_property(connector, >>> state, property, val); >>> @@ -1359,6 +1365,12 @@ drm_atomic_connector_get_property(struct >>> drm_connector *connector, >>> *val = state->scaling_mode; >>> } else if (property == connector->content_protection_property) { >>> *val = state->content_protection; >>> + } else if (property == connector->underscan_mode_property) { >>> + *val = state->underscan.mode; >>> + } else if (property == connector->underscan_hborder_property) { >>> + *val = state->underscan.hborder; >>> + } else if (property == connector->underscan_vborder_property) { >>> + *val = state->underscan.vborder; >>> } else if (connector->funcs->atomic_get_property) { >>> return connector->funcs->atomic_get_property(connector, >>> state, property, val); >>> diff --git a/drivers/gpu/drm/drm_connector.c >>> b/drivers/gpu/drm/drm_connector.c >>> index dfc8ca1e9413..9937390b8a25 100644 >>> --- a/drivers/gpu/drm/drm_connector.c >>> +++ b/drivers/gpu/drm/drm_connector.c >>> @@ -914,6 +914,31 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, >>> drm_cp_enum_list) >>> * can also expose this property to external outputs, in which case they >>> * must support "None", which should be the default (since external screens >>> * have a built-in scaler). >>> + * >>> + * underscan: >>> + * This properties defines whether underscan is activated or not, and when >>> + * it is activated, how the horizontal and vertical borders are calculated: >>> + * >>> + * off: >>> + * Underscan is disabled. The output image shouldn't be scaled to >>> + * take screen borders into account. >> >>> + * on: >>> + * Underscan is activated and horizontal and vertical borders are >>> + * specified through the "underscan hborder" and >>> + * "underscan vborder" properties. >> >> How is the output scaled? > > In HW. The formula is > > hfactor = (hdisplay - hborder) / hdisplay > vfactor = (vdisplay - vborder) / vdisplay > >> What does the user mode hdisplay/vdisplay mean >> in this case? > > The same as before this patch: the output resolution. You just add > black margins. > >> What if I want underscan without scaling? > > Then don't involve the DRM driver and do that from userspace: just > fill the visible portion of the framebuffer and leave the rest black. > There nothing the DRM driver can do to help with that, except maybe > exposing the information about the active area of the screen. It would > be nice to do that, but that means patching all userspace libs to take > this into account. > >> >>> + * auto: >>> + * Underscan is activated and horizontal and vertical borders are >>> + * automatically chosen by the driver. >> >> Seems overly vague to be useful. You didn't even seem to implement it >> for vc4. > FWIW, amdgpu treats UNDERSCAN_AUTO like UNDERSCAN_ON. radeon and nouveau seem to do the same. So there's probably
Re: [PATCH v2 2/4] drm/dsc: Define Display Stream Compression PPS infoframe
On 2018-05-14 10:05 PM, Manasi Navare wrote: > This patch defines a new header file for all the DSC 1.2 structures > and creates a structure for PPS infoframe which will be used to send > picture parameter set secondary data packet for display stream compression. > All the PPS infoframe syntax elements are taken from DSC 1.2 specification > from VESA. > > v2: > * Fix the comments for kernel-doc > > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Anusha Srivatsa > Signed-off-by: Manasi Navare > --- > include/drm/drm_dsc.h | 437 > ++ > 1 file changed, 437 insertions(+) > create mode 100644 include/drm/drm_dsc.h > > diff --git a/include/drm/drm_dsc.h b/include/drm/drm_dsc.h > new file mode 100644 > index 000..5ee72e8 > --- /dev/null > +++ b/include/drm/drm_dsc.h > @@ -0,0 +1,437 @@ > +/* > + * Copyright (C) 2018 Intel Corp. > + * > + * 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, sublicense, > + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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: > + * Manasi Navare > + */ > + > +#ifndef DRM_DSC_H_ > +#define DRM_DSC_H_ > + > +#include > + > +#define DSC_NUM_BUF_RANGES 15 > + > +/** > + * struct picture_parameter_set - Represents 128 bytes of Picture Parameter > Set > + * > + * The VESA DSC standard defines picture parameter set (PPS) which display > stream > + * compression encoders must communicate to decoders. The PPS is encapsulated > + * in 128 bytes (PPS 0 through PPS 127). The fields in this structure are as > per > + * Table 4.1 in Vesa DSC specification v1.1/v1.2. > + * The PPS fields that span over more than a byte should be stored in Big > Endian > + * format. > + */ > +struct picture_parameter_set { > + /** > + * @dsc_version_minor: > + * PPS0[3:0] - Contains Minor version of DSC > + */ > + u8 dsc_version_minor:4; > + /** > + * @dsc_version_major: > + * PPS0[7:4] - Contains major version of DSC > + */ > + u8 dsc_version_major:4; > + /** > + * @pps_identifier: > + * PPS1[7:0] - Application specific identifier that can be > + * used to differentiate between different PPS tables. > + */ > + u8 pps_identifier; > + /** > + * @pps2_reserved: > + * PPS2[7:0]- RESERVED Byte > + */ > + u8 pps2_reserved; > + /** > + * @linebuf_depth: > + * PPS3[3:0] - Contains linebuffer bit depth used to generate > + * the bitstream. (0x0 - 16 bits for DSc 1.2, 0x8 - 8 bits, > + * 0xA - 10 bits, 0xB - 11 bits, 0xC - 12 bits, 0xD - 13 bits, > + * 0xE - 14 bits for DSC1.2, 0xF - 14 bits for DSC 1.2. > + */ > + u8 linebuf_depth:4; > + /** > + * @bits_per_component: > + * PPS3[7:4] - Bits per component fo rthe original pixels typo: "for the" > + * of the encoded picture. > + */ Would it make sense to indicate in the comments what the values mean? From the spec: 0x0 = 16bpc (allowed only when dsc_version_minor = 0x2). 0x8 = 8bpc. 0xA = 10bpc. 0xC = 12bpc. 0xE = 14bpc (allowed only when dsc_version_minor = 0x2). All other encodings are RESERVED. Harry > + u8 bits_per_component:4; > + /** > + * @bpp_high: > + * PPS4[1:0] - These are the most significant 2 bits of > + * compressed BPP bits_per_pixel[9:0] syntax element. > + */ > + u8 bpp_high:2; > + /** > + * @vbr_enable: > + * PPS4[2] - 0 = VBR disabled, 1 = VBR enabled > + */ > + u8 vbr_enable:1; > + /** > + * @simple_422: > + * PPS4[3] - Indicates if decoder drops samples to > + * reconstruct the 4:2:2 picture. > + */ > + u8 simple_422:1; > + /** > + * @convert_rgb: > + * PPS4[4] - Indicates if DSC color space conversion is active > + */ > + u8 convert_rgb:1; > + /** > + * @block_pred_enable: > + * PPS4[5] - Indicates if BP is used to code any groups in picture > + */ > + u8 blo
Re: [PATCH v2 3/4] drm/dsc: Define VESA Display Stream Compression Capabilities
On 2018-05-14 10:05 PM, Manasi Navare wrote: > From: Gaurav K Singh > > This defines all the DSC parameters as per the VESA DSC spec > that will be required for DSC encoder/decoder > > v2: Define this struct in DRM (From Manasi) > * Changed the data types to u8/u16 instead of unsigned longs (Manasi) > * Remove driver specific fields (Manasi) > * Move this struct definition to DRM (Manasi) > * Define DSC 1.2 parameters (Manasi) > * Use DSC_NUM_BUF_RANGES (Manasi) > * Call it drm_dsc_config (Manasi) > > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Anusha Srivatsa > Signed-off-by: Manasi Navare > Signed-off-by: Gaurav K Singh > --- > include/drm/drm_dsc.h | 111 > ++ > 1 file changed, 111 insertions(+) > > diff --git a/include/drm/drm_dsc.h b/include/drm/drm_dsc.h > index 5ee72e8..04501e2 100644 > --- a/include/drm/drm_dsc.h > +++ b/include/drm/drm_dsc.h > @@ -30,6 +30,117 @@ > > #define DSC_NUM_BUF_RANGES 15 > > +/* VESA Display Stream Compression DSC 1.2 constants */ > +#define DSC_NUM_BUF_RANGES 15 Duplicate definition of previous line. Harry > + > +/* Configuration for a single Rate Control model range */ > +struct dsc_rc_range_parameters { > + /* Min Quantization Parameters allowed for this range */ > + u8 range_min_qp; > + /* Max Quantization Parameters allowed for this range */ > + u8 range_max_qp; > + /* Bits/group offset to apply to target for this group */ > + u8 range_bpg_offset; > +}; > + > +struct drm_dsc_config { > + /* Bits / component for previous reconstructed line buffer */ > + u8 line_buf_depth; > + /* Bits per component to code (must be 8, 10, or 12) */ > + u8 bits_per_component; > + /* > + * Flag indicating to do RGB - YCoCg conversion > + * and back (should be 1 for RGB input) > + */ > + bool convert_rgb; > + u8 slice_count; > + /* Slice Width */ > + u16 slice_width; > + /* Slice Height */ > + u16 slice_height; > + /* > + * 4:2:2 enable mode (from PPS, 4:2:2 conversion happens > + * outside of DSC encode/decode algorithm) > + */ > + bool enable422; > + /* Picture Width */ > + u16 pic_width; > + /* Picture Height */ > + u16 pic_height; > + /* Offset to bits/group used by RC to determine QP adjustment */ > + u8 rc_tgt_offset_high; > + /* Offset to bits/group used by RC to determine QP adjustment */ > + u8 rc_tgt_offset_low; > + /* Bits/pixel target << 4 (ie., 4 fractional bits) */ > + u16 bits_per_pixel; > + /* > + * Factor to determine if an edge is present based > + * on the bits produced > + */ > + u8 rc_edge_factor; > + /* Slow down incrementing once the range reaches this value */ > + u8 rc_quant_incr_limit1; > + /* Slow down incrementing once the range reaches this value */ > + u8 rc_quant_incr_limit0; > + /* Number of pixels to delay the initial transmission */ > + u16 initial_xmit_delay; > + /* Number of pixels to delay the VLD on the decoder,not including SSM */ > + u16 initial_dec_delay; > + /* Block prediction enable */ > + bool block_pred_enable; > + /* Bits/group offset to use for first line of the slice */ > + u8 first_line_bpg_offset; > + /* Value to use for RC model offset at slice start */ > + u16 initial_offset; > + /* Thresholds defining each of the buffer ranges */ > + u16 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1]; > + /* Parameters for each of the RC ranges */ > + struct dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES]; > + /* Total size of RC model */ > + u16 rc_model_size; > + /* Minimum QP where flatness information is sent */ > + u8 flatness_min_qp; > + /* Maximum QP where flatness information is sent */ > + u8 flatness_max_qp; > + /* Initial value for scale factor */ > + u8 initial_scale_value; > + /* Decrement scale factor every scale_decrement_interval groups */ > + u16 scale_decrement_interval; > + /* Increment scale factor every scale_increment_interval groups */ > + u16 scale_increment_interval; > + /* Non-first line BPG offset to use */ > + u16 nfl_bpg_offset; > + /* BPG offset used to enforce slice bit */ > + u16 slice_bpg_offset; > + /* Final RC linear transformation offset value */ > + u16 final_offset; > + /* Enable on-off VBR (ie., disable stuffing bits) */ > + bool vbr_enable; > + /* Mux word size (in bits) for SSM mode */ > + u8 mux_word_size; > + /* > + * The (max) size in bytes of the "chunks" that are > + * used in slice multiplexing > + */ > + u16 slice_chunk_size; > + /* Rate Control buffer siz in bits */ > + u16 rc_bits; > + /* DSC Minor Version */ > + u8 dsc_version_minor; > + /* DSC Major version */ > + u8 dsc_version_major; > + /* Native 4:2:2 suppo
Re: [PATCH v2 0/4] DRM helpers for Display Stream Compression PPS infoframes
On 2018-05-14 10:05 PM, Manasi Navare wrote: > VESA Display Stream Compression is a specification for visually losless > video compression over display links. The DSC standard also defines > a picture parameter set (PPS) which encoder must communicate to decoders. > This is done by encapsulating PPS header and payload bytes in an infoframe > that can be sent to the display sink using secondary data packets > as defined in DP 1.4 spec. > > This patch series creates a new files drm_dsc.h and drm_dsc.c > which define all the DSC related structures and helpers that > can be called by drivers to form DSC PPS infoframes before > enabling Display Stream compression on eDP/DP/MIPI > > v2: > *This is a v2 of the original patch series which adds kernel-doc > hooks for the new dsc files in drm-kms-helpers.rst. (Daniel Vetter) > > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Anusha Srivatsa With my comments for patch 2 and 3 addressed patches 1-3 are Reviewed-by: Harry Wentland Patch 4 is Acked-by: Harry Wentland Harry > > Gaurav K Singh (1): > drm/dsc: Define VESA Display Stream Compression Capabilities > > Manasi Navare (3): > drm/dp: Define payload size for DP SDP PPS packet > drm/dsc: Define Display Stream Compression PPS infoframe > drm/dsc: Add helpers for DSC picture parameter set infoframes > > Documentation/gpu/drm-kms-helpers.rst | 12 + > drivers/gpu/drm/Makefile | 2 +- > drivers/gpu/drm/drm_dsc.c | 227 ++ > include/drm/drm_dp_helper.h | 1 + > include/drm/drm_dsc.h | 564 > ++ > 5 files changed, 805 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/drm_dsc.c > create mode 100644 include/drm/drm_dsc.h > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3] Allow fd.o to join forces with X.Org
The leadership of freedesktop.org (fd.o) has recently expressed interest in having an elected governing body. Given the tight connection between fd.o and X.Org and the fact that X.Org has such a governing body it seemed obvious to consider extending X.Org's mandate to fd.o. Quite a bit of background on fd.o leading up to this has been covered by Daniel Stone at XDC 2018 [2] and was covered really well by Jake Edge of LWN [1]. One question that is briefly addressed in the LWN article and was thoroughly discussed by members of the X.Org boards, Daniel Stone, and others in hallway discussions is the question of whether to extend the X.Org membership to projects hosted on fd.o but outside the purpose of the X.Org foundation as enacted in its bylaws. Most people I talked to would prefer not to dilute X.Org's mission and extend membership only to contributors of projects that follow X.Org's purpose as enacted in its bylaws. Other projects can continue to be hosted on fd.o but won't receive X.Org membership for the mere reason of being hosted on fd.o. [1] https://lwn.net/Articles/767258/ [2] https://youtu.be/s22B3E7rUTs v3: - Clarify what support of fd.o projects entails without formalizing a two-tier system for fd.o projects that fall under X.Org's mandate and those who don't - Add link to Daniel's talk at XDC2018 v2: - Subject line that better describes the intention - Briefly describe reasons behind this change - Drop expanding membership eligibility Acked-by: Daniel Stone --- We're looking for feedback and comments on this patch. If it's not widely controversial the final version of the patch will be put to a vote at the 2019 X.Org elections. The patch applies to the X.Org bylaws git repo, which can be found at https://gitlab.freedesktop.org/xorgfoundation/bylaws Happy commenting. Harry bylaws.tex | 5 + 1 file changed, 5 insertions(+) diff --git a/bylaws.tex b/bylaws.tex index 4ab35a4f7745..5a7542739582 100644 --- a/bylaws.tex +++ b/bylaws.tex @@ -24,6 +24,11 @@ The purpose of the X.Org Foundation shall be to: \item Support and educate the general community of users of this graphics stack. + + \item Support free and open source projects through the freedesktop.org + infrastructure. This includes, but is not limited to: Administering and + providing project hosting services. + \end{enumerate} \article{INTERPRETATION} -- 2.19.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH (repost) 5/5] drm/amdgpu: add DisplayPort CEC-Tunneling-over-AUX support
On 2018-08-17 10:11 AM, Hans Verkuil wrote: > From: Hans Verkuil > > Add DisplayPort CEC-Tunneling-over-AUX support to amdgpu. > > Signed-off-by: Hans Verkuil > Acked-by: Alex Deucher > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 +++-- > .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 ++ > 2 files changed, 13 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index 34f34823bab5..77898c95bef6 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -898,6 +898,7 @@ amdgpu_dm_update_connector_after_detect(struct > amdgpu_dm_connector *aconnector) > aconnector->dc_sink = sink; > if (sink->dc_edid.length == 0) { > aconnector->edid = NULL; > + drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); > } else { > aconnector->edid = > (struct edid *) sink->dc_edid.raw_edid; > @@ -905,10 +906,13 @@ amdgpu_dm_update_connector_after_detect(struct > amdgpu_dm_connector *aconnector) > > drm_connector_update_edid_property(connector, > aconnector->edid); > + drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, > + aconnector->edid); > } > amdgpu_dm_add_sink_to_freesync_module(connector, > aconnector->edid); > > } else { > + drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); > amdgpu_dm_remove_sink_from_freesync_module(connector); > drm_connector_update_edid_property(connector, NULL); > aconnector->num_modes = 0; > @@ -1059,12 +1063,16 @@ static void handle_hpd_rx_irq(void *param) > drm_kms_helper_hotplug_event(dev); > } > } > + > if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) || > - (dc_link->type == dc_connection_mst_branch)) > + (dc_link->type == dc_connection_mst_branch)) { > dm_handle_hpd_rx_irq(aconnector); > + } These lines don't really add anything functional. Either way, this patch is Reviewed-by: Harry Wentland Harry > > - if (dc_link->type != dc_connection_mst_branch) > + if (dc_link->type != dc_connection_mst_branch) { > + drm_dp_cec_irq(&aconnector->dm_dp_aux.aux); > mutex_unlock(&aconnector->hpd_lock); > + } > } > > static void register_hpd_handlers(struct amdgpu_device *adev) > @@ -2732,6 +2740,7 @@ static void amdgpu_dm_connector_destroy(struct > drm_connector *connector) > dm->backlight_dev = NULL; > } > #endif > + drm_dp_cec_unregister_connector(&aconnector->dm_dp_aux.aux); > drm_connector_unregister(connector); > drm_connector_cleanup(connector); > kfree(connector); > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > index 9a300732ba37..18a3a6e5ffa0 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > @@ -496,6 +496,8 @@ void amdgpu_dm_initialize_dp_connector(struct > amdgpu_display_manager *dm, > aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc; > > drm_dp_aux_register(&aconnector->dm_dp_aux.aux); > + drm_dp_cec_register_connector(&aconnector->dm_dp_aux.aux, > + aconnector->base.name, dm->adev->dev); > aconnector->mst_mgr.cbs = &dm_mst_cbs; > drm_dp_mst_topology_mgr_init( > &aconnector->mst_mgr, > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 07/23] drm/dsc: Define Display Stream Compression PPS infoframe
On 2018-07-31 05:07 PM, Manasi Navare wrote: > This patch defines a new header file for all the DSC 1.2 structures > and creates a structure for PPS infoframe which will be used to send > picture parameter set secondary data packet for display stream compression. > All the PPS infoframe syntax elements are taken from DSC 1.2 specification > from VESA. > > Cc: Gaurav K Singh > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Anusha Srivatsa > Cc: Harry Wentland > Signed-off-by: Manasi Navare Looks like this version basically removes the bitfield definitions and adds those in the comments, compared to the review in May. Reviewed-by: Harry Wentland Harry > --- > include/drm/drm_dsc.h | 365 > ++ > 1 file changed, 365 insertions(+) > create mode 100644 include/drm/drm_dsc.h > > diff --git a/include/drm/drm_dsc.h b/include/drm/drm_dsc.h > new file mode 100644 > index 000..678e8e6 > --- /dev/null > +++ b/include/drm/drm_dsc.h > @@ -0,0 +1,365 @@ > +/* > + * Copyright (C) 2018 Intel Corp. > + * > + * 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, sublicense, > + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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: > + * Manasi Navare > + */ > + > +#ifndef DRM_DSC_H_ > +#define DRM_DSC_H_ > + > +#include > + > +/* VESA Display Stream Compression DSC 1.2 constants */ > +#define DSC_NUM_BUF_RANGES 15 > + > +/** > + * struct picture_parameter_set - Represents 128 bytes of Picture Parameter > Set > + * > + * The VESA DSC standard defines picture parameter set (PPS) which display > + * stream compression encoders must communicate to decoders. > + * The PPS is encapsulated in 128 bytes (PPS 0 through PPS 127). The fields > in > + * this structure are as per Table 4.1 in Vesa DSC specification v1.1/v1.2. > + * The PPS fields that span over more than a byte should be stored in Big > Endian > + * format. > + */ > +struct picture_parameter_set { > + /** > + * @dsc_version: > + * PPS0[3:0] - dsc_version_minor: Contains Minor version of DSC > + * PPS0[7:4] - dsc_version_major: Contains major version of DSC > + */ > + u8 dsc_version; > + /** > + * @pps_identifier: > + * PPS1[7:0] - Application specific identifier that can be > + * used to differentiate between different PPS tables. > + */ > + u8 pps_identifier; > + /** > + * @pps_reserved: > + * PPS2[7:0]- RESERVED Byte > + */ > + u8 pps_reserved; > + /** > + * @pps_3: > + * PPS3[3:0] - linebuf_depth: Contains linebuffer bit depth used to > + * generate the bitstream. (0x0 - 16 bits for DSC 1.2, 0x8 - 8 bits, > + * 0xA - 10 bits, 0xB - 11 bits, 0xC - 12 bits, 0xD - 13 bits, > + * 0xE - 14 bits for DSC1.2, 0xF - 14 bits for DSC 1.2. > + * PPS3[7:4] - bits_per_component: Bits per component for the original > + * pixels of the encoded picture. > + * 0x0 = 16bpc (allowed only when dsc_version_minor = 0x2) > + * 0x8 = 8bpc, 0xA = 10bpc, 0xC = 12bpc, 0xE = 14bpc (also > + * allowed only when dsc_minor_version = 0x2) > + */ > + u8 pps_3; > + /** > + * @pps_4: > + * PPS4[1:0] -These are the most significant 2 bits of > + * compressed BPP bits_per_pixel[9:0] syntax element. > + * PPS4[2] - vbr_enable: 0 = VBR disabled, 1 = VBR enabled > + * PPS4[3] - simple_422: Indicates if decoder drops samples to > + * reconstruct the 4:2:2 picture. > + * PPS4[4] - Convert_rgb: Indicates if DSC color space conversion is > + * active. > + *
Re: [PATCH v2 10/23] drm/dsc: Add helpers for DSC picture parameter set infoframes
On 2018-07-31 05:07 PM, Manasi Navare wrote: > According to Display Stream compression spec 1.2, the picture > parameter set metadata is sent from source to sink device > using the DP Secondary data packet. An infoframe is formed > for the PPS SDP header and PPS SDP payload bytes. > This patch adds helpers to fill the PPS SDP header > and PPS SDP payload according to the DSC 1.2 specification. > > v5: > Do not use bitfields for DRM structs (Jani N) > v4: > * Use DSC constants for params that dont change across > configurations > v3: > * Add reference to added kernel-docs in Documentation/gpu/drm-kms-helpers.rst > (Daniel Vetter) > > v2: > * Add EXPORT_SYMBOL for the drm functions (Manasi) > > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Anusha Srivatsa > Cc: Harry Wentland > Signed-off-by: Manasi Navare Acked-by: Harry Wentland Harry > --- > Documentation/gpu/drm-kms-helpers.rst | 12 ++ > drivers/gpu/drm/Makefile | 2 +- > drivers/gpu/drm/drm_dsc.c | 221 > ++ > include/drm/drm_dsc.h | 22 > 4 files changed, 256 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/drm_dsc.c > > diff --git a/Documentation/gpu/drm-kms-helpers.rst > b/Documentation/gpu/drm-kms-helpers.rst > index f9cfcdc..50bb717 100644 > --- a/Documentation/gpu/drm-kms-helpers.rst > +++ b/Documentation/gpu/drm-kms-helpers.rst > @@ -223,6 +223,18 @@ MIPI DSI Helper Functions Reference > .. kernel-doc:: drivers/gpu/drm/drm_mipi_dsi.c > :export: > > +Display Stream Compression Helper Functions Reference > += > + > +.. kernel-doc:: drivers/gpu/drm/drm_dsc.c > + :doc: dsc helpers > + > +.. kernel-doc:: include/drm/drm_dsc.h > + :internal: > + > +.. kernel-doc:: drivers/gpu/drm/drm_dsc.c > + :export: > + > Output Probing Helper Functions Reference > = > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index a6771ce..961e511 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -31,7 +31,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o > drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o > drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o > > -drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ > +drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.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 \ > diff --git a/drivers/gpu/drm/drm_dsc.c b/drivers/gpu/drm/drm_dsc.c > new file mode 100644 > index 000..99a8794 > --- /dev/null > +++ b/drivers/gpu/drm/drm_dsc.c > @@ -0,0 +1,221 @@ > +/* > + *Copyright © 2018 Intel Corp > + * > + * Permission to use, copy, modify, distribute, and sell this software and > its > + * documentation for any purpose is hereby granted without fee, provided that > + * the above copyright notice appear in all copies and that both that > copyright > + * notice and this permission notice appear in supporting documentation, and > + * that the name of the copyright holders not be used in advertising or > + * publicity pertaining to distribution of the software without specific, > + * written prior permission. The copyright holders make no representations > + * about the suitability of this software for any purpose. It is provided > "as > + * is" without express or implied warranty. > + * > + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS > SOFTWARE, > + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO > + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR > + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF > USE, > + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER > + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR > PERFORMANCE > + * OF THIS SOFTWARE. > + * > + * Author: > + * Manasi Navare > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + * DOC: dsc helpers > + * > + * These functions contain some common logic and helpers to deal with VESA > + * Display Stream Compression standard required for DSC on Display Port/eDP > or > + * MIPI display interfaces. > + */ > + > +/** > + * drm_dsc_dp_pps_hea
Re: [PATCH v2 08/23] drm/dsc: Define VESA Display Stream Compression Capabilities
On 2018-07-31 05:07 PM, Manasi Navare wrote: > From: Gaurav K Singh > > This defines all the DSC parameters as per the VESA DSC spec > that will be required for DSC encoder/decoder > > v4 (From Manasi) > * Add the DSC_MUX_WORD_SIZE constants (Manasi) > > v3 (From Manasi) > * Remove the duplicate define (Suggested By:Harry Wentland) > > v2: Define this struct in DRM (From Manasi) > * Changed the data types to u8/u16 instead of unsigned longs (Manasi) > * Remove driver specific fields (Manasi) > * Move this struct definition to DRM (Manasi) > * Define DSC 1.2 parameters (Manasi) > * Use DSC_NUM_BUF_RANGES (Manasi) > * Call it drm_dsc_config (Manasi) > > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Anusha Srivatsa > Cc: Harry Wentland > Signed-off-by: Manasi Navare > Signed-off-by: Gaurav K Singh Acked-by: Harry Wentland Harry > --- > include/drm/drm_dsc.h | 110 > ++ > 1 file changed, 110 insertions(+) > > diff --git a/include/drm/drm_dsc.h b/include/drm/drm_dsc.h > index 678e8e6..eda323d 100644 > --- a/include/drm/drm_dsc.h > +++ b/include/drm/drm_dsc.h > @@ -30,6 +30,116 @@ > > /* VESA Display Stream Compression DSC 1.2 constants */ > #define DSC_NUM_BUF_RANGES 15 > +#define DSC_MUX_WORD_SIZE_8_10_BPC 48 > +#define DSC_MUX_WORD_SIZE_12_BPC 64 > + > +/* Configuration for a single Rate Control model range */ > +struct dsc_rc_range_parameters { > + /* Min Quantization Parameters allowed for this range */ > + u8 range_min_qp; > + /* Max Quantization Parameters allowed for this range */ > + u8 range_max_qp; > + /* Bits/group offset to apply to target for this group */ > + u8 range_bpg_offset; > +}; > + > +struct drm_dsc_config { > + /* Bits / component for previous reconstructed line buffer */ > + u8 line_buf_depth; > + /* Bits per component to code (must be 8, 10, or 12) */ > + u8 bits_per_component; > + /* > + * Flag indicating to do RGB - YCoCg conversion > + * and back (should be 1 for RGB input) > + */ > + bool convert_rgb; > + u8 slice_count; > + /* Slice Width */ > + u16 slice_width; > + /* Slice Height */ > + u16 slice_height; > + /* > + * 4:2:2 enable mode (from PPS, 4:2:2 conversion happens > + * outside of DSC encode/decode algorithm) > + */ > + bool enable422; > + /* Picture Width */ > + u16 pic_width; > + /* Picture Height */ > + u16 pic_height; > + /* Offset to bits/group used by RC to determine QP adjustment */ > + u8 rc_tgt_offset_high; > + /* Offset to bits/group used by RC to determine QP adjustment */ > + u8 rc_tgt_offset_low; > + /* Bits/pixel target << 4 (ie., 4 fractional bits) */ > + u16 bits_per_pixel; > + /* > + * Factor to determine if an edge is present based > + * on the bits produced > + */ > + u8 rc_edge_factor; > + /* Slow down incrementing once the range reaches this value */ > + u8 rc_quant_incr_limit1; > + /* Slow down incrementing once the range reaches this value */ > + u8 rc_quant_incr_limit0; > + /* Number of pixels to delay the initial transmission */ > + u16 initial_xmit_delay; > + /* Number of pixels to delay the VLD on the decoder,not including SSM */ > + u16 initial_dec_delay; > + /* Block prediction enable */ > + bool block_pred_enable; > + /* Bits/group offset to use for first line of the slice */ > + u8 first_line_bpg_offset; > + /* Value to use for RC model offset at slice start */ > + u16 initial_offset; > + /* Thresholds defining each of the buffer ranges */ > + u16 rc_buf_thresh[DSC_NUM_BUF_RANGES - 1]; > + /* Parameters for each of the RC ranges */ > + struct dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES]; > + /* Total size of RC model */ > + u16 rc_model_size; > + /* Minimum QP where flatness information is sent */ > + u8 flatness_min_qp; > + /* Maximum QP where flatness information is sent */ > + u8 flatness_max_qp; > + /* Initial value for scale factor */ > + u8 initial_scale_value; > + /* Decrement scale factor every scale_decrement_interval groups */ > + u16 scale_decrement_interval; > + /* Increment scale factor every scale_increment_interval groups */ > + u16 scale_increment_interval; > + /* Non-first line BPG offset to use */ > + u16 nfl_bpg_offset; > + /* BPG offset used to enforce slice bit */ > + u16 slice_bpg_offset; > + /* Final RC linear transformation
Re: [PATCH 1/2] amdgpu: display: use modern ktime accessors
On 2018-06-18 11:35 AM, Arnd Bergmann wrote: > getrawmonotonic64() is deprecated because of the nonstandard naming. > > The replacement functions ktime_get_raw_ns() also simplifies the callers. > > Signed-off-by: Arnd Bergmann Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c | 8 > drivers/gpu/drm/amd/display/dc/dm_services.h | 5 - > 2 files changed, 4 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c > index 5a3346124a01..e861929dd981 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c > @@ -35,14 +35,6 @@ > #include "amdgpu_dm_irq.h" > #include "amdgpu_pm.h" > > -unsigned long long dm_get_timestamp(struct dc_context *ctx) > -{ > - struct timespec64 time; > - > - getrawmonotonic64(&time); > - return timespec64_to_ns(&time); > -} > - > unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, > unsigned long long current_time_stamp, > unsigned long long last_time_stamp) > diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h > b/drivers/gpu/drm/amd/display/dc/dm_services.h > index 4ff9b2bba178..eb5ab3978e84 100644 > --- a/drivers/gpu/drm/amd/display/dc/dm_services.h > +++ b/drivers/gpu/drm/amd/display/dc/dm_services.h > @@ -339,7 +339,10 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned > int controller_id); > #define dm_log_to_buffer(buffer, size, fmt, args)\ > vsnprintf(buffer, size, fmt, args) > > -unsigned long long dm_get_timestamp(struct dc_context *ctx); > +static inline unsigned long long dm_get_timestamp(struct dc_context *ctx) > +{ > + return ktime_get_raw_ns(); > +} > > unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, > unsigned long long current_time_stamp, > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amdgpu: Count disabled CRTCs in commit tail earlier
8041e000c70 88041e00efc0 > raw: 00170017 0001 > page dumped because: kasan: bad access detected > > Memory state around the buggy address: > 8803a697af00: fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > 8803a697af80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >> 8803a697b000: fc fc fc fc fc fc fc fc fc fc fc fc fc fb fb fb > ^ > 8803a697b080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > 8803a697b100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb > == > > So, we fix this by counting the number of CRTCs this atomic commit disabled > early on in the function before their atomic states have been freed, then use > that count later to do the appropriate number of RPM puts at the end of the > function. > > Fixes: 97028037a38ae ("drm/amdgpu: Grab/put runtime PM references in > atomic_commit_tail()") > Signed-off-by: Lyude Paul > Cc: Michel Dänzer > Reported-by: Michel Dänzer Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++ > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index f9add85157e7..689dbdf44bbf 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -4206,6 +4206,7 @@ static void amdgpu_dm_atomic_commit_tail(struct > drm_atomic_state *state) > struct drm_connector *connector; > struct drm_connector_state *old_con_state, *new_con_state; > struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; > + int crtc_disable_count = 0; > > drm_atomic_helper_update_legacy_modeset_state(dev, state); > > @@ -4410,6 +4411,9 @@ static void amdgpu_dm_atomic_commit_tail(struct > drm_atomic_state *state) > struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); > bool modeset_needed; > > + if (old_crtc_state->active && !new_crtc_state->active) > + crtc_disable_count++; > + > dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); > dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); > modeset_needed = modeset_required( > @@ -4463,11 +4467,9 @@ static void amdgpu_dm_atomic_commit_tail(struct > drm_atomic_state *state) >* so we can put the GPU into runtime suspend if we're not driving any >* displays anymore >*/ > + for (i = 0; i < crtc_disable_count; i++) > + pm_runtime_put_autosuspend(dev->dev); > pm_runtime_mark_last_busy(dev->dev); > - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, > new_crtc_state, i) { > - if (old_crtc_state->active && !new_crtc_state->active) > - pm_runtime_put_autosuspend(dev->dev); > - } > } > > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: don't initialize result
On 2018-06-17 04:53 AM, Stefan Agner wrote: > The wrong enum type is used to initialize the result, leading to a > warning when using clang: > drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:1998:26: warning: > implicit conversion from enumeration type 'enum ddc_result' to different > enumeration type 'enum dc_status' [-Wenum-conversion] > enum dc_status result = DDC_RESULT_UNKNOWN; >~~ ^~ > 1 warning generated. > > Initialization of result is unnecessary anyway, just drop the > initialization. > > Signed-off-by: Stefan Agner Thanks for the patch. Reviewed-by: Harry Wentland Ill merge this today. Harry > --- > drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > index 7857cb42b3e6..1dbfbfc0fd45 100644 > --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c > @@ -1995,7 +1995,7 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, > union hpd_irq_data *out_hpd > { > union hpd_irq_data hpd_irq_dpcd_data = 0; > union device_service_irq device_service_clear = { { 0 } }; > - enum dc_status result = DDC_RESULT_UNKNOWN; > + enum dc_status result; > bool status = false; > /* For use cases related to down stream connection status change, >* PSR and device auto test, refer to function handle_sst_hpd_irq > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: Pass crtc to .best_encoder()
On 2018-06-15 03:52 PM, Ville Syrjala wrote: > From: Ville Syrjälä > > To pick the correct MST encoder i915 wants to know which crtc is going > to be feeding us. To that end let's pass the crtc to the .best_encoder() > hook. The atomic variant already knows the crtc via the connector state, > but the non-atomic hooks is still being used by the fb_helper even on > atomic drivers. > > This allows us to fix up the possible_crtcs bitmask for the i915 MST > encoders. We have one encoder for each crtc+port combination, and thus > we have to know both the connector and the crtc to pick the right one. > This has only worked so far because every MST encoder lied in its > possible_crtcs bitmask that they can be driven by any crtc. > > I took the easy way out and passed NULL as the crtc for all the driver > internal uses of .best_encoder() in the amdgpu/radeon drivers. None of > the other drivers have such internal uses. The other callers > (crtc_helper, atomic_helper, fb_helper) will pass in the proper crtc. > but no one besides i915 will currently look at it. > > Cc: Alex Deucher > Cc: "Christian König" > Cc: "David (ChunMing) Zhou" > Cc: Harry Wentland > Cc: amd-...@lists.freedesktop.org > Signed-off-by: Ville Syrjälä amdgpu parts are Acked-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 33 + > drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 3 +- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-- > .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c| 5 +-- > drivers/gpu/drm/ast/ast_mode.c | 3 +- > drivers/gpu/drm/bochs/bochs_kms.c | 3 +- > drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 3 +- > drivers/gpu/drm/bridge/tc358767.c | 3 +- > drivers/gpu/drm/cirrus/cirrus_mode.c | 5 +-- > drivers/gpu/drm/drm_atomic_helper.c| 16 ++--- > drivers/gpu/drm/drm_crtc_helper.c | 3 +- > drivers/gpu/drm/drm_fb_helper.c| 41 > -- > drivers/gpu/drm/gma500/gma_display.c | 3 +- > drivers/gpu/drm/gma500/mdfld_dsi_output.c | 5 +-- > drivers/gpu/drm/gma500/psb_intel_drv.h | 3 +- > drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 +- > drivers/gpu/drm/i2c/tda998x_drv.c | 3 +- > drivers/gpu/drm/i915/intel_dp_mst.c| 9 +++-- > drivers/gpu/drm/imx/imx-ldb.c | 5 +-- > drivers/gpu/drm/imx/imx-tve.c | 5 +-- > drivers/gpu/drm/imx/parallel-display.c | 5 +-- > drivers/gpu/drm/mediatek/mtk_hdmi.c| 3 +- > drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-- > drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +- > drivers/gpu/drm/nouveau/dispnv50/disp.c| 3 +- > drivers/gpu/drm/nouveau/nouveau_connector.c| 3 +- > drivers/gpu/drm/qxl/qxl_display.c | 3 +- > drivers/gpu/drm/radeon/radeon_connectors.c | 40 +++-- > drivers/gpu/drm/radeon/radeon_dp_mst.c | 5 +-- > drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 3 +- > drivers/gpu/drm/tilcdc/tilcdc_panel.c | 5 +-- > drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 5 +-- > drivers/gpu/drm/udl/udl_connector.c| 3 +- > drivers/staging/vboxvideo/vbox_mode.c | 5 +-- > include/drm/drm_atomic_helper.h| 3 +- > include/drm/drm_modeset_helper_vtables.h | 6 ++-- > 36 files changed, 155 insertions(+), 106 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > index 8e66851eb427..3dfa50ec2589 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > @@ -135,7 +135,8 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector > *connector) > else { > const struct drm_connector_helper_funcs > *connector_funcs = > connector->helper_private; > - struct drm_encoder *encoder = > connector_funcs->best_encoder(connector); > + struct drm_encoder *encoder = > connector_funcs->best_encoder(connector, > + > NULL); > struct amdgpu_encoder *amdgpu_encoder = > to_amdgpu_encoder(encoder); > struct amdgpu_encoder_atom_dig *dig = > amdgpu_encoder->enc_priv; >
Re: [PATCH] drm: Pass crtc to .best_encoder()
On 2018-06-26 11:01 AM, Harry Wentland wrote: > On 2018-06-15 03:52 PM, Ville Syrjala wrote: >> From: Ville Syrjälä >> >> To pick the correct MST encoder i915 wants to know which crtc is going >> to be feeding us. To that end let's pass the crtc to the .best_encoder() >> hook. The atomic variant already knows the crtc via the connector state, >> but the non-atomic hooks is still being used by the fb_helper even on >> atomic drivers. >> >> This allows us to fix up the possible_crtcs bitmask for the i915 MST >> encoders. We have one encoder for each crtc+port combination, and thus >> we have to know both the connector and the crtc to pick the right one. >> This has only worked so far because every MST encoder lied in its >> possible_crtcs bitmask that they can be driven by any crtc. >> >> I took the easy way out and passed NULL as the crtc for all the driver >> internal uses of .best_encoder() in the amdgpu/radeon drivers. None of >> the other drivers have such internal uses. The other callers >> (crtc_helper, atomic_helper, fb_helper) will pass in the proper crtc. >> but no one besides i915 will currently look at it. >> >> Cc: Alex Deucher >> Cc: "Christian König" >> Cc: "David (ChunMing) Zhou" >> Cc: Harry Wentland >> Cc: amd-...@lists.freedesktop.org >> Signed-off-by: Ville Syrjälä > > amdgpu parts are > Acked-by: Harry Wentland > Upgrading after proper review of the entire patch Reviewed-by: Harry Wentland Harry > Harry > >> --- >> drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 33 + >> drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 3 +- >> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-- >> .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c| 5 +-- >> drivers/gpu/drm/ast/ast_mode.c | 3 +- >> drivers/gpu/drm/bochs/bochs_kms.c | 3 +- >> drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 3 +- >> drivers/gpu/drm/bridge/tc358767.c | 3 +- >> drivers/gpu/drm/cirrus/cirrus_mode.c | 5 +-- >> drivers/gpu/drm/drm_atomic_helper.c| 16 ++--- >> drivers/gpu/drm/drm_crtc_helper.c | 3 +- >> drivers/gpu/drm/drm_fb_helper.c| 41 >> -- >> drivers/gpu/drm/gma500/gma_display.c | 3 +- >> drivers/gpu/drm/gma500/mdfld_dsi_output.c | 5 +-- >> drivers/gpu/drm/gma500/psb_intel_drv.h | 3 +- >> drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 3 +- >> drivers/gpu/drm/i2c/tda998x_drv.c | 3 +- >> drivers/gpu/drm/i915/intel_dp_mst.c| 9 +++-- >> drivers/gpu/drm/imx/imx-ldb.c | 5 +-- >> drivers/gpu/drm/imx/imx-tve.c | 5 +-- >> drivers/gpu/drm/imx/parallel-display.c | 5 +-- >> drivers/gpu/drm/mediatek/mtk_hdmi.c| 3 +- >> drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +-- >> drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +- >> drivers/gpu/drm/nouveau/dispnv50/disp.c| 3 +- >> drivers/gpu/drm/nouveau/nouveau_connector.c| 3 +- >> drivers/gpu/drm/qxl/qxl_display.c | 3 +- >> drivers/gpu/drm/radeon/radeon_connectors.c | 40 >> +++-- >> drivers/gpu/drm/radeon/radeon_dp_mst.c | 5 +-- >> drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 3 +- >> drivers/gpu/drm/tilcdc/tilcdc_panel.c | 5 +-- >> drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 5 +-- >> drivers/gpu/drm/udl/udl_connector.c| 3 +- >> drivers/staging/vboxvideo/vbox_mode.c | 5 +-- >> include/drm/drm_atomic_helper.h| 3 +- >> include/drm/drm_modeset_helper_vtables.h | 6 ++-- >> 36 files changed, 155 insertions(+), 106 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> index 8e66851eb427..3dfa50ec2589 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c >> @@ -135,7 +135,8 @@ int amdgpu_connector_get_monitor_bpc(struct >> drm_connector *connector) >> else { >> const struct drm_connector_helper_funcs >> *connector_funcs = >> connector->helper_private; >> -struct drm_encoder *enco
Re: [PATCH] drm/amd/display: off by one in find_irq_source_info()
On 2018-07-04 05:46 AM, Dan Carpenter wrote: > The ->info[] array has DAL_IRQ_SOURCES_NUMBER elements so this condition > should be >= instead of > or we could read one element beyond the end of > the array. > > Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") > Signed-off-by: Dan Carpenter Reviewed-by: Harry Wentland Harry > > diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c > b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c > index dcdfa0f01551..604bea01fc13 100644 > --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c > +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c > @@ -78,7 +78,7 @@ const struct irq_source_info *find_irq_source_info( > struct irq_service *irq_service, > enum dc_irq_source source) > { > - if (source > DAL_IRQ_SOURCES_NUMBER || source < DC_IRQ_SOURCE_INVALID) > + if (source >= DAL_IRQ_SOURCES_NUMBER || source < DC_IRQ_SOURCE_INVALID) > return NULL; > > return &irq_service->info[source]; > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display/dc/dce: Fix multiple potential integer overflows
On 2018-07-04 03:38 AM, Michel Dänzer wrote: > On 2018-07-04 03:13 AM, Gustavo A. R. Silva wrote: >> Add suffix ULL to constant 5 and cast variables target_pix_clk_khz and >> feedback_divider to uint64_t in order to avoid multiple potential integer >> overflows and give the compiler complete information about the proper >> arithmetic to use. >> >> Notice that such constant and variables are used in contexts that >> expect expressions of type uint64_t (64 bits, unsigned). The current >> casts to uint64_t effectively apply to each expression as a whole, >> but they do not prevent them from being evaluated using 32-bit >> arithmetic instead of 64-bit arithmetic. >> >> Also, once the expressions are properly evaluated using 64-bit >> arithmentic, there is no need for the parentheses that enclose >> them. >> >> Addresses-Coverity-ID: 1460245 ("Unintentional integer overflow") >> Addresses-Coverity-ID: 1460286 ("Unintentional integer overflow") >> Addresses-Coverity-ID: 1460401 ("Unintentional integer overflow") >> Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") >> Signed-off-by: Gustavo A. R. Silva >> >> [...] >> >> @@ -145,8 +145,8 @@ static bool calculate_fb_and_fractional_fb_divider( >> * of fractional feedback decimal point and the fractional FB Divider >> precision >> * is 2 then the equation becomes (ullfeedbackDivider + 5*100) / (10*100))*/ >> >> -feedback_divider += (uint64_t) >> -(5 * calc_pll_cs->fract_fb_divider_precision_factor); >> +feedback_divider += 5UL * >> +calc_pll_cs->fract_fb_divider_precision_factor; > > This should be 5ULL, as the commit log says, otherwise it's still only > 32 bits on 32-bit platforms. > Agreed. Otherwise this looks good. With that fixed this patch is Reviewed-by: Harry Wentland Harry > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: Use 2-factor allocator calls
On 2018-07-04 01:27 PM, Kees Cook wrote: > As already done treewide, switch from open-coded multiplication to > 2-factor allocation helper. > > Signed-off-by: Kees Cook Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c > b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c > index 98edaefa2b47..ee69c949bfbf 100644 > --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c > +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c > @@ -1723,8 +1723,8 @@ bool mod_color_calculate_curve(enum > dc_transfer_func_predefined trans, > kvfree(rgb_regamma); > } else if (trans == TRANSFER_FUNCTION_HLG || > trans == TRANSFER_FUNCTION_HLG12) { > - rgb_regamma = kvzalloc(sizeof(*rgb_regamma) * > -(MAX_HW_POINTS + _EXTRA_POINTS), > + rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, > +sizeof(*rgb_regamma), > GFP_KERNEL); > if (!rgb_regamma) > goto rgb_regamma_alloc_fail; > @@ -1802,8 +1802,8 @@ bool mod_color_calculate_degamma_curve(enum > dc_transfer_func_predefined trans, > kvfree(rgb_degamma); > } else if (trans == TRANSFER_FUNCTION_HLG || > trans == TRANSFER_FUNCTION_HLG12) { > - rgb_degamma = kvzalloc(sizeof(*rgb_degamma) * > -(MAX_HW_POINTS + _EXTRA_POINTS), > + rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, > +sizeof(*rgb_degamma), > GFP_KERNEL); > if (!rgb_degamma) > goto rgb_degamma_alloc_fail; > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display/dc/dce: Fix multiple potential integer overflows
On 2018-07-04 01:54 PM, Gustavo A. R. Silva wrote: > > > On 07/04/2018 12:51 PM, Harry Wentland wrote: > [..] >>>> >>>> @@ -145,8 +145,8 @@ static bool calculate_fb_and_fractional_fb_divider( >>>> * of fractional feedback decimal point and the fractional FB Divider >>>> precision >>>> * is 2 then the equation becomes (ullfeedbackDivider + 5*100) / >>>> (10*100))*/ >>>> >>>> - feedback_divider += (uint64_t) >>>> - (5 * calc_pll_cs->fract_fb_divider_precision_factor); >>>> + feedback_divider += 5UL * >>>> + calc_pll_cs->fract_fb_divider_precision_factor; >>> >>> This should be 5ULL, as the commit log says, otherwise it's still only >>> 32 bits on 32-bit platforms. >>> >> >> Agreed. >> >> Otherwise this looks good. >> >> With that fixed this patch is >> Reviewed-by: Harry Wentland >> > > Hi Harry, > > I already sent v2: https://patchwork.kernel.org/patch/10506897/ > Thanks. Merged. Harry > Thanks > -- > Gustavo > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/9] drm: Add variable refresh rate properties to DRM connector
On 2018-09-11 01:56 PM, Ville Syrjälä wrote: > On Tue, Sep 11, 2018 at 01:36:01PM -0400, Kazlauskas, Nicholas wrote: >> On 09/11/2018 12:31 PM, Ville Syrjälä wrote: >>> On Tue, Sep 11, 2018 at 07:22:43PM +0300, Ville Syrjälä wrote: On Tue, Sep 11, 2018 at 12:13:25PM -0400, Nicholas Kazlauskas wrote: > Modern monitor hardware is capable of supporting variable refresh rates > and adaptive sync technologies. The properties for querying and > controlling these features should be exposed on the DRM connector. > > This patch introduces two new properties for variable refresh rate > support: > > - variable_refresh_capable > - variable_refresh_enabled > > These are optional properties that can be added to a DRM connector > dynamically by using drm_connector_attach_variable_refresh_properties. > > DRM drivers should set variable_refresh_capable as applicable for > their hardware. The property variable_refresh_enabled as a userspace > controlled option. > > Change-Id: I5f60f8b57534e1d3dacda4c64c6c9106b42f4439 > Signed-off-by: Nicholas Kazlauskas > --- > drivers/gpu/drm/drm_atomic.c| 9 + > drivers/gpu/drm/drm_connector.c | 35 + > include/drm/drm_connector.h | 27 + > 3 files changed, 71 insertions(+) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index d0478abc01bd..2f89ab0fac87 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -1403,6 +1403,11 @@ static int > drm_atomic_connector_set_property(struct drm_connector *connector, > state->content_type = val; > } else if (property == connector->scaling_mode_property) { > state->scaling_mode = val; > + } else if (property == connector->variable_refresh_capable_property) { > + DRM_DEBUG_KMS("only drivers can set > variable_refresh_capable\n"); > + return -EINVAL; Why is that needed? Why not just avoid exposing the vrr_enabled prop when it's not supported? >>> >>> Ah, I guess you want to change the value after plugging in a new >>> display. Yeah, if we don't want userspace to have to parse the EDID I >>> guess we need this. But in that case it should be marked immutable, >>> and then you don't need any of this atomic state related code for it. >> >> Yeah, it's for hotplugging that it works this way. The reason it's not >> marked as immutable is mostly convention - the existing driver >> write-only properties (with userspace queries) do the same thing. >> >> The immutable property flag is only used for non-connector properties. > > There are plenty of immutable connector properties: EDID, TILE, > non-desktop, etc. I'm pretty sure there are more immutable connector > properties than there are immutable properties on other types of > objects. And considering immutable connector properties existed > before other types of objects even had any properties I'd say > it's well established by now :) > >> During testing I also noticed that something likes to cache the initial >> default value for these immutable flagged properties for userspace >> queries - so when you call xrandr you only end up seeing the default >> value and not the current. > > 'xrandr --current' is supposed to not probe hard for new stuff. Without > the --current it may or may not result in a full probe depending on the > implementation in the ddx and or the kms driver. A full probe should > definitely happen after a hotplug. If it's not happening then there is > a bug somewhere. > >> >>> > + } else if (property == connector->variable_refresh_enabled_property) { > + state->variable_refresh_enabled = val; So one thing I already asked long ago is whether there would a point in exposing some kind of min/max refresh rate range control. Never really got an answer. Was somehting like that considered and rejected? >> >> For the initial patchset it seemed best to keep things simple and target >> the dynamic adaptation usecase with on/off toggle. >> >> The driver having access to the full range can enable additional >> functionality that can improve the user experience - a good example is >> low framerate compensation. >> >> Adding the properties to support setting the min/max could be done on >> top of this, however. Driver behavior would likely need to be defined >> for atomic check. The driver needs to verify with the monitor that the >> ranges are valid at some point - whether it silently fails or returns an >> error is an example of something to consider here. >> >> Do you have a specific usecase in mind that needs min/max exposed to >> userspace? > > Not really. Some vague ideas about video playback and such, and maybe > just for power saving. It was just an idea that occurred to
Re: EVoC Program
Adding e...@foundation.x.org and Trevor. He or someone else on the evoc list can probably point you in the right direction. Harry On 2018-09-20 03:06 AM, Sidharth Bansal wrote: > Hi > I want to contribute towards XOrg for EVoC. Can anyone guide me? > Thanks > Sidharth Bansal > > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/2] drm/amdgpu: Use per-device driver_features to disable atomic
On 2018-09-13 12:31 PM, Ville Syrjala wrote: > From: Ville Syrjälä > > Disable atomic on a per-device basis instead of for all devices. > Made possible by the new device.driver_features thing. > > Cc: Alex Deucher > Cc: "Christian König" > Cc: "David (ChunMing) Zhou" > Cc: Harry Wentland > Cc: Michel Dänzer > Suggested-by: Michel Dänzer > Signed-off-by: Ville Syrjälä Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 > 1 file changed, 4 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 6870909da926..8c1db96be070 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -816,17 +816,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, > if (ret) > return ret; > > - /* warn the user if they mix atomic and non-atomic capable GPUs */ > - if ((kms_driver.driver_features & DRIVER_ATOMIC) && !supports_atomic) > - DRM_ERROR("Mixing atomic and non-atomic capable GPUs!\n"); > - /* support atomic early so the atomic debugfs stuff gets created */ > - if (supports_atomic) > - kms_driver.driver_features |= DRIVER_ATOMIC; > - > dev = drm_dev_alloc(&kms_driver, &pdev->dev); > if (IS_ERR(dev)) > return PTR_ERR(dev); > > + if (!supports_atomic) > + dev->driver_features &= ~DRIVER_ATOMIC; > + > ret = pci_enable_device(pdev); > if (ret) > goto err_free; > @@ -1078,7 +1074,7 @@ amdgpu_get_crtc_scanout_position(struct drm_device > *dev, unsigned int pipe, > > static struct drm_driver kms_driver = { > .driver_features = > - DRIVER_USE_AGP | > + DRIVER_USE_AGP | DRIVER_ATOMIC | > DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | > DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ, > .load = amdgpu_driver_load_kms, > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check()
On 2018-09-18 07:06 PM, Lyude Paul wrote: > Currently the way that we prevent userspace from performing new modesets > on MST connectors that have just been destroyed is rather broken. > There's nothing in the actual DRM DP MST topology helpers that checks > whether or not a connector still exists, instead each DRM driver does > this on it's own, usually by returning NULL from the best_encoder > callback which in turn, causes the atomic commit to fail. > > However, this is wrong in a rather subtle way. If ->best_encoder() > returns NULL, this makes ALL modesets involving the connector fail. This > includes modesets from userspace that would shut off the CRTCs being > used by the connector. Since this results in blocking any changes to a > connector's DPMS prop, it has the sideaffect of preventing legacy > modesetting users from ever disabling a CRTC that was previously enabled > for use in an MST topology. An example of this, where X tries to > change the DPMS property of an MST connector that was just detached from > the system: > > [ 2908.320131] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] > [CONNECTOR:82:DP-6] > [ 2908.320148] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] > [CONNECTOR:82:DP-6] status updated from connected to disconnected > [ 2908.320166] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] > [CONNECTOR:82:DP-6] disconnected > [ 2908.320193] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 111 (1) > [ 2908.320230] [drm:drm_sysfs_hotplug_event [drm]] generating hotplug event > ... > [ 2908.638539] [drm:drm_ioctl [drm]] pid=12928, dev=0xe201, auth=1, > DRM_IOCTL_MODE_SETPROPERTY > [ 2908.638546] [drm:drm_atomic_state_init [drm]] Allocated atomic state > 7155ba49 > [ 2908.638553] [drm:drm_mode_object_get [drm]] OBJ ID: 114 (1) > [ 2908.638560] [drm:drm_mode_object_get [drm]] OBJ ID: 108 (1) > [ 2908.638568] [drm:drm_atomic_get_crtc_state [drm]] Added [CRTC:41:head-0] > 97a6396e state to 7155ba49 > [ 2908.638575] [drm:drm_atomic_add_affected_connectors [drm]] Adding all > current connectors for [CRTC:41:head-0] to 7155ba49 > [ 2908.638582] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (3) > [ 2908.638589] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (4) > [ 2908.638596] [drm:drm_atomic_get_connector_state [drm]] Added > [CONNECTOR:82:DP-6] 87427144 state to 7155ba49 > [ 2908.638603] [drm:drm_atomic_check_only [drm]] checking 7155ba49 > [ 2908.638609] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] > [CRTC:41:head-0] active changed > [ 2908.638613] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] > Updating routing for [CONNECTOR:82:DP-6] > [ 2908.638616] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] No > suitable encoder found for [CONNECTOR:82:DP-6] > [ 2908.638623] [drm:drm_atomic_check_only [drm]] atomic driver check for > 7155ba49 failed: -22 > [ 2908.638630] [drm:drm_atomic_state_default_clear [drm]] Clearing atomic > state 7155ba49 > [ 2908.638637] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (4) > [ 2908.638643] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (3) > [ 2908.638650] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 114 (2) > [ 2908.638656] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 108 (2) > [ 2908.638663] [drm:__drm_atomic_state_free [drm]] Freeing atomic state > 7155ba49 > [ 2908.638669] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (2) > [ 2908.638676] [drm:drm_ioctl [drm]] pid=12928, ret = -22 > > While this doesn't usually result in any errors that would be obvious to > the user, it does result in us leaving display resources on. This in > turn leads to unwanted sideaffects like inactive GPUs being left on > (usually from the resulting leaked runtime PM ref). > > So, provide an easier way of doing this that doesn't require breaking > ->best_encoder(): add a common drm_dp_mst_connector_atomic_check() > function that DRM drivers can call in order to have CRTC enabling > commits fail automatically if the MST port driving the connector no > longer exists. We'll also be able to expand upon this later as well once > we add MST fallback retraining support. > > Signed-off-by: Lyude Paul > Cc: sta...@vger.kernel.org This does seem like a saner way to handle the case when the MST connector is gone. As this doesn't currently seem to affect amdgpu directly and I therefore might miss something I'll leave the RB to someone else, but you have my Acked-by: Harry Wentland Harry > --- > drivers/gpu/drm/drm_dp_mst_topology.c | 76 +++ > include/drm/drm_dp_mst_helper.h | 3 ++ > 2 files changed, 7
Re: [PATCH 6/6] drm/amdgpu/dm/mst: Use drm_dp_mst_connector_atomic_check()
On 2018-09-18 07:06 PM, Lyude Paul wrote: > Hook this into amdgpu's atomic check for their connectors so they never > get modesets on no-longer-present MST connectors. We'll also expand on > this later once we add DP MST fallback retraining support. > > As well, turns out that the only atomic DRM driver without the > ->best_encoder() bug is amdgpu. Congrats AMD! > > Signed-off-by: Lyude Paul Reviewed-by: Harry Wentland Harry > --- > .../drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 12 > 1 file changed, 12 insertions(+) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > index 9a300732ba37..d011a39f17b2 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c > @@ -294,10 +294,22 @@ static struct drm_encoder *dm_mst_best_encoder(struct > drm_connector *connector) > return &amdgpu_dm_connector->mst_encoder->base; > } > > +static int > +amdgpu_dm_mst_connector_atomic_check(struct drm_connector *connector, > + struct drm_connector_state *new_cstate) > +{ > + struct amdgpu_dm_connector *aconnector = > + to_amdgpu_dm_connector(connector); > + > + return drm_dp_mst_connector_atomic_check(connector, new_cstate, > + &aconnector->mst_mgr); > +} > + > static const struct drm_connector_helper_funcs > dm_dp_mst_connector_helper_funcs = { > .get_modes = dm_dp_mst_get_modes, > .mode_valid = amdgpu_dm_connector_mode_valid, > .best_encoder = dm_mst_best_encoder, > + .atomic_check = amdgpu_dm_mst_connector_atomic_check, > }; > > static void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder) > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check()
On 2018-09-19 07:08 PM, Lyude Paul wrote: > Currently the way that we prevent userspace from performing new modesets > on MST connectors that have just been destroyed is rather broken. > There's nothing in the actual DRM DP MST topology helpers that checks > whether or not a connector still exists, instead each DRM driver does > this on it's own, usually by returning NULL from the best_encoder > callback which in turn, causes the atomic commit to fail. > > However, this is wrong in a rather subtle way. If ->best_encoder() > returns NULL, this makes ALL modesets involving the connector fail. This > includes modesets from userspace that would shut off the CRTCs being > used by the connector. Since this results in blocking any changes to a > connector's DPMS prop, it has the sideaffect of preventing legacy > modesetting users from ever disabling a CRTC that was previously enabled > for use in an MST topology. An example of this, where X tries to > change the DPMS property of an MST connector that was just detached from > the system: > > [ 2908.320131] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] > [CONNECTOR:82:DP-6] > [ 2908.320148] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] > [CONNECTOR:82:DP-6] status updated from connected to disconnected > [ 2908.320166] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] > [CONNECTOR:82:DP-6] disconnected > [ 2908.320193] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 111 (1) > [ 2908.320230] [drm:drm_sysfs_hotplug_event [drm]] generating hotplug event > ... > [ 2908.638539] [drm:drm_ioctl [drm]] pid=12928, dev=0xe201, auth=1, > DRM_IOCTL_MODE_SETPROPERTY > [ 2908.638546] [drm:drm_atomic_state_init [drm]] Allocated atomic state > 7155ba49 > [ 2908.638553] [drm:drm_mode_object_get [drm]] OBJ ID: 114 (1) > [ 2908.638560] [drm:drm_mode_object_get [drm]] OBJ ID: 108 (1) > [ 2908.638568] [drm:drm_atomic_get_crtc_state [drm]] Added [CRTC:41:head-0] > 97a6396e state to 7155ba49 > [ 2908.638575] [drm:drm_atomic_add_affected_connectors [drm]] Adding all > current connectors for [CRTC:41:head-0] to 7155ba49 > [ 2908.638582] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (3) > [ 2908.638589] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (4) > [ 2908.638596] [drm:drm_atomic_get_connector_state [drm]] Added > [CONNECTOR:82:DP-6] 87427144 state to 7155ba49 > [ 2908.638603] [drm:drm_atomic_check_only [drm]] checking 7155ba49 > [ 2908.638609] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] > [CRTC:41:head-0] active changed > [ 2908.638613] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] > Updating routing for [CONNECTOR:82:DP-6] > [ 2908.638616] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] No > suitable encoder found for [CONNECTOR:82:DP-6] > [ 2908.638623] [drm:drm_atomic_check_only [drm]] atomic driver check for > 7155ba49 failed: -22 > [ 2908.638630] [drm:drm_atomic_state_default_clear [drm]] Clearing atomic > state 7155ba49 > [ 2908.638637] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (4) > [ 2908.638643] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (3) > [ 2908.638650] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 114 (2) > [ 2908.638656] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 108 (2) > [ 2908.638663] [drm:__drm_atomic_state_free [drm]] Freeing atomic state > 7155ba49 > [ 2908.638669] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (2) > [ 2908.638676] [drm:drm_ioctl [drm]] pid=12928, ret = -22 > > While this doesn't usually result in any errors that would be obvious to > the user, it does result in us leaving display resources on. This in > turn leads to unwanted sideaffects like inactive GPUs being left on > (usually from the resulting leaked runtime PM ref). > > So, provide an easier way of doing this that doesn't require breaking > ->best_encoder(): add a common drm_dp_mst_connector_atomic_check() > function that DRM drivers can call in order to have CRTC enabling > commits fail automatically if the MST port driving the connector no > longer exists. We'll also be able to expand upon this later as well once > we add MST fallback retraining support. > > Changes since v1: > - Use list_for_each_entry_safe in drm_dp_mst_connector_still_exists() - > Julia Lawall > > Signed-off-by: Lyude Paul > Cc: Julia Lawall > Cc: sta...@vger.kernel.org Whoops, missed the v2 earlier. It's still Acked-by: Harry Wentland Harry > --- > drivers/gpu/drm/drm_dp_mst_topology.c | 76 +++ > include/drm/drm_dp_mst_helper.h | 3 ++ > 2 files changed, 79 insertions(+) > > diff --git a/driver
Re: [PATCH] drm/amd/display: Change status's type in aux_reply_transaction_data
On 2018-09-24 06:22 PM, Nathan Chancellor wrote: > On Mon, Sep 24, 2018 at 03:07:16PM -0700, Nick Desaulniers wrote: >> On Fri, Sep 21, 2018 at 2:55 PM Nathan Chancellor >> wrote: >>> >>> Clang warns when one enumerated type is implicitly converted to another. >>> >>> drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.c:315:19: warning: >>> implicit conversion from enumeration type 'enum >>> aux_channel_operation_result' to different enumeration type 'enum >>> aux_transaction_reply' [-Wenum-conversion] >>> reply->status = AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; >>> ~ ^~~ >>> drivers/gpu/drm/amd/amdgpu/../display/dc/i2caux/dce110/aux_engine_dce110.c:349:19: >>> warning: implicit conversion from enumeration type 'enum >>> aux_channel_operation_result' to different enumeration type 'enum >>> aux_transaction_reply' [-Wenum-conversion] >>> reply->status = AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; >>> ~ ^~~ >> >> I think the enum is actually wrong here. I think the correct fix would be: >> >> - reply->status = AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; >> + reply->status = AUX_TRANSACTION_REPLY_HPD_DISCON; >> >> The identifiers are so similar, my guess was that it was easy to mix >> them up. This looks like an actual bug to me, since the identifiers >> have different values between the 2 different enums. >> > > Hmmm interesting... I will be happy to send a v2 with your suggestion if > one of the maintainers could confirm that to be the case (given DRM code > is rather dense). > Nick is correct. We should keep the enum but assign AUX_TRANSACTION_REPLY_HPD_DISCON in dce_aux.c and aux_engine_dce110.c. Thanks for spotting this. Harry > Thanks for the review! > Nathan > >>> >>> Instead of implicitly or explicitly converting between types, just >>> change status to type uint8_t (since its max size is 255) which avoids >>> this construct altogether. >>> >>> Reported-by: Nick Desaulniers >>> Signed-off-by: Nathan Chancellor >>> --- >>> drivers/gpu/drm/amd/display/dc/dc_ddc_types.h | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h >>> b/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h >>> index 05c8c31d8b31..97e1d4d19263 100644 >>> --- a/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h >>> +++ b/drivers/gpu/drm/amd/display/dc/dc_ddc_types.h >>> @@ -79,7 +79,7 @@ enum aux_transaction_reply { >>> }; >>> >>> struct aux_reply_transaction_data { >>> - enum aux_transaction_reply status; >>> + uint8_t status; >>> uint32_t length; >>> uint8_t *data; >>> }; >>> -- >>> 2.19.0 >>> >> >> >> -- >> Thanks, >> ~Nick Desaulniers ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: 答复: 答复: [alsa-devel] 答复: [PATCH] vgaswitchroo: set audio client id according to bound gpu client id
On 2018-07-15 10:36 AM, Alex Deucher wrote: > On Sat, Jul 14, 2018 at 12:31 PM, Takashi Iwai wrote: >> On Sat, 14 Jul 2018 14:03:26 +0200, >> jimqu wrote: >>> >>> >>> >>> 在 2018/7/13 23:07, Takashi Iwai 写道: On Wed, 11 Jul 2018 13:12:01 +0200, Takashi Iwai wrote: > And the forced runtime PM is still an issue, and this would need the > other notification mechanism than the HD-audio unsolicited event as > AMD HDMI controller doesn't honor the HD-audio WAKEEN bit. Since we had a nice "hack week" in this week at SUSE, I spent some time to write some patches for the support of the direct hotplug notification / ELD query between HD-audio and radeon/amdgpu. It re-utilizes the audio component framework for i915 but in a slightly more flexible way. The patches are found in topic/hda-acomp branch of my sound.git tree: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git The following commits are relevant: drm/i915: Split audio component to a generic type ALSA: hda/i915: Allow delayed i915 audio component binding ALSA: hda/i915: Associate audio component with devres ALSA: hda: Make audio component support more generic ALSA: hda/hdmi: Allow audio component for AMD/ATI HDMI ALSA: hda/hdmi: Use single mutex unlock in error paths drm/radeon: Add audio component support drm/amdgpu: Add audio component support The branch should be cleanly pullable onto the latest 4.18-rc. I couldn't test amdgpu but the test with a radeon driver on an old laptop seemed working through a very quick test. Please give it a try. >>> >>> That is really wonderful work. I will check it on our AMD >>> platform. >> >> Thanks, it'll be great if you can check whether the current code works >> or not. I'd love to push the stuff for 4.19. Hopefully I'll start >> submitting the preparation patches in the next week. >> >> Basically this also opens the door of the similar capability for >> nouveau, and I guess it's also trivial enough. >> >>> BTW, For display, AMD has moved to use DC to support new >>> asics. so there also need a patch for amdgpu in DC code. >> >> Could you give a more hint? I'll try adapt the code if such a change >> is already in upstream tree. > > The new code is in drivers/gpu/drm/amd/display. > In particular, I imagine all you need should be in display/amdgpu_dm, although there's chance you might have to touch display/dc/dce/dce_audio.c if you have to do anything with the unsolicited event. I see you're using the GPL license, rather than MIT in amdgpu_audio.c. Since the code in display/dc is shared with other OSes and internal test frameworks it has to be MIT. Not entirely sure about display/amdgpu_dm, but if GPL is fine in amd/amdgpu it's probably fine there as well. Harry > Alex > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 00/10] Add helper for plane reset
On 2018-07-20 05:14 PM, Alexandru Gheorghe wrote: > Drivers that subclass drm_plane need to copy the logic for linking the > drm_plane with its state and to initialize core properties to their > default values. E.g (alpha and rotation) > > Having a helper to reset the plane_state makes sense because of multiple > reasons: > 1. Eliminate code duplication. > 2. Add a single place for initializing core properties to their > default values, no need for driver to do it if what the helper sets > makes sense for them. > 3. No need to debug the driver when you enable a core property and > observe it doesn't have a proper default value. > > Tested with mali-dp the other drivers are just built-tested. > For some reason I lost 02/10 hence I'm replying to the cover letter. Patches 1 & 2 are Reviewed-by: Harry Wentland Harry > > Alexandru Gheorghe (10): > drm/atomic: Add __drm_atomic_helper_plane_reset > drm/amd/display: Use __drm_atomic_helper_plane_reset instead of > copying the logic > drm: mali-dp: Use __drm_atomic_helper_plane_reset instead of copying > the logic > drm: atmel-hlcdc: Use __drm_atomic_helper_plane_reset instead of > copying the logic > drm/exynos: Use __drm_atomic_helper_plane_reset instead of copying the > logic > drm/imx: Use __drm_atomic_helper_plane_reset instead of copying the > logic > drm: rcar-du: Use __drm_atomic_helper_plane_reset instead of copying > the logic > drm/sun4i: Use __drm_atomic_helper_plane_reset instead of copying the > logic > drm/vc4: Use __drm_atomic_helper_plane_reset instead of copying the > logic > drm/vmwgfx: Use __drm_atomic_helper_plane_reset instead of copying the > logic > > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++-- > drivers/gpu/drm/arm/malidp_planes.c | 7 ++-- > .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 5 +-- > drivers/gpu/drm/drm_atomic_helper.c | 32 +-- > drivers/gpu/drm/exynos/exynos_drm_plane.c | 3 +- > drivers/gpu/drm/imx/ipuv3-plane.c | 8 ++--- > drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +-- > drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +-- > drivers/gpu/drm/sun4i/sun4i_layer.c | 4 +-- > drivers/gpu/drm/vc4/vc4_plane.c | 4 +-- > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +-- > include/drm/drm_atomic_helper.h | 2 ++ > 12 files changed, 39 insertions(+), 45 deletions(-) > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/amd/display: add missing void parameter to dc_create_transfer_func
On 2018-07-31 06:42 AM, Colin King wrote: > From: Colin Ian King > > Add a missing void parameter to function dc_create_transfer_func, fixes > sparse warning: > > warning: non-ANSI function declaration of function 'dc_create_transfer_func' > > Signed-off-by: Colin Ian King Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c > b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c > index 815dfb50089b..8fb3aefd195c 100644 > --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c > @@ -192,7 +192,7 @@ void dc_transfer_func_release(struct dc_transfer_func *tf) > kref_put(&tf->refcount, dc_transfer_func_free); > } > > -struct dc_transfer_func *dc_create_transfer_func() > +struct dc_transfer_func *dc_create_transfer_func(void) > { > struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL); > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 03/44] drm/vkms: Add kunit tests for VKMS LUT handling
On 2024-08-27 13:49, Louis Chauvet wrote: > Le 19/08/24 - 16:56, Harry Wentland a écrit : > > [...] > >> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c >> b/drivers/gpu/drm/vkms/vkms_composer.c >> index 3d6785d081f2..3ecda70c2b55 100644 >> --- a/drivers/gpu/drm/vkms/vkms_composer.c >> +++ b/drivers/gpu/drm/vkms/vkms_composer.c >> @@ -435,3 +435,7 @@ int vkms_set_crc_source(struct drm_crtc *crtc, const >> char *src_name) > diff --git a/drivers/gpu/drm/vkms/vkms_composer.c > b/drivers/gpu/drm/vkms/vkms_composer.c > index 3d6785d081f2..3ecda70c2b55 100644 > --- a/drivers/gpu/drm/vkms/vkms_composer.c > +++ b/drivers/gpu/drm/vkms/vkms_composer.c > @@ -435,3 +435,7 @@ int vkms_set_crc_source(struct drm_crtc *crtc, const char > *src_name) > > return ret; > } > + > +#ifdef CONFIG_DRM_VKMS_KUNIT_TESTS > +#include "tests/vkms_color_tests.c" > +#endif> >> return ret; >> } >> + >> +#ifdef CONFIG_DRM_VKMS_KUNIT_TESTS >> +#include "tests/vkms_color_tests.c" >> +#endif > > This is very strange to include a .c in this file, is it something done a > lot in the kernel? I can find only one occurence of this pattern in the > kernel [1], the other tests are in their own modules. > > In addition it crate many warning during compilations: > warning: symbol 'test_*' was not declared. Should it be static? > > As other tests will be introduced (yuv [2], config [3]), it is maybe > interesting to introduce a new module as [2] is doing? The VISIBLE_IF_KUNIT et al. is much nicer than including a .c file. Thanks for pointing me to them. Will change this. Harry > > [1]: https://elixir.bootlin.com/linux/v6.11-rc5/source/fs/ext4/mballoc.c#L7047 > [2]: https://lore.kernel.org/all/20240809-yuv-v10-14-1a7c76416...@bootlin.com/ > [3]: > https://lore.kernel.org/all/20240814-google-remove-crtc-index-from-parameter-v1-15-6e179abf9...@bootlin.com/ >
Re: [RESEND 3/3] drm/amd/display: switch to guid_gen() to generate valid GUIDs
On 2024-08-28 09:58, Alex Deucher wrote: > On Wed, Aug 28, 2024 at 9:53 AM Jani Nikula wrote: >> >> On Wed, 28 Aug 2024, Daniel Vetter wrote: >>> On Mon, Aug 12, 2024 at 03:23:12PM +0300, Jani Nikula wrote: >>>> Instead of just smashing jiffies into a GUID, use guid_gen() to generate >>>> RFC 4122 compliant GUIDs. >>>> >>>> Signed-off-by: Jani Nikula >>>> >>>> --- >>>> >>>> Side note, it baffles me why amdgpu has a copy of this instead of >>>> plumbing it into drm mst code. >>> >>> Yeah ec5fa9fcdeca ("drm/amd/display: Adjust the MST resume flow") promised >>> a follow-up, but that seems to have never materialized. Really should >>> materialize though. Patch lgtm >>> >>> Reviewed-by: Daniel Vetter >> >> Thanks! >> >> Cc: AMD folks, ack for merging the series via drm-misc-next? > > Unless Harry has any objections, > Acked-by: Alex Deucher > Acked-by: Harry Wentland Harry >> >> BR, >> Jani. >> >> >>> >>> >>>> --- >>>> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++- >>>> 1 file changed, 12 insertions(+), 11 deletions(-) >>>> >>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >>>> index 72c10fc2c890..ce05e7e2a383 100644 >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c >>>> @@ -2568,9 +2568,9 @@ static int dm_late_init(void *handle) >>>> >>>> static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr) >>>> { >>>> +u8 buf[UUID_SIZE]; >>>> +guid_t guid; >>>> int ret; >>>> -u8 guid[16]; >>>> -u64 tmp64; >>>> >>>> mutex_lock(&mgr->lock); >>>> if (!mgr->mst_primary) >>>> @@ -2591,26 +2591,27 @@ static void resume_mst_branch_status(struct >>>> drm_dp_mst_topology_mgr *mgr) >>>> } >>>> >>>> /* Some hubs forget their guids after they resume */ >>>> -ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); >>>> -if (ret != 16) { >>>> +ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, buf, sizeof(buf)); >>>> +if (ret != sizeof(buf)) { >>>> drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during >>>> suspend?\n"); >>>> goto out_fail; >>>> } >>>> >>>> -if (memchr_inv(guid, 0, 16) == NULL) { >>>> -tmp64 = get_jiffies_64(); >>>> -memcpy(&guid[0], &tmp64, sizeof(u64)); >>>> -memcpy(&guid[8], &tmp64, sizeof(u64)); >>>> +import_guid(&guid, buf); >>>> >>>> -ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16); >>>> +if (guid_is_null(&guid)) { >>>> +guid_gen(&guid); >>>> +export_guid(buf, &guid); >>>> >>>> -if (ret != 16) { >>>> +ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, buf, sizeof(buf)); >>>> + >>>> +if (ret != sizeof(buf)) { >>>> drm_dbg_kms(mgr->dev, "check mstb guid failed - >>>> undocked during suspend?\n"); >>>> goto out_fail; >>>> } >>>> } >>>> >>>> -import_guid(&mgr->mst_primary->guid, guid); >>>> +guid_copy(&mgr->mst_primary->guid, &guid); >>>> >>>> out_fail: >>>> mutex_unlock(&mgr->lock); >>>> -- >>>> 2.39.2 >>>> >> >> -- >> Jani Nikula, Intel
Re: [PATCH 1/2] drm/amd/display: Avoid race between dcn10_set_drr() and dc_state_destruct()
On 2024-09-02 05:40, tjak...@math.uni-bielefeld.de wrote: > From: Tobias Jakobi > > dc_state_destruct() nulls the resource context of the DC state. The pipe > context passed to dcn10_set_drr() is a member of this resource context. > > If dc_state_destruct() is called parallel to the IRQ processing (which > calls dcn10_set_drr() at some point), we can end up using already nulled > function callback fields of struct stream_resource. > > The logic in dcn10_set_drr() already tries to avoid this, by checking tg > against NULL. But if the nulling happens exactly after the NULL check and > before the next access, then we get a race. > > Avoid this by copying tg first to a local variable, and then use this > variable for all the operations. This should work, as long as nobody > frees the resource pool where the timing generators live. > > Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3142 > Fixes: 06ad7e164256 ("drm/amd/display: Destroy DC context while keeping DML > and DML2") > Signed-off-by: Tobias Jakobi Thanks for this fix. It also makes the code more readable. Reviewed-by: Harry Wentland Harry > --- > .../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 20 +++ > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c > b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c > index 3306684e805a..da8f2cb3c5db 100644 > --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c > +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c > @@ -3223,15 +3223,19 @@ void dcn10_set_drr(struct pipe_ctx **pipe_ctx, >* as well. >*/ > for (i = 0; i < num_pipes; i++) { > - if ((pipe_ctx[i]->stream_res.tg != NULL) && > pipe_ctx[i]->stream_res.tg->funcs) { > - if (pipe_ctx[i]->stream_res.tg->funcs->set_drr) > - pipe_ctx[i]->stream_res.tg->funcs->set_drr( > - pipe_ctx[i]->stream_res.tg, ¶ms); > + /* dc_state_destruct() might null the stream resources, so > fetch tg > + * here first to avoid a race condition. The lifetime of the > pointee > + * itself (the timing_generator object) is not a problem here. > + */ > + struct timing_generator *tg = pipe_ctx[i]->stream_res.tg; > + > + if ((tg != NULL) && tg->funcs) { > + if (tg->funcs->set_drr) > + tg->funcs->set_drr(tg, ¶ms); > if (adjust.v_total_max != 0 && adjust.v_total_min != 0) > - if > (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control) > - > pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( > - pipe_ctx[i]->stream_res.tg, > - event_triggers, num_frames); > + if (tg->funcs->set_static_screen_control) > + tg->funcs->set_static_screen_control( > + tg, event_triggers, num_frames); > } > } > }
Re: [PATCH 2/2] drm/amd/display: Avoid race between dcn35_set_drr() and dc_state_destruct()
On 2024-09-02 05:40, tjak...@math.uni-bielefeld.de wrote: > From: Tobias Jakobi > > dc_state_destruct() nulls the resource context of the DC state. The pipe > context passed to dcn35_set_drr() is a member of this resource context. > > If dc_state_destruct() is called parallel to the IRQ processing (which > calls dcn35_set_drr() at some point), we can end up using already nulled > function callback fields of struct stream_resource. > > The logic in dcn35_set_drr() already tries to avoid this, by checking tg > against NULL. But if the nulling happens exactly after the NULL check and > before the next access, then we get a race. > > Avoid this by copying tg first to a local variable, and then use this > variable for all the operations. This should work, as long as nobody > frees the resource pool where the timing generators live. > > Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3142 > Fixes: 06ad7e164256 ("drm/amd/display: Destroy DC context while keeping DML > and DML2") > Signed-off-by: Tobias Jakobi Reviewed-by: Harry Wentland Harry > --- > .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 20 +++ > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c > b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c > index dcced89c07b3..4e77728dac10 100644 > --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c > +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c > @@ -1370,7 +1370,13 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx, > params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num; > > for (i = 0; i < num_pipes; i++) { > - if ((pipe_ctx[i]->stream_res.tg != NULL) && > pipe_ctx[i]->stream_res.tg->funcs) { > + /* dc_state_destruct() might null the stream resources, so > fetch tg > + * here first to avoid a race condition. The lifetime of the > pointee > + * itself (the timing_generator object) is not a problem here. > + */ > + struct timing_generator *tg = pipe_ctx[i]->stream_res.tg; > + > + if ((tg != NULL) && tg->funcs) { > struct dc_crtc_timing *timing = > &pipe_ctx[i]->stream->timing; > struct dc *dc = pipe_ctx[i]->stream->ctx->dc; > > @@ -1383,14 +1389,12 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx, > num_frames = 2 * (frame_rate % 60); > } > } > - if (pipe_ctx[i]->stream_res.tg->funcs->set_drr) > - pipe_ctx[i]->stream_res.tg->funcs->set_drr( > - pipe_ctx[i]->stream_res.tg, ¶ms); > + if (tg->funcs->set_drr) > + tg->funcs->set_drr(tg, ¶ms); > if (adjust.v_total_max != 0 && adjust.v_total_min != 0) > - if > (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control) > - > pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( > - pipe_ctx[i]->stream_res.tg, > - event_triggers, num_frames); > + if (tg->funcs->set_static_screen_control) > + tg->funcs->set_static_screen_control( > + tg, event_triggers, num_frames); > } > } > }
Re: [PATCH v5 19/44] drm/vkms: add 3x4 matrix in color pipeline
On 2024-08-27 13:49, Louis Chauvet wrote: > Le 19/08/24 - 16:56, Harry Wentland a écrit : >> We add two 3x4 matrices into the VKMS color pipeline. The reason >> we're adding matrices is so that we can test that application >> of a matrix and its inverse yields an output equal to the input >> image. >> >> One complication with the matrix implementation has to do with >> the fact that the matrix entries are in signed-magnitude fixed >> point, whereas the drm_fixed.h implementation uses 2s-complement. >> The latter one is the one that we want for easy addition and >> subtraction, so we convert all entries to 2s-complement. > > Is there a reason to use signed-magnitude and not 2s-complement here? I > did not read the whole amd driver, but it seems that the matrix is always > converted to fixed point notation (amdgpu_dm_fixpt_from_s3132 in > amdgpu_dm_color.c). It may reduce the complexity here and in the amd > driver too. > It's so as to keep the 3x4 matrix the same as the 3x3 one (drm_color_ctm_3x4 and drm_color_ctm) and the original 3x3 one was defined to use S31.32 sign-magnitude. I'd prefer 2s-complement myself but that ship has sailed. >> >> Signed-off-by: Harry Wentland >> --- >> drivers/gpu/drm/vkms/vkms_colorop.c | 32 +++- >> drivers/gpu/drm/vkms/vkms_composer.c | 27 +++ >> 2 files changed, 58 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c >> b/drivers/gpu/drm/vkms/vkms_colorop.c >> index f61dfde47156..adcb08153a09 100644 >> --- a/drivers/gpu/drm/vkms/vkms_colorop.c >> +++ b/drivers/gpu/drm/vkms/vkms_colorop.c >> @@ -37,7 +37,37 @@ static int vkms_initialize_color_pipeline(struct >> drm_plane *plane, struct drm_pr >> >> prev_op = op; >> >> -/* 2nd op: 1d curve */ >> +/* 2nd op: 3x4 matrix */ >> +op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); >> +if (!op) { >> +DRM_ERROR("KMS: Failed to allocate colorop\n"); >> +return -ENOMEM; >> +} > > Same as before, don't we leak memory/properties here? > Thanks. Fix for this will be in v6 (for both vkms and amdgpu). >> +ret = drm_colorop_ctm_3x4_init(dev, op, plane); >> +if (ret) >> +return ret; >> + >> +drm_colorop_set_next_property(prev_op, op); >> + >> +prev_op = op; >> + >> +/* 3rd op: 3x4 matrix */ >> +op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); >> +if (!op) { >> +DRM_ERROR("KMS: Failed to allocate colorop\n"); >> +return -ENOMEM; >> +} >> + >> +ret = drm_colorop_ctm_3x4_init(dev, op, plane); >> +if (ret) >> +return ret; >> + >> +drm_colorop_set_next_property(prev_op, op); >> + >> +prev_op = op; >> + >> +/* 4th op: 1d curve */ >> op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); >> if (!op) { >> DRM_ERROR("KMS: Failed to allocate colorop\n"); >> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c >> b/drivers/gpu/drm/vkms/vkms_composer.c >> index 6e939d3a6d5c..bd1df06ced85 100644 >> --- a/drivers/gpu/drm/vkms/vkms_composer.c >> +++ b/drivers/gpu/drm/vkms/vkms_composer.c >> @@ -164,6 +164,30 @@ static void apply_lut(const struct vkms_crtc_state >> *crtc_state, struct line_buff >> } >> } >> >> +static void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct >> drm_color_ctm_3x4 *matrix) >> +{ >> +s64 rf, gf, bf; >> + >> +rf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[0]), >> drm_int2fixp(pixel->r)) + >> + drm_fixp_mul(drm_sm2fixp(matrix->matrix[1]), >> drm_int2fixp(pixel->g)) + >> + drm_fixp_mul(drm_sm2fixp(matrix->matrix[2]), >> drm_int2fixp(pixel->b)) + >> + drm_sm2fixp(matrix->matrix[3]); >> + >> +gf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[4]), >> drm_int2fixp(pixel->r)) + >> + drm_fixp_mul(drm_sm2fixp(matrix->matrix[5]), >> drm_int2fixp(pixel->g)) + >> + drm_fixp_mul(drm_sm2fixp(matrix->matrix[6]), >> drm_int2fixp(pixel->b)) + >> + drm_sm2fixp(matrix->matrix[7]); >> + >> +bf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[8]), >> drm_int2fixp(pixel->r)) + >> + drm_fixp_mul(drm_sm2fixp(matrix->matrix[9]), >> drm_int2fixp(pixel->g)) + >> + drm_fixp_mul(drm_sm2
Re: [RFC 00/33] Add Support for Plane Color Pipeline
. This color pipeline is then packaged within a blob for the user space to retrieve it. Would it be better to expose the drm_color_ops directly, instead of packing a array of drm_color_ops into a blob and then giving that to userspace. To advertise the available color pipelines, an immutable ENUM property "GET_COLOR_PIPELINE" is introduced. This enum property has blob id's as values. With each blob id representing a distinct color pipeline based on underlying HW capabilities and their respective combinations. Once the user space decides on a color pipeline, it can set the pipeline and the corresponding data for the hardware blocks within the pipeline with the BLOB property "SET_COLOR_PIPELINE". When I discussed this at the hackfest with Simon he proposed a new DRM object, (I've called it a drm_colorop) to represent a color operation. Each drm_colorop has a "NEXT" pointer to another drm_colorop, or NULL if its the last in the pipeline. You can then have a mutable enum property on the plane to discover and select a color pipeline. This seems a bit more transparent than a blob. You can see my changes (unfortunately very WIP, don't look too closely at individual patches) at https://gitlab.freedesktop.org/hwentland/linux/-/merge_requests/5/diffs libdrm changes: https://gitlab.freedesktop.org/hwentland/drm/-/merge_requests/1/diffs IGT changes: https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/merge_requests/1/diffs I'll take time to review your whole series and will see whether we can somehow keep the best parts of each. Curious to hear other opinions on the blob vs new DRM object question as well. Refer to Documentation/gpu/rfc/plane_color_pipeline.rst added in the patch IGT and test details A set of IGT tests is written to demonstrate the usage of the proposed UAPIs along with some sanity validation. Details of the IGT test can be found here: https://patchwork.freedesktop.org/series/123018/ Opens = a. To come up with a list of common HW blocks which can be defined generically by the DRM core in agreement with all the stakeholders b. To enhance/finalize the data structure to define segmented LUTs generically. It would be good to add some basic support in VKMS. My work has been based on VKMS. Once we kinda settle on an approach I'll look at exposing the AMD private properties from Melissa through the API. Out of Scope a. The coefficients for CTM and LUT value calculations are out of scope of the proposal. b. The onus of programming the HW blocks and their values is on user-space. Driver will just provide the interface for the same. c. In order to compute LUT values and coefficients, a helper library can be created in user-space. However, it is out of scope for the current proposal. Acknowledgements and credits There are multiple contributors who have helped us to reach to this proposal. Special mention to Ville Syrjala, Pekka Paalanen, Simon Ser, Harry Wentland, Melissa Wen, Jonas, Sebastian Wick, Bhanu and Shashank. Also, thanks to Carlos and the Redhat team for organizing the HDR hackfest. UAPI dependency and Usermode development The current KMS implementation requires a user space consumer for it to be accepted upstream. Work is ongoing in weston and mutter community to get color management and HDR support implemented in the respective stacks. If we can get AMD properties encoded using a Color Pipeline API we can probably use gamescope as the userspace vehicle. I'm reviewing this in sequence, so there's a chance I'm missing context. Please bear with me if some of my comments are answered later in the series. Again, thanks for sending this. Harry = We have tried to take care of all the scenarios and use-cases which possibly could exists in the current proposal. Thanks to everyone who has contributed in all color management discussions so far. Let's work together to improve the current proposal and get this thing implemented in upstream linux. All the feedback and suggestions to enhance the design are welcome. Regards, Uma Shankar Chaitanya Kumar Borah Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Chaitanya Kumar Borah (14): drm: Add color operation structure drm: Add plane get color pipeline property drm: Add helper to add color pipeline drm: Manage color blob states drm: Replace individual color blobs drm: Reset pipeline when user sends NULL blob drm: Reset plane color state on pipeline switch request drm/i915/color: Add HDR plane LUT range data to color pipeline drm/i915/color: Add SDR plane LUT range da
Re: [RFC 01/33] drm/doc/rfc: Add RFC document for proposed Plane Color Pipeline
On 2023-08-29 12:03, Uma Shankar wrote: Add the documentation for the new proposed Plane Color Pipeline. Co-developed-by: Chaitanya Kumar Borah Signed-off-by: Chaitanya Kumar Borah Signed-off-by: Uma Shankar --- .../gpu/rfc/plane_color_pipeline.rst | 394 ++ 1 file changed, 394 insertions(+) create mode 100644 Documentation/gpu/rfc/plane_color_pipeline.rst diff --git a/Documentation/gpu/rfc/plane_color_pipeline.rst b/Documentation/gpu/rfc/plane_color_pipeline.rst new file mode 100644 index ..60ce515b6ea7 --- /dev/null +++ b/Documentation/gpu/rfc/plane_color_pipeline.rst @@ -0,0 +1,394 @@ +=== + Plane Color Pipeline: A UAPI proposal +=== + +To build the proposal on, lets take the premise of a color pipeline as shown +below. + + +---+ + |RAM| + | +--++-++-+ | + | | FB 1 || FB 2 || FB N| | + | +--++-++-+ | + +---+ + | Plane Color Hardware Block | + ++ + | +---v-+ +---v---+ +---v--+ | + | | Plane A | | Plane B | | Plane N | | + | | Pre-CSC | | Pre-CSC | | Pre-CSC | | + | +---+-+ +---+---+ +---+--+ | + | | | || + | +---v-+ +---v---+ +---v--+ | + | |Plane A | | Plane B | | Plane N | | + | |CSC/CTM | | CSC/CTM | | CSC/CTM | | + | +---+-+ ++--+ ++-+ | + | | | | | + | +---v-+ +v--+ +v-+ | + | | Plane A | | Plane B | | Plane N | | + | |Post-CSC | | Post-CSC | | Post-CSC | | + | +---+-+ ++--+ ++-+ | + | | | | | + ++ ++--v--v---v---| +|| || +|| Pipe Blender|| ++++ +||| +|+---v--+ | +|| Pipe Pre-CSC| | +|| | | +|+---+--+ | +||Pipe Color | +|+---v--+ Hardware| +|| Pipe CSC/CTM| | +|| | | +|+---+--+ | +||| +|+---v--+ | +|| Pipe Post-CSC | | +|| | | +|+---+--+ | +||| ++-+ + | + v +Pipe Output + +Each plane consists of the following color blocks + * Pre-CSC : This block can used to linearize the input frame buffer data. + The linear data then can be further acted on by the following + color hardware blocks in the display hardware pipeline + + * CSC/CTM: Used to program color transformation matrix, this block is used +to perform color space conversions like BT2020 to BT709 or BT601 +etc. This block acts on the linearized data coming from the +Pre-CSC HW block. + + * Post-CSC: This HW block can be used to non-linearize frame buffer data to + match the sink. Another use case of it could be to perform Tone + mapping for HDR use-cases. + +Data from multiple planes will then be fed to pipe/crtc where it will get blended. +There is a similar set of HW blocks available at pipe/crtc level which acts on +this blended data. + +Below is a sample usecase fo video playback with sub-titles and playback +controls + +┌┐┌─┐ ┌─┐┌─┐ +│FB1 ││PRE-CSC │ │ CTM Matrix ││ POST-CSC│ +│├───►│Linearize├►│ BT709 to├───►│ SDR to HDR │ +│BT709 SDR ││ │ │ BT2020 ││ Tone Mapping├─┐ +└┘└─┘ └─┘└─┘ │ +(subtitles) │ + │ +┌┐┌─┐ ┌─┐┌─┐ │ +│FB2 ││PRE-CSC │ │ CTM Matrix ││ POST-CSC│ │ +│├───►│Linearize├►│ BT601 to├───►│ SDR to HDR ├───┐ │ +│BT601 SDR ││ │ │ BT2020 ││ Tone Mapping│ │ │ +
Re: [PATCH] drm/amd/display: remove useless check in should_enable_fbc()
On 2023-08-30 10:01, Dembskiy Igor wrote: > It does not make sense to compare a pointer to array element with NULL. > > Found by Linux Verification Center (linuxtesting.org) with SVACE. > > Fixes: 65d38262b3e8 ("drm/amd/display: fbc state could not reach while enable > fbc") > Signed-off-by: Dembskiy Igor Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 --- > 1 file changed, 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c > b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c > index 6966420dfbac..e87cf54ec658 100644 > --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c > +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c > @@ -1992,9 +1992,6 @@ static bool should_enable_fbc(struct dc *dc, > > pipe_ctx = &res_ctx->pipe_ctx[i]; > > - if (!pipe_ctx) > - continue; > - > /* fbc not applicable on underlay pipe */ > if (pipe_ctx->pipe_idx != underlay_idx) { > *pipe_idx = i;
Re: [PATCH] Revert "drm/amd/display: Remove v_startup workaround for dcn3+"
On 2023-08-29 16:10, Hamza Mahfooz wrote: > This reverts commit 3a31e8b89b7240d9a17ace8a1ed050bdcb560f9e. > This isn't a straight-up revert. Please split it into a revert (git revert), followed by a patch to limit the revert to < DCN_VERSION_3_1. Harry > We still need to call dcn20_adjust_freesync_v_startup() for older DCN3+ > ASICs otherwise it can cause DP to HDMI 2.1 PCONs to fail to light up. > So, reintroduce the reverted code and limit it to ASICs older than > DCN31. > > Cc: sta...@vger.kernel.org > Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2809 > Signed-off-by: Hamza Mahfooz > --- > .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 24 --- > 1 file changed, 4 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > index 0989a0152ae8..0841176e8d6c 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > @@ -1099,6 +1099,10 @@ void dcn20_calculate_dlg_params(struct dc *dc, > context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = > > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000; > context->res_ctx.pipe_ctx[i].pipe_dlg_param = > pipes[pipe_idx].pipe.dest; > + if (dc->ctx->dce_version < DCN_VERSION_3_1 && > + > context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) > + > dcn20_adjust_freesync_v_startup(&context->res_ctx.pipe_ctx[i].stream->timing, > + > &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); > > pipe_idx++; > } > @@ -1927,7 +1931,6 @@ static bool dcn20_validate_bandwidth_internal(struct dc > *dc, struct dc_state *co > int vlevel = 0; > int pipe_split_from[MAX_PIPES]; > int pipe_cnt = 0; > - int i = 0; > display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * > sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); > DC_LOGGER_INIT(dc->ctx->logger); > > @@ -1951,15 +1954,6 @@ static bool dcn20_validate_bandwidth_internal(struct > dc *dc, struct dc_state *co > dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, > vlevel, fast_validate); > dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); > > - for (i = 0; i < dc->res_pool->pipe_count; i++) { > - if (!context->res_ctx.pipe_ctx[i].stream) > - continue; > - if > (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) > - dcn20_adjust_freesync_v_startup( > - &context->res_ctx.pipe_ctx[i].stream->timing, > - > &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); > - } > - > BW_VAL_TRACE_END_WATERMARKS(); > > goto validate_out; > @@ -2232,7 +2226,6 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc, > int vlevel = 0; > int pipe_split_from[MAX_PIPES]; > int pipe_cnt = 0; > - int i = 0; > display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * > sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); > DC_LOGGER_INIT(dc->ctx->logger); > > @@ -2261,15 +2254,6 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc, > dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, > vlevel, fast_validate); > dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); > > - for (i = 0; i < dc->res_pool->pipe_count; i++) { > - if (!context->res_ctx.pipe_ctx[i].stream) > - continue; > - if > (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) > - dcn20_adjust_freesync_v_startup( > - &context->res_ctx.pipe_ctx[i].stream->timing, > - > &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); > - } > - > BW_VAL_TRACE_END_WATERMARKS(); > > goto validate_out;
Re: [PATCH v2 1/2] Revert "drm/amd/display: Remove v_startup workaround for dcn3+"
On 2023-08-31 15:44, Zuo, Jerry wrote: > [AMD Official Use Only - General] > > > Series is: > > Reviewed-By: Fangzhi Zuo > Reviewed-by: Harry Wentland Harry > -- > *发件人:* Mahfooz, Hamza > *发送时间:* 星期四, 八月 31, 2023 3:39:04 下午 > *收件人:* amd-...@lists.freedesktop.org > *抄送:* Zuo, Jerry ; Mahfooz, Hamza ; > sta...@vger.kernel.org ; Wentland, Harry > ; Li, Sun peng (Leo) ; Siqueira, > Rodrigo ; Deucher, Alexander > ; Koenig, Christian ; > Pan, Xinhui ; David Airlie ; Daniel > Vetter ; Lei, Jun ; Pillai, Aurabindo > ; Kazlauskas, Nicholas > ; Liu, Wenjing ; Lee, Alvin > ; Kim, Sung joon ; Miess, Daniel > ; Teeger, Gabe ; > dri-devel@lists.freedesktop.org ; > linux-ker...@vger.kernel.org > *主题:* [PATCH v2 1/2] Revert "drm/amd/display: Remove v_startup workaround for > dcn3+" > > This reverts commit 3a31e8b89b7240d9a17ace8a1ed050bdcb560f9e. > > We still need to call dcn20_adjust_freesync_v_startup() for older DCN3+ > ASICs otherwise it can cause DP to HDMI 2.1 PCONs to fail to light up. > > Cc: sta...@vger.kernel.org > Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2809 > <https://gitlab.freedesktop.org/drm/amd/-/issues/2809> > Signed-off-by: Hamza Mahfooz > --- > .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 24 --- > 1 file changed, 4 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > index 0989a0152ae8..1bfdf0271fdf 100644 > --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c > @@ -1099,6 +1099,10 @@ void dcn20_calculate_dlg_params(struct dc *dc, > context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = > > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000; > context->res_ctx.pipe_ctx[i].pipe_dlg_param = > pipes[pipe_idx].pipe.dest; > + if > (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) > + dcn20_adjust_freesync_v_startup( > + &context->res_ctx.pipe_ctx[i].stream->timing, > + > &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); > > pipe_idx++; > } > @@ -1927,7 +1931,6 @@ static bool dcn20_validate_bandwidth_internal(struct dc > *dc, struct dc_state *co > int vlevel = 0; > int pipe_split_from[MAX_PIPES]; > int pipe_cnt = 0; > - int i = 0; > display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count > * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); > DC_LOGGER_INIT(dc->ctx->logger); > > @@ -1951,15 +1954,6 @@ static bool dcn20_validate_bandwidth_internal(struct > dc *dc, struct dc_state *co > dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, > vlevel, fast_validate); > dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); > > - for (i = 0; i < dc->res_pool->pipe_count; i++) { > - if (!context->res_ctx.pipe_ctx[i].stream) > - continue; > - if > (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) > - dcn20_adjust_freesync_v_startup( > - &context->res_ctx.pipe_ctx[i].stream->timing, > - > &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); > - } > - > BW_VAL_TRACE_END_WATERMARKS(); > > goto validate_out; &
Re: [PATCH v2 19/34] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
On 2023-08-28 04:17, Pekka Paalanen wrote: > On Fri, 25 Aug 2023 13:29:44 -0100 > Melissa Wen wrote: > >> On 08/22, Pekka Paalanen wrote: >>> On Thu, 10 Aug 2023 15:02:59 -0100 >>> Melissa Wen wrote: >>> >>>> The next patch adds pre-blending degamma to AMD color mgmt pipeline, but >>>> pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC >>>> atomic degamma or implict degamma on legacy gamma. Detach degamma usage >>>> regarging CRTC color properties to manage plane and CRTC color >>>> correction combinations. >>>> >>>> Reviewed-by: Harry Wentland >>>> Signed-off-by: Melissa Wen >>>> --- >>>> .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 59 +-- >>>> 1 file changed, 41 insertions(+), 18 deletions(-) >>>> >>>> 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 68e9f2c62f2e..74eb02655d96 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 >>>> @@ -764,20 +764,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct >>>> dm_crtc_state *crtc) >>>>return 0; >>>> } >>>> >>>> -/** >>>> - * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC >>>> plane. >>>> - * @crtc: amdgpu_dm crtc state >>>> - * @dc_plane_state: target DC surface >>>> - * >>>> - * Update the underlying dc_stream_state's input transfer function (ITF) >>>> in >>>> - * preparation for hardware commit. The transfer function used depends on >>>> - * the preparation done on the stream for color management. >>>> - * >>>> - * Returns: >>>> - * 0 on success. -ENOMEM if mem allocation fails. >>>> - */ >>>> -int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, >>>> -struct dc_plane_state *dc_plane_state) >>>> +static int >>>> +map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, >>>> + struct dc_plane_state *dc_plane_state) >>>> { >>>>const struct drm_color_lut *degamma_lut; >>>>enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; >>>> @@ -800,8 +789,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct >>>> dm_crtc_state *crtc, >>>> °amma_size); >>>>ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES); >>>> >>>> - dc_plane_state->in_transfer_func->type = >>>> - TF_TYPE_DISTRIBUTED_POINTS; >>>> + dc_plane_state->in_transfer_func->type = >>>> TF_TYPE_DISTRIBUTED_POINTS; >>>> >>>>/* >>>> * This case isn't fully correct, but also fairly >>>> @@ -837,7 +825,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct >>>> dm_crtc_state *crtc, >>>> degamma_lut, degamma_size); >>>>if (r) >>>>return r; >>>> - } else if (crtc->cm_is_degamma_srgb) { >>>> + } else { >>>>/* >>>> * For legacy gamma support we need the regamma input >>>> * in linear space. Assume that the input is sRGB. >>>> @@ -847,8 +835,43 @@ int amdgpu_dm_update_plane_color_mgmt(struct >>>> dm_crtc_state *crtc, >>>> >>>>if (tf != TRANSFER_FUNCTION_SRGB && >>>>!mod_color_calculate_degamma_params(NULL, >>>> - dc_plane_state->in_transfer_func, NULL, false)) >>>> + >>>> dc_plane_state->in_transfer_func, >>>> + NULL, false)) >>>>return -ENOMEM; >>>> + } >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +/** >>>> + * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC >>>> plane. >>>> + * @crtc: amdgpu_dm crtc state >>>> + * @dc_plane_state: target DC surface >>>> + * >>>> + * Updat
Re: [PATCH v2 19/34] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
//patchwork.freedesktop.org/series/2720/ >> [2] https://codereview.chromium.org/1182063002 >> [3] https://dri.freedesktop.org/docs/drm/_images/dcn3_cm_drm_current.svg >> >>> >>> If drivers do not agree on the behaviour of a KMS property, then that >>> property is useless for generic userspace. >>> >>> >>> Thanks, >>> pq >>> >>> >>>> On Tuesday, 22 August 2023, Pekka Paalanen >>>> wrote: >>>>> On Thu, 10 Aug 2023 15:02:59 -0100 >>>>> Melissa Wen wrote: >>>>> >>>>>> The next patch adds pre-blending degamma to AMD color mgmt pipeline, but >>>>>> pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC >>>>>> atomic degamma or implict degamma on legacy gamma. Detach degamma usage >>>>>> regarging CRTC color properties to manage plane and CRTC color >>>>>> correction combinations. >>>>>> >>>>>> Reviewed-by: Harry Wentland >>>>>> Signed-off-by: Melissa Wen >>>>>> --- >>>>>> .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 59 +-- >>>>>> 1 file changed, 41 insertions(+), 18 deletions(-) >>>>>> >>>>>> 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 68e9f2c62f2e..74eb02655d96 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 >>>>>> @@ -764,20 +764,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct >>>> dm_crtc_state *crtc) >>>>>> return 0; >>>>>> } >>>>>> >>>>>> -/** >>>>>> - * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC >>>>>> >>>> plane. >>>>>> - * @crtc: amdgpu_dm crtc state >>>>>> - * @dc_plane_state: target DC surface >>>>>> - * >>>>>> - * Update the underlying dc_stream_state's input transfer function >>>> (ITF) in >>>>>> - * preparation for hardware commit. The transfer function used depends >>>>>> >>>> on >>>>>> - * the preparation done on the stream for color management. >>>>>> - * >>>>>> - * Returns: >>>>>> - * 0 on success. -ENOMEM if mem allocation fails. >>>>>> - */ >>>>>> -int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, >>>>>> - struct dc_plane_state >>>> *dc_plane_state) >>>>>> +static int >>>>>> +map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, >>>>>> + struct dc_plane_state *dc_plane_state) >>>>>> { >>>>>> const struct drm_color_lut *degamma_lut; >>>>>> enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; >>>>>> @@ -800,8 +789,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct >>>> dm_crtc_state *crtc, >>>>>>°amma_size); >>>>>> ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES); >>>>>> >>>>>> - dc_plane_state->in_transfer_func->type = >>>>>> - TF_TYPE_DISTRIBUTED_POINTS; >>>>>> + dc_plane_state->in_transfer_func->type = >>>> TF_TYPE_DISTRIBUTED_POINTS; >>>>>> >>>>>> /* >>>>>>* This case isn't fully correct, but also fairly >>>>>> @@ -837,7 +825,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct >>>> dm_crtc_state *crtc, >>>>>> degamma_lut, degamma_size); >>>>>> if (r) >>>>>> return r; >>>>>> - } else if (crtc->cm_is_degamma_srgb) { >>>>>> + } else { >>>>>> /* >>>>>>* For legacy gamma support we need the regamma input >>>>>>* in linear space. Assume that the input
Re: [PATCH v2 29/34] drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
On 2023-08-10 12:03, Melissa Wen wrote: > From: Joshua Ashton > > Need to funnel the color caps through to these functions so it can check > that the hardware is capable. > > v2: > - remove redundant color caps assignment on plane degamma map (Harry) > - pass color caps to degamma params > > Signed-off-by: Joshua Ashton > Signed-off-by: Melissa Wen > --- > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 35 --- > 1 file changed, 22 insertions(+), 13 deletions(-) > > 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 f638e5b3a70b..4356846a2bce 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 > @@ -538,6 +538,7 @@ static int amdgpu_dm_set_atomic_regamma(struct > dc_stream_state *stream, > /** > * __set_input_tf - calculates the input transfer function based on expected > * input space. > + * @caps: dc color capabilities > * @func: transfer function > * @lut: lookup table that defines the color space > * @lut_size: size of respective lut. > @@ -545,7 +546,7 @@ static int amdgpu_dm_set_atomic_regamma(struct > dc_stream_state *stream, > * Returns: > * 0 in case of success. -ENOMEM if fails. > */ > -static int __set_input_tf(struct dc_transfer_func *func, > +static int __set_input_tf(struct dc_color_caps *caps, struct > dc_transfer_func *func, > const struct drm_color_lut *lut, uint32_t lut_size) > { > struct dc_gamma *gamma = NULL; > @@ -562,7 +563,7 @@ static int __set_input_tf(struct dc_transfer_func *func, > __drm_lut_to_dc_gamma(lut, gamma, false); > } > > - res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != > NULL); > + res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != > NULL); > > if (gamma) > dc_gamma_release(&gamma); > @@ -725,7 +726,7 @@ static int amdgpu_dm_atomic_blend_lut(const struct > drm_color_lut *blend_lut, > func_blend->tf = tf; > func_blend->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE; > > - ret = __set_input_tf(func_blend, blend_lut, blend_size); > + ret = __set_input_tf(NULL, func_blend, blend_lut, blend_size); > } else { > func_blend->type = TF_TYPE_BYPASS; > func_blend->tf = TRANSFER_FUNCTION_LINEAR; > @@ -950,7 +951,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state > *crtc) > > static int > map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, > - struct dc_plane_state *dc_plane_state) > + struct dc_plane_state *dc_plane_state, > + struct dc_color_caps *caps) > { > const struct drm_color_lut *degamma_lut; > enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; > @@ -1005,7 +1007,7 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, > dc_plane_state->in_transfer_func->tf = > TRANSFER_FUNCTION_LINEAR; > > - r = __set_input_tf(dc_plane_state->in_transfer_func, > + r = __set_input_tf(caps, dc_plane_state->in_transfer_func, > degamma_lut, degamma_size); > if (r) > return r; > @@ -1018,7 +1020,7 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, > dc_plane_state->in_transfer_func->tf = tf; > > if (tf != TRANSFER_FUNCTION_SRGB && > - !mod_color_calculate_degamma_params(NULL, > + !mod_color_calculate_degamma_params(caps, > > dc_plane_state->in_transfer_func, > NULL, false)) > return -ENOMEM; > @@ -1029,7 +1031,8 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, > > static int > __set_dm_plane_degamma(struct drm_plane_state *plane_state, > -struct dc_plane_state *dc_plane_state) > +struct dc_plane_state *dc_plane_state, > +struct dc_color_caps *color_caps) > { > struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); > const struct drm_color_lut *degamma_lut; > @@ -1060,7 +1063,7 @@ __set_dm_plane_degamma(struct drm_plane_state > *plane_state, > dc_plane_state->in_transfer_func->type = > TF_TYPE_DISTRIBUTED_POINTS; > > - ret = __set_input_tf(dc_plane_state->in_transfer_func, > + ret = __set_input_tf(color_caps, > dc_plane_state->in_transfer_func, >degamma_lut, degamma_size); > if (ret) > return ret; > @@ -1068,7 +1071,7 @@ __set_dm_plane_degamma(struct drm_plane_state
Re: [PATCH v2 31/34] drm/amd/display: set stream gamut remap matrix to MPC for DCN301
On 2023-08-28 04:20, Pekka Paalanen wrote: > On Fri, 25 Aug 2023 13:37:08 -0100 > Melissa Wen wrote: > >> On 08/22, Pekka Paalanen wrote: >>> On Thu, 10 Aug 2023 15:03:11 -0100 >>> Melissa Wen wrote: >>> dc->caps.color.mpc.gamut_remap says there is a post-blending color block for gamut remap matrix for DCN3 HW family and newer versions. However, those drivers still follow DCN10 programming that remap stream gamut_remap_matrix to DPP (pre-blending). >>> >>> That's ok only as long as CRTC degamma is pass-through. Blending itself >>> is a linear operation, so it doesn't matter if a matrix is applied to >>> the blending result or to all blending inputs. But you cannot move a >>> matrix operation to the other side of a non-linear operation, and you >>> cannot move a non-linear operation across blending. >> >> Oh, I'm not moving it, what I'm doing here is the opposite and fixing >> it. This patch puts each pre- and post-blending CTM in their right >> place, since we have the HW caps for it on DCN3+... Or are you just >> pointing out the implementation mistake on old driver versions? > > It's just the old mistake. > > I hope no-one complains, forcing you to revert this fix as a regression. > I'm worried this will break other OSes since its in DC and shared. I'll check with Kruno when he's back from vacation. But most likely this will be problematic. Worst case we can add a new "program_gamut_remap_actually_post_blending" (with a better name) function to HWSS, expose it in DC, and make sure amdgpu_dm never calls the old "program_gamut_remap". I hope nobody relies on the current (IMO broken) behavior on Linux. Harry > > Thanks, > pq > > To enable pre-blending and post-blending gamut_remap matrix supports at the same time, set stream gamut_remap to MPC and plane gamut_remap to DPP for DCN301 that support both. It was tested using IGT KMS color tests for DRM CRTC CTM property and it preserves test results. Signed-off-by: Melissa Wen --- .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 37 +++ .../drm/amd/display/dc/dcn30/dcn30_hwseq.h| 3 ++ .../drm/amd/display/dc/dcn301/dcn301_init.c | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-)
Re: [PATCH v2 32/34] drm/amd/display: add plane CTM driver-specific property
On 2023-08-10 12:03, Melissa Wen wrote: > Plane CTM for pre-blending color space conversion. Only enable > driver-specific plane CTM property on drivers that support both pre- and > post-blending gamut remap matrix, i.e., DCN3+ family. Otherwise it > conflits with DRM CRTC CTM property. > > Signed-off-by: Melissa Wen > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 ++ > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 +++ > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 7 +++ > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 +++ > 4 files changed, 36 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > index abb871a912d7..84bf501b02f4 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > @@ -363,6 +363,8 @@ struct amdgpu_mode_info { >* @plane_hdr_mult_property: >*/ > struct drm_property *plane_hdr_mult_property; > + > + struct drm_property *plane_ctm_property; > /** >* @shaper_lut_property: Plane property to set pre-blending shaper LUT >* that converts color content before 3D LUT. > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > index 095f39f04210..6252ee912a63 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > @@ -769,6 +769,13 @@ struct dm_plane_state { >* S31.32 sign-magnitude. >*/ > __u64 hdr_mult; > + /** > + * @ctm: > + * > + * Color transformation matrix. See drm_crtc_enable_color_mgmt(). The > + * blob (if not NULL) is a &struct drm_color_ctm. > + */ > + struct drm_property_blob *ctm; > /** >* @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an >* array of &struct drm_color_lut. > 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 4356846a2bce..86a918ab82be 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 > @@ -218,6 +218,13 @@ amdgpu_dm_create_color_properties(struct amdgpu_device > *adev) > return -ENOMEM; > adev->mode_info.plane_hdr_mult_property = prop; > > + prop = drm_property_create(adev_to_drm(adev), > +DRM_MODE_PROP_BLOB, > +"AMD_PLANE_CTM", 0); We'll want to wrap the property creation/attachment with #ifdef AMD_PRIVATE_COLOR here as well. Harry > + if (!prop) > + return -ENOMEM; > + adev->mode_info.plane_ctm_property = prop; > + > prop = drm_property_create(adev_to_drm(adev), > DRM_MODE_PROP_BLOB, > "AMD_PLANE_SHAPER_LUT", 0); > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > index 3fd57de7c5be..0b1081c690cb 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > @@ -1355,6 +1355,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) > > if (dm_plane_state->degamma_lut) > drm_property_blob_get(dm_plane_state->degamma_lut); > + if (dm_plane_state->ctm) > + drm_property_blob_get(dm_plane_state->ctm); > if (dm_plane_state->shaper_lut) > drm_property_blob_get(dm_plane_state->shaper_lut); > if (dm_plane_state->lut3d) > @@ -1436,6 +1438,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane > *plane, > > if (dm_plane_state->degamma_lut) > drm_property_blob_put(dm_plane_state->degamma_lut); > + if (dm_plane_state->ctm) > + drm_property_blob_put(dm_plane_state->ctm); > if (dm_plane_state->lut3d) > drm_property_blob_put(dm_plane_state->lut3d); > if (dm_plane_state->shaper_lut) > @@ -1473,6 +1477,11 @@ dm_atomic_plane_attach_color_mgmt_properties(struct > amdgpu_display_manager *dm, > dm->adev->mode_info.plane_hdr_mult_property, > AMDGPU_HDR_MULT_DEFAULT); > > + /* Only enable plane CTM if both DPP and MPC gamut remap is available. > */ > + if (dm->dc->caps.color.mpc.gamut_remap) > + drm_object_attach_property(&plane->base, > + > dm->adev->mode_info.plane_ctm_property, 0); > + > if (dpp_color_caps.hw_3d_lut) { > drm_object_attach_property(&plane->base, > mode_info.plane_shaper_lut_property, > 0); > @@ -1530,6 +1539,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane, > dm_plane_st
Re: [PATCH v2 33/34] drm/amd/display: add plane CTM support
On 2023-08-10 12:03, Melissa Wen wrote: > Map the plane CTM driver-specific property to DC plane, instead of DC > stream. The remaining steps to program DPP block are already implemented > on DC shared-code. > > Signed-off-by: Melissa Wen > --- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 25 +++ > 2 files changed, 26 insertions(+) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index dfe61c5ed49e..f239410234b3 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -9578,6 +9578,7 @@ static bool should_reset_plane(struct drm_atomic_state > *state, > if (dm_old_other_state->degamma_tf != > dm_new_other_state->degamma_tf || > dm_old_other_state->degamma_lut != > dm_new_other_state->degamma_lut || > dm_old_other_state->hdr_mult != > dm_new_other_state->hdr_mult || > + dm_old_other_state->ctm != dm_new_other_state->ctm || > dm_old_other_state->shaper_lut != > dm_new_other_state->shaper_lut || > dm_old_other_state->shaper_tf != > dm_new_other_state->shaper_tf || > dm_old_other_state->lut3d != dm_new_other_state->lut3d || > 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 86a918ab82be..7ff329101fd4 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 > @@ -1158,6 +1158,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct > dm_crtc_state *crtc, > struct dc_plane_state *dc_plane_state) > { > struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev); > + struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); > + struct drm_color_ctm *ctm = NULL; > struct dc_color_caps *color_caps = NULL; > bool has_crtc_cm_degamma; > int ret; > @@ -1209,6 +1211,29 @@ int amdgpu_dm_update_plane_color_mgmt(struct > dm_crtc_state *crtc, > return ret; > } > > + /* Setup CRTC CTM. */ > + if (dm_plane_state->ctm) { > + ctm = (struct drm_color_ctm *)dm_plane_state->ctm->data; > + > + /* > + * So far, if we have both plane and CRTC CTM, plane CTM takes > + * the priority and we discard data for CRTC CTM, as > + * implemented in dcn10_program_gamut_remap(). However, we Isn't it the opposite? If stream (crtc) has a CTM we program that, only if stream doesn't have a CTM we program the plane one? Harry > + * have MPC gamut_remap_matrix from DCN3 family, therefore we > + * can remap MPC programing of the matrix to MPC block and > + * provide support for both DPP and MPC matrix at the same > + * time. > + */ > + __drm_ctm_to_dc_matrix(ctm, > dc_plane_state->gamut_remap_matrix.matrix); > + > + dc_plane_state->gamut_remap_matrix.enable_remap = true; > + dc_plane_state->input_csc_color_matrix.enable_adjustment = > false; > + } else { > + /* Bypass CTM. */ > + dc_plane_state->gamut_remap_matrix.enable_remap = false; > + dc_plane_state->input_csc_color_matrix.enable_adjustment = > false; > + } > + > return amdgpu_dm_plane_set_color_properties(plane_state, > dc_plane_state, color_caps); > }
Re: [PATCH v2 34/34] drm/amd/display: Use 3x4 CTM for plane CTM
On 2023-08-10 12:03, Melissa Wen wrote: > From: Joshua Ashton > > Signed-off-by: Joshua Ashton > Signed-off-by: Melissa Wen > --- > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 32 +-- > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 2 +- > include/uapi/drm/drm_mode.h | 8 + > 3 files changed, 38 insertions(+), 4 deletions(-) > > 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 7ff329101fd4..0a51af44efd5 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 > @@ -412,6 +412,32 @@ static void __drm_ctm_to_dc_matrix(const struct > drm_color_ctm *ctm, > } > } > > +/** > + * __drm_ctm2_to_dc_matrix - converts a DRM CTM2 to a DC CSC float matrix > + * @ctm: DRM color transformation matrix > + * @matrix: DC CSC float matrix > + * > + * The matrix needs to be a 3x4 (12 entry) matrix. > + */ > +static void __drm_ctm2_to_dc_matrix(const struct drm_color_ctm2 *ctm, > +struct fixed31_32 *matrix) > +{ > + int i; > + > + /* > + * DRM gives a 3x3 matrix, but DC wants 3x4. Assuming we're operating > + * with homogeneous coordinates, augment the matrix with 0's. > + * Left-over copy-paste comment. This version takes 3x4 as input param. > + * The format provided is S31.32, using signed-magnitude representation. > + * Our fixed31_32 is also S31.32, but is using 2's complement. We have > + * to convert from signed-magnitude to 2's complement. > + */ > + for (i = 0; i < 12; i++) { > + /* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */ > + matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i]); > + } > +} > + > /** > * __set_legacy_tf - Calculates the legacy transfer function > * @func: transfer function > @@ -1159,7 +1185,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct > dm_crtc_state *crtc, > { > struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev); > struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); > - struct drm_color_ctm *ctm = NULL; > + struct drm_color_ctm2 *ctm = NULL; > struct dc_color_caps *color_caps = NULL; > bool has_crtc_cm_degamma; > int ret; > @@ -1213,7 +1239,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct > dm_crtc_state *crtc, > > /* Setup CRTC CTM. */ > if (dm_plane_state->ctm) { > - ctm = (struct drm_color_ctm *)dm_plane_state->ctm->data; > + ctm = (struct drm_color_ctm2 *)dm_plane_state->ctm->data; > > /* >* So far, if we have both plane and CRTC CTM, plane CTM takes > @@ -1224,7 +1250,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct > dm_crtc_state *crtc, >* provide support for both DPP and MPC matrix at the same >* time. >*/ > - __drm_ctm_to_dc_matrix(ctm, > dc_plane_state->gamut_remap_matrix.matrix); > + __drm_ctm2_to_dc_matrix(ctm, > dc_plane_state->gamut_remap_matrix.matrix); > > dc_plane_state->gamut_remap_matrix.enable_remap = true; > dc_plane_state->input_csc_color_matrix.enable_adjustment = > false; > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > index 0b1081c690cb..27962a3d30f5 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > @@ -1543,7 +1543,7 @@ dm_atomic_plane_set_property(struct drm_plane *plane, > ret = drm_property_replace_blob_from_id(plane->dev, > &dm_plane_state->ctm, > val, > - sizeof(struct > drm_color_ctm), -1, > + sizeof(struct > drm_color_ctm2), -1, We need to update the comment for dm_plane_state.ctm in amdgpu_dm.h to specify the property is of type drm_color_ctm2 (or drm_color_ctm_3x4). > &replaced); > dm_plane_state->base.color_mgmt_changed |= replaced; > return ret; > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > index 46becedf5b2f..402288133e4c 100644 > --- a/include/uapi/drm/drm_mode.h > +++ b/include/uapi/drm/drm_mode.h > @@ -838,6 +838,14 @@ struct drm_color_ctm { > __u64 matrix[9]; > }; > > +struct drm_color_ctm2 { Calling this drm_color_ctm_3x4 might be good to make it clear this is for a 3x4 matrix. Harry > + /* > + * Conversion matrix in S31.32 sign-magnitude > + * (not two's complement!) format. > + */ > + __u64 matrix[12]; > +}; > + > struct drm
Re: [PATCH v2 01/34] drm/amd/display: fix segment distribution for linear LUTs
On 2023-08-10 12:02, Melissa Wen wrote: > From: Harry Wentland > > The region and segment calculation was incapable of dealing > with regions of more than 16 segments. We first fix this. > > Now that we can support regions up to 256 elements we can > define a better segment distribution for near-linear LUTs > for our maximum of 256 HW-supported points. > > With these changes an "identity" LUT looks visually > indistinguishable from bypass and allows us to use > our 3DLUT. > Have you had a chance to test whether this patch makes a difference? I haven't had the time yet. Harry > Signed-off-by: Harry Wentland > Signed-off-by: Melissa Wen > --- > .../amd/display/dc/dcn10/dcn10_cm_common.c| 93 +++ > 1 file changed, 75 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c > b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c > index 3538973bd0c6..04b2e04b68f3 100644 > --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c > +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c > @@ -349,20 +349,37 @@ bool cm_helper_translate_curve_to_hw_format(struct > dc_context *ctx, >* segment is from 2^-10 to 2^1 >* There are less than 256 points, for optimization >*/ > - seg_distr[0] = 3; > - seg_distr[1] = 4; > - seg_distr[2] = 4; > - seg_distr[3] = 4; > - seg_distr[4] = 4; > - seg_distr[5] = 4; > - seg_distr[6] = 4; > - seg_distr[7] = 4; > - seg_distr[8] = 4; > - seg_distr[9] = 4; > - seg_distr[10] = 1; > + if (output_tf->tf == TRANSFER_FUNCTION_LINEAR) { > + seg_distr[0] = 0; /* 2 */ > + seg_distr[1] = 1; /* 4 */ > + seg_distr[2] = 2; /* 4 */ > + seg_distr[3] = 3; /* 8 */ > + seg_distr[4] = 4; /* 16 */ > + seg_distr[5] = 5; /* 32 */ > + seg_distr[6] = 6; /* 64 */ > + seg_distr[7] = 7; /* 128 */ > + > + region_start = -8; > + region_end = 1; > + } else { > + seg_distr[0] = 3; /* 8 */ > + seg_distr[1] = 4; /* 16 */ > + seg_distr[2] = 4; > + seg_distr[3] = 4; > + seg_distr[4] = 4; > + seg_distr[5] = 4; > + seg_distr[6] = 4; > + seg_distr[7] = 4; > + seg_distr[8] = 4; > + seg_distr[9] = 4; > + seg_distr[10] = 1; /* 2 */ > + /* total = 8*16 + 8 + 64 + 2 = */ > + > + region_start = -10; > + region_end = 1; > + } > + > > - region_start = -10; > - region_end = 1; > } > > for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) > @@ -375,16 +392,56 @@ bool cm_helper_translate_curve_to_hw_format(struct > dc_context *ctx, > > j = 0; > for (k = 0; k < (region_end - region_start); k++) { > - increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); > + /* > + * We're using an ugly-ish hack here. Our HW allows for > + * 256 segments per region but SW_SEGMENTS is 16. > + * SW_SEGMENTS has some undocumented relationship to > + * the number of points in the tf_pts struct, which > + * is 512, unlike what's suggested TRANSFER_FUNC_POINTS. > + * > + * In order to work past this dilemma we'll scale our > + * increment by (1 << 4) and then do the inverse (1 >> 4) > + * when accessing the elements in tf_pts. > + * > + * TODO: find a better way using SW_SEGMENTS and > + * TRANSFER_FUNC_POINTS definitions > + */ > + increment = (NUMBER_SW_SEGMENTS << 4) / (1 << seg_distr[k]); > start_index = (region_start + k + MAX_LOW_POINT) * > NUMBER_SW_SEGMENTS; > - for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; > + for (i = (start_index << 4); i < (start_index << 4) + > (NUMBER_SW_SEGMENTS << 4); > i += increment) { > + struct fixed31_32 in_plus_one, in; > +
Re: [PATCH v2 10/34] drm/amd/display: add plane 3D LUT driver-specific properties
On 2023-08-10 12:02, Melissa Wen wrote: > Add 3D LUT property for plane gamma correction using a 3D lookup table. > Since a 3D LUT has a limited number of entries in each dimension we want > to use them in an optimal fashion. This means using the 3D LUT in a > colorspace that is optimized for human vision, such as sRGB, PQ, or > another non-linear space. Therefore, userpace may need one 1D LUT > (shaper) before it to delinearize content and another 1D LUT after 3D > LUT (blend) to linearize content again for blending. The next patches > add these 1D LUTs to the plane color mgmt pipeline. > > Signed-off-by: Melissa Wen > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 10 > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 9 > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 14 +++ > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 23 +++ > 4 files changed, 56 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > index 66bae0eed80c..730a88236501 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > @@ -363,6 +363,16 @@ struct amdgpu_mode_info { >* @plane_hdr_mult_property: >*/ > struct drm_property *plane_hdr_mult_property; > + /** > + * @plane_lut3d_property: Plane property for gamma correction using a > + * 3D LUT (pre-blending). > + */ I think we'll want to describe how the 3DLUT entries are laid out. Something that describes how userspace should fill it, like gamescope does for example: https://github.com/ValveSoftware/gamescope/blob/7108880ed80b68c21750369e2ac9b7315fecf264/src/color_helpers.cpp#L302 Something like: a three-dimensional array, with each dimension having a size of the cubed root of lut3d_size, blue being the outermost dimension, red the innermost. > + struct drm_property *plane_lut3d_property; > + /** > + * @plane_degamma_lut_size_property: Plane property to define the max > + * size of 3D LUT as supported by the driver (read-only). > + */ We should probably document that the size of the 3DLUT should be the size of one dimension cubed, or that the cubed root of the LUT size gives the size per dimension. Harry > + struct drm_property *plane_lut3d_size_property; > }; > > #define AMDGPU_MAX_BL_LEVEL 0xFF > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > index 44f17ac11a5f..deea90212e31 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > @@ -769,6 +769,11 @@ struct dm_plane_state { >* S31.32 sign-magnitude. >*/ > __u64 hdr_mult; > + /** > + * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of > + * &struct drm_color_lut. > + */ > + struct drm_property_blob *lut3d; > }; > > struct dm_crtc_state { > @@ -854,6 +859,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector > *connector, > > void amdgpu_dm_trigger_timing_sync(struct drm_device *dev); > > +/* 3D LUT max size is 17x17x17 */ > +#define MAX_COLOR_3DLUT_ENTRIES 4913 > +#define MAX_COLOR_3DLUT_BITDEPTH 12 > +/* 1D LUT size */ > #define MAX_COLOR_LUT_ENTRIES 4096 > /* Legacy gamm LUT users such as X doesn't like large LUT sizes */ > #define MAX_COLOR_LEGACY_LUT_ENTRIES 256 > 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 b891aaf5f7c1..7e6d4df99a0c 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 > @@ -209,6 +209,20 @@ amdgpu_dm_create_color_properties(struct amdgpu_device > *adev) > return -ENOMEM; > adev->mode_info.plane_hdr_mult_property = prop; > > + prop = drm_property_create(adev_to_drm(adev), > +DRM_MODE_PROP_BLOB, > +"AMD_PLANE_LUT3D", 0); > + if (!prop) > + return -ENOMEM; > + adev->mode_info.plane_lut3d_property = prop; > + > + prop = drm_property_create_range(adev_to_drm(adev), > + DRM_MODE_PROP_IMMUTABLE, > + "AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX); > + if (!prop) > + return -ENOMEM; > + adev->mode_info.plane_lut3d_size_property = prop; > + > return 0; > } > #endif > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > index ab7f0332c431..882391f7add6 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > @@ -1353,6 +1353,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) > > if (dm_plane_state->degam
Re: [PATCH v2 11/34] drm/amd/display: add plane shaper LUT and TF driver-specific properties
On 2023-08-10 12:02, Melissa Wen wrote: > On AMD HW, 3D LUT always assumes a preceding shaper 1D LUT used for > delinearizing and/or normalizing the color space before applying a 3D > LUT. Add pre-defined transfer function to enable delinearizing content > with or without shaper LUT, where AMD color module calculates the > resulted shaper curve. We apply an inverse EOTF to go from linear values > to encoded values. If we are already in a non-linear space and/or don't > need to normalize values, we can bypass shaper LUT with a linear > transfer function that is also the default TF value. > I think the color module will combine the TF and the custom 1D LUT into the LUT that's actually programmed. We should spell out this behavior in the comments below and in the patch description as it's important for a userspace application to know. The same applies to all other TF+LUT blocks. Harry > v2: > - squash commits for shaper LUT and shaper TF > - define inverse EOTF as supported shaper TFs > > Signed-off-by: Melissa Wen > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 16 ++ > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++ > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 29 + > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 32 +++ > 4 files changed, 88 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > index 730a88236501..4fb164204ee6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > @@ -363,6 +363,22 @@ struct amdgpu_mode_info { >* @plane_hdr_mult_property: >*/ > struct drm_property *plane_hdr_mult_property; > + /** > + * @shaper_lut_property: Plane property to set pre-blending shaper LUT > + * that converts color content before 3D LUT. > + */ > + struct drm_property *plane_shaper_lut_property; > + /** > + * @shaper_lut_size_property: Plane property for the size of > + * pre-blending shaper LUT as supported by the driver (read-only). > + */ > + struct drm_property *plane_shaper_lut_size_property; > + /** > + * @plane_shaper_tf_property: Plane property to set a predefined > + * transfer function for pre-blending shaper (before applying 3D LUT) > + * with or without LUT. > + */ > + struct drm_property *plane_shaper_tf_property; > /** >* @plane_lut3d_property: Plane property for gamma correction using a >* 3D LUT (pre-blending). > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > index deea90212e31..6b6c2980f0af 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h > @@ -769,6 +769,17 @@ struct dm_plane_state { >* S31.32 sign-magnitude. >*/ > __u64 hdr_mult; > + /** > + * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an > + * array of &struct drm_color_lut. > + */ > + struct drm_property_blob *shaper_lut; > + /** > + * @shaper_tf: > + * > + * Predefined transfer function to delinearize color space. > + */ > + enum amdgpu_transfer_function shaper_tf; > /** >* @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of >* &struct drm_color_lut. > 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 7e6d4df99a0c..fbcee717bf0a 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 > @@ -151,6 +151,14 @@ static const u32 amdgpu_eotf = > BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF) | > BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF); > > +static const u32 amdgpu_inv_eotf = > + BIT(AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF) | > + BIT(AMDGPU_TRANSFER_FUNCTION_BT709_INV_EOTF) | > + BIT(AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF) | > + BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF) | > + BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF) | > + BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF); > + > static struct drm_property * > amdgpu_create_tf_property(struct drm_device *dev, > const char *name, > @@ -209,6 +217,27 @@ amdgpu_dm_create_color_properties(struct amdgpu_device > *adev) > return -ENOMEM; > adev->mode_info.plane_hdr_mult_property = prop; > > + prop = drm_property_create(adev_to_drm(adev), > +DRM_MODE_PROP_BLOB, > +"AMD_PLANE_SHAPER_LUT", 0); > + if (!prop) > + return -ENOMEM; > + adev->mode_info.plane_shaper_lut_property = prop; > + > + prop = drm_property_create_range(adev_to_drm(adev), > + DRM
Re: [PATCH v2 00/34] drm/amd/display: add AMD driver-specific properties for color mgmt
On 2023-08-10 12:02, Melissa Wen wrote: > Hi all, > > Here is the next version of our work to enable AMD driver-specific color > management properties [1][2]. This series is a collection of > contributions from Joshua, Harry, and me to enhance the AMD KMS color > pipeline for Steam Deck/SteamOS by exposing additional pre-blending and > post-blending color capabilities from those available in the current DRM > KMS API[3]. > > The userspace case here is Gamescope which is the compositor for > SteamOS. Gamescope is already using these features to implement its > color management pipeline [4]. > > In this version, I try to address all concerns shared in the previous > one, i.e.: > - Replace DRM_ by AMDGPU_ prefix for transfer function enumeration; > - Explicitly define EOTFs and inverse EOTFs and set props accordingly; > - Document pre-defined transfer functions; > - Remove misleading comments; > - Remove post-blending/MPC shaper and 3D LUT support; > - Move driver-specific property operations from amdgpu_display.c to > amdgpu_dm_color.c; > - Reset planes if any color props change; > - Nits/small fixes; > > Bearing in mind the complexity of color concepts, I believe there is a > high chance of some misunderstanding from my side when defining EOTFs > and documenting pre-defined TFs. So, reviews are very important and > welcome (thanks in advance). FWIW, I added Harry as a co-developer of > this TF documentation since I based on his description of EOTF/inv_EOTF > and previous documentation work [5]. Let me know if there is a better > way for credits. > > Two DC patches were already applied and, therefore, removed from the > series. I added r-b according to previous feedback. We also add plane > CTM to driver-specific properties. As a result, this is the updated list > of all driver-specific color properties exposed by this series: > > - plane degamma LUT and pre-defined TF; > - plane HDR multiplier; > - plane CTM 3x4; > - plane shaper LUT and pre-defined TF; > - plane 3D LUT; > - plane blend LUT and pre-defined TF; > - CRTC gamma pre-defined TF; > > Remember you can find the AMD HW color capabilities documented here: > https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties > > Worth mentioning that the pre-blending degamma block can use ROM curves > for some pre-defined TFs, but the other blocks use the AMD color module > to calculate this curve considering pre-defined coefficients. > > We need changes on DC gamut remap matrix to support the plane and CRTC > CTM on drivers that support both. I've sent a previous patch to apply > these changes to all DCN3+ families [6]. Here I use the same changes but > limited to DCN301. Just let me know if you prefer the previous/expanded > version. > > Finally, this is the Linux/AMD color management API before and after > blending with the driver-specific properties: > > +--+ > | PLANE | > | | > | ++ | > | | AMD Degamma| | > | || | > | | EOTF | 1D LUT | | > | ++---+ | > | | | > | +v---+ | > | |AMD HDR | | > | |Multiply| | > | ++---+ | > | | | > | +v---+ | > | | AMD CTM (3x4) | | > | ++---+ | > | | | > | +v---+ | > | | AMD Shaper | | > | || | > | | inv_EOTF | | | > | | Custom 1D LUT | | > | ++---+ | > | | | > | +v---+ | > | | AMD 3D LUT | | > | | 17^3/12-bit | | > | ++---+ | > | | | > | +v---+ | > | | AMD Blend | | > | || | > | | EOTF | 1D LUT | | > | ++---+ | > | | | > ++--v-++ > || Blending || > ++--+-++ > |CRTC | | > | | | > | +---v---+ | > | | DRM Degamma | | > | | | | > | | Custom 1D LUT | | > | +---+---+ | > | | | > | +---v---+ | > | | DRM CTM (3x3) | | > | +---+---+ | > | | | > | +---v---+ | > | | DRM Gamma | | > | | | | > | | Custom 1D LUT | | > | +---+ | > | | *AMD Gamma| | > | | inv_EOTF| | > | +---+ | > | | > +--+ > > Let me know your thoughts. > Thanks aga
Re: [PATCH v2 07/34] drm/amd/display: explicitly define EOTF and inverse EOTF
On 2023-08-25 10:18, Melissa Wen wrote: > On 08/22, Pekka Paalanen wrote: >> On Thu, 10 Aug 2023 15:02:47 -0100 >> Melissa Wen wrote: >> >>> Instead of relying on color block names to get the transfer function >>> intention regarding encoding pixel's luminance, define supported >>> Electro-Optical Transfer Functions (EOTFs) and inverse EOTFs, that >>> includes pure gamma or standardized transfer functions. >>> >>> Suggested-by: Harry Wentland >>> Signed-off-by: Melissa Wen >>> --- >>> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 19 +++-- >>> .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 69 +++ >>> 2 files changed, 67 insertions(+), 21 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>> index c749c9cb3d94..f6251ed89684 100644 >>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>> @@ -718,14 +718,21 @@ extern const struct amdgpu_ip_block_version >>> dm_ip_block; >>> >>> enum amdgpu_transfer_function { >>> AMDGPU_TRANSFER_FUNCTION_DEFAULT, >>> - AMDGPU_TRANSFER_FUNCTION_SRGB, >>> - AMDGPU_TRANSFER_FUNCTION_BT709, >>> - AMDGPU_TRANSFER_FUNCTION_PQ, >>> + AMDGPU_TRANSFER_FUNCTION_SRGB_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_BT709_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_PQ_EOTF, >>> AMDGPU_TRANSFER_FUNCTION_LINEAR, >>> AMDGPU_TRANSFER_FUNCTION_UNITY, >>> - AMDGPU_TRANSFER_FUNCTION_GAMMA22, >>> - AMDGPU_TRANSFER_FUNCTION_GAMMA24, >>> - AMDGPU_TRANSFER_FUNCTION_GAMMA26, >>> + AMDGPU_TRANSFER_FUNCTION_GAMMA22_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_BT709_INV_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF, >>> + AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF, >>> +AMDGPU_TRANSFER_FUNCTION_COUNT >>> }; >>> >>> struct dm_plane_state { >>> 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 56ce008b9095..cc2187c0879a 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 >>> @@ -85,18 +85,59 @@ void amdgpu_dm_init_color_mod(void) >>> } >>> >>> #ifdef AMD_PRIVATE_COLOR >>> -static const struct drm_prop_enum_list >>> amdgpu_transfer_function_enum_list[] = { >>> - { AMDGPU_TRANSFER_FUNCTION_DEFAULT, "Default" }, >>> - { AMDGPU_TRANSFER_FUNCTION_SRGB, "sRGB" }, >>> - { AMDGPU_TRANSFER_FUNCTION_BT709, "BT.709" }, >>> - { AMDGPU_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" }, >>> - { AMDGPU_TRANSFER_FUNCTION_LINEAR, "Linear" }, >>> - { AMDGPU_TRANSFER_FUNCTION_UNITY, "Unity" }, >>> - { AMDGPU_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" }, >>> - { AMDGPU_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" }, >>> - { AMDGPU_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" }, >>> +static const char * const >>> +amdgpu_transfer_function_names[] = { >>> + [AMDGPU_TRANSFER_FUNCTION_DEFAULT] = "Default", >>> + [AMDGPU_TRANSFER_FUNCTION_LINEAR] = "Linear", >> >> Hi, >> >> if the below is identity, then what is linear? Is there a coefficient >> (multiplier) somewhere? Offset? >> >>> + [AMDGPU_TRANSFER_FUNCTION_UNITY]= "Unity", >> >> Should "Unity" be called "Identity"? > > AFAIU, AMD treats Linear and Unity as the same: Identity. So, IIUC, > indeed merging both as identity sounds the best approach. Agreed. >> >> Doesn't unity mean that the output is always 1.0 regardless of input? >> >>> + [AMDGPU_TRANSFER_FUNCTION_SRGB_EOTF]= "sRGB EOTF", >>> + [AMDGPU_TRANSFER_FUNCTION_BT709_EOTF] = "BT.709 EOTF", >> >> BT.709 says about "Overall opto-electronic transfer characteristics at >> sour
Re: [PATCH v2 07/34] drm/amd/display: explicitly define EOTF and inverse EOTF
On 2023-09-07 03:49, Pekka Paalanen wrote: > On Wed, 6 Sep 2023 16:15:10 -0400 > Harry Wentland wrote: > >> On 2023-08-25 10:18, Melissa Wen wrote: >>> On 08/22, Pekka Paalanen wrote: >>>> On Thu, 10 Aug 2023 15:02:47 -0100 >>>> Melissa Wen wrote: >>>> >>>>> Instead of relying on color block names to get the transfer function >>>>> intention regarding encoding pixel's luminance, define supported >>>>> Electro-Optical Transfer Functions (EOTFs) and inverse EOTFs, that >>>>> includes pure gamma or standardized transfer functions. >>>>> >>>>> Suggested-by: Harry Wentland >>>>> Signed-off-by: Melissa Wen >>>>> --- >>>>> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 19 +++-- >>>>> .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 69 +++ >>>>> 2 files changed, 67 insertions(+), 21 deletions(-) >>>>> >>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>>>> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>>>> index c749c9cb3d94..f6251ed89684 100644 >>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h >>>>> @@ -718,14 +718,21 @@ extern const struct amdgpu_ip_block_version >>>>> dm_ip_block; >>>>> >>>>> enum amdgpu_transfer_function { >>>>> AMDGPU_TRANSFER_FUNCTION_DEFAULT, >>>>> - AMDGPU_TRANSFER_FUNCTION_SRGB, >>>>> - AMDGPU_TRANSFER_FUNCTION_BT709, >>>>> - AMDGPU_TRANSFER_FUNCTION_PQ, >>>>> + AMDGPU_TRANSFER_FUNCTION_SRGB_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_BT709_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_PQ_EOTF, >>>>> AMDGPU_TRANSFER_FUNCTION_LINEAR, >>>>> AMDGPU_TRANSFER_FUNCTION_UNITY, >>>>> - AMDGPU_TRANSFER_FUNCTION_GAMMA22, >>>>> - AMDGPU_TRANSFER_FUNCTION_GAMMA24, >>>>> - AMDGPU_TRANSFER_FUNCTION_GAMMA26, >>>>> + AMDGPU_TRANSFER_FUNCTION_GAMMA22_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_BT709_INV_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF, >>>>> + AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF, >>>>> +AMDGPU_TRANSFER_FUNCTION_COUNT >>>>> }; >>>>> >>>>> struct dm_plane_state { >>>>> 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 56ce008b9095..cc2187c0879a 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 >>>>> @@ -85,18 +85,59 @@ void amdgpu_dm_init_color_mod(void) >>>>> } >>>>> >>>>> #ifdef AMD_PRIVATE_COLOR >>>>> -static const struct drm_prop_enum_list >>>>> amdgpu_transfer_function_enum_list[] = { >>>>> - { AMDGPU_TRANSFER_FUNCTION_DEFAULT, "Default" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_SRGB, "sRGB" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_BT709, "BT.709" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_LINEAR, "Linear" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_UNITY, "Unity" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" }, >>>>> - { AMDGPU_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" }, >>>>> +static const char * const >>>>> +amdgpu_transfer_function_names[] = { >>>>> + [AMDGPU_TRANSFER_FUNCTION_DEFAULT] = "Default", >>>>> + [AMDGPU_TRANSFER_FUNCTION_LINEAR] = "Linear", >>>> >>>> Hi, >>>> >>>> if the below is identity, then what is linear? Is there a coefficient >>>> (multiplier) somewhere? Offset? >>>> &g
Re: [PATCH v2 01/34] drm/amd/display: fix segment distribution for linear LUTs
On 2023-09-08 10:11, Melissa Wen wrote: On 09/06, Harry Wentland wrote: On 2023-08-10 12:02, Melissa Wen wrote: From: Harry Wentland The region and segment calculation was incapable of dealing with regions of more than 16 segments. We first fix this. Now that we can support regions up to 256 elements we can define a better segment distribution for near-linear LUTs for our maximum of 256 HW-supported points. With these changes an "identity" LUT looks visually indistinguishable from bypass and allows us to use our 3DLUT. Have you had a chance to test whether this patch makes a difference? I haven't had the time yet. Last time I tested there was a banding issue on plane shaper LUT PQ -> Display Native, but it seems I don't have this use case on tester anymore, so I wasn't able to double-check if the issue persist. Maybe Joshua can provide some inputs here. Something I noticed is that shaper LUTs are the only 1D LUT on DCN30 pipeline that uses cm_helper_translate_curve_to_hw_format(), all others (dpp-degamma/dpp-blend/mpc-regamma) call cm3_helper_translate_curve_*. Yeah, they use different codepaths, unfortunately. Might be nice if we could make them use the same. We can drop it from this series until we get the steps to report the issue properly. Thanks. If you have concrete steps that show the issue (or even better, an IGT test) I would be happy to include this. Harry Melissa Harry Signed-off-by: Harry Wentland Signed-off-by: Melissa Wen --- .../amd/display/dc/dcn10/dcn10_cm_common.c| 93 +++ 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index 3538973bd0c6..04b2e04b68f3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -349,20 +349,37 @@ bool cm_helper_translate_curve_to_hw_format(struct dc_context *ctx, * segment is from 2^-10 to 2^1 * There are less than 256 points, for optimization */ - seg_distr[0] = 3; - seg_distr[1] = 4; - seg_distr[2] = 4; - seg_distr[3] = 4; - seg_distr[4] = 4; - seg_distr[5] = 4; - seg_distr[6] = 4; - seg_distr[7] = 4; - seg_distr[8] = 4; - seg_distr[9] = 4; - seg_distr[10] = 1; + if (output_tf->tf == TRANSFER_FUNCTION_LINEAR) { + seg_distr[0] = 0; /* 2 */ + seg_distr[1] = 1; /* 4 */ + seg_distr[2] = 2; /* 4 */ + seg_distr[3] = 3; /* 8 */ + seg_distr[4] = 4; /* 16 */ + seg_distr[5] = 5; /* 32 */ + seg_distr[6] = 6; /* 64 */ + seg_distr[7] = 7; /* 128 */ + + region_start = -8; + region_end = 1; + } else { + seg_distr[0] = 3; /* 8 */ + seg_distr[1] = 4; /* 16 */ + seg_distr[2] = 4; + seg_distr[3] = 4; + seg_distr[4] = 4; + seg_distr[5] = 4; + seg_distr[6] = 4; + seg_distr[7] = 4; + seg_distr[8] = 4; + seg_distr[9] = 4; + seg_distr[10] = 1; /* 2 */ + /* total = 8*16 + 8 + 64 + 2 = */ + + region_start = -10; + region_end = 1; + } + - region_start = -10; - region_end = 1; } for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) @@ -375,16 +392,56 @@ bool cm_helper_translate_curve_to_hw_format(struct dc_context *ctx, j = 0; for (k = 0; k < (region_end - region_start); k++) { - increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); + /* +* We're using an ugly-ish hack here. Our HW allows for +* 256 segments per region but SW_SEGMENTS is 16. +* SW_SEGMENTS has some undocumented relationship to +* the number of points in the tf_pts struct, which +* is 512, unlike what's suggested TRANSFER_FUNC_POINTS. +* +* In order to work past this dilemma we'll scale our +* increment by (1 << 4) and then do the inverse (1 >> 4) +* when accessing the elements in tf_pts. +* +* TODO: find a better way using SW_SEGMENTS and +* TRANSFER_FUNC_POINTS definitions +*/ + increment = (NUMBER_SW_SEGMENTS <&l
Re: [PATCH v2 32/34] drm/amd/display: add plane CTM driver-specific property
On 2023-09-08 10:41, Melissa Wen wrote: On 09/06, Harry Wentland wrote: On 2023-08-10 12:03, Melissa Wen wrote: Plane CTM for pre-blending color space conversion. Only enable driver-specific plane CTM property on drivers that support both pre- and post-blending gamut remap matrix, i.e., DCN3+ family. Otherwise it conflits with DRM CRTC CTM property. Signed-off-by: Melissa Wen --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 +++ .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 7 +++ .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 +++ 4 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index abb871a912d7..84bf501b02f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -363,6 +363,8 @@ struct amdgpu_mode_info { * @plane_hdr_mult_property: */ struct drm_property *plane_hdr_mult_property; + + struct drm_property *plane_ctm_property; /** * @shaper_lut_property: Plane property to set pre-blending shaper LUT * that converts color content before 3D LUT. diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 095f39f04210..6252ee912a63 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -769,6 +769,13 @@ struct dm_plane_state { * S31.32 sign-magnitude. */ __u64 hdr_mult; + /** +* @ctm: +* +* Color transformation matrix. See drm_crtc_enable_color_mgmt(). The +* blob (if not NULL) is a &struct drm_color_ctm. +*/ + struct drm_property_blob *ctm; /** * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an * array of &struct drm_color_lut. 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 4356846a2bce..86a918ab82be 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 @@ -218,6 +218,13 @@ amdgpu_dm_create_color_properties(struct amdgpu_device *adev) return -ENOMEM; adev->mode_info.plane_hdr_mult_property = prop; + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, + "AMD_PLANE_CTM", 0); We'll want to wrap the property creation/attachment with #ifdef AMD_PRIVATE_COLOR here as well. yeah, it's already wrapped because it's created and attached together with the other properties. Ah, I missed that. All good then. Reviewed-by: Harry Wentland Harry Harry + if (!prop) + return -ENOMEM; + adev->mode_info.plane_ctm_property = prop; + prop = drm_property_create(adev_to_drm(adev), DRM_MODE_PROP_BLOB, "AMD_PLANE_SHAPER_LUT", 0); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index 3fd57de7c5be..0b1081c690cb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -1355,6 +1355,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) if (dm_plane_state->degamma_lut) drm_property_blob_get(dm_plane_state->degamma_lut); + if (dm_plane_state->ctm) + drm_property_blob_get(dm_plane_state->ctm); if (dm_plane_state->shaper_lut) drm_property_blob_get(dm_plane_state->shaper_lut); if (dm_plane_state->lut3d) @@ -1436,6 +1438,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, if (dm_plane_state->degamma_lut) drm_property_blob_put(dm_plane_state->degamma_lut); + if (dm_plane_state->ctm) + drm_property_blob_put(dm_plane_state->ctm); if (dm_plane_state->lut3d) drm_property_blob_put(dm_plane_state->lut3d); if (dm_plane_state->shaper_lut) @@ -1473,6 +1477,11 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, dm->adev->mode_info.plane_hdr_mult_property, AMDGPU_HDR_MULT_DEFAULT); + /* Only enable plane CTM if both DPP and MPC gamut remap is available. */ + if (dm->dc->caps.color.mpc.gamut_remap) + drm_object_attach_property(&plane->base, + dm->adev->mode_info.plane
[RFC PATCH 00/10] Color Pipeline API w/ VKMS
This is an early RFC set for a color pipeline API, along with a sample implementation in VKMS. All the key API bits are here, but I would like to show a larger variety of colorop types, as well as examples of different possible color pipelines for a given plane. The first patch is a doc patch that will explain the motivation and reasoning behind this approach and give an overview over the API. 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. libdrm changes to support the new IOCTLs are at https://gitlab.freedesktop.org/hwentland/drm/-/merge_requests/1 If you prefer a gitlab MR for review you can find it at https://gitlab.freedesktop.org/hwentland/linux/-/merge_requests/5 A slightly different approach for a Color Pipeline API was sent by Uma Shankar and can be found at https://patchwork.freedesktop.org/series/123024/ The main difference is that his approach is not introducing a new DRM core object but instead exposes color pipelines via blob properties. There are pros and cons to both approaches. Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Harry Wentland (10): drm/doc/rfc: Describe why prescriptive color pipeline is needed drm/colorop: Introduce new drm_colorop mode object drm/colorop: Add TYPE property drm/color: Add 1D Curve subtype drm/colorop: Add BYPASS property drm/colorop: Add NEXT property drm/colorop: Add atomic state print for drm_colorop drm/colorop: Add new IOCTLs to retrieve drm_colorop objects drm/plane: Add COLOR PIPELINE property drm/vkms: Add enumerated 1D curve colorop Documentation/gpu/rfc/color_pipeline.rst | 278 ++ drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_atomic.c | 154 ++ drivers/gpu/drm/drm_atomic_helper.c | 12 + drivers/gpu/drm/drm_atomic_state_helper.c | 5 + drivers/gpu/drm/drm_atomic_uapi.c | 110 +++ drivers/gpu/drm/drm_colorop.c | 343 ++ drivers/gpu/drm/drm_crtc_internal.h | 4 + drivers/gpu/drm/drm_ioctl.c | 5 + drivers/gpu/drm/drm_mode_config.c | 7 + drivers/gpu/drm/drm_plane_helper.c| 2 +- drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/vkms_colorop.c | 108 +++ drivers/gpu/drm/vkms/vkms_composer.c | 316 drivers/gpu/drm/vkms/vkms_drv.h | 4 + drivers/gpu/drm/vkms/vkms_plane.c | 2 + include/drm/drm_atomic.h | 82 ++ include/drm/drm_atomic_uapi.h | 3 + include/drm/drm_colorop.h | 233 +++ include/drm/drm_mode_config.h | 18 ++ include/drm/drm_plane.h | 10 + include/uapi/drm/drm.h| 3 + include/uapi/drm/drm_mode.h | 22 ++ 23 files changed, 1723 insertions(+), 2 deletions(-) create mode 100644 Documentation/gpu/rfc/color_pipeline.rst create mode 100644 drivers/gpu/drm/drm_colorop.c create mode 100644 drivers/gpu/drm/vkms/vkms_colorop.c create mode 100644 include/drm/drm_colorop.h -- 2.42.0
[RFC PATCH 03/10] drm/colorop: Add TYPE property
Add a read-only TYPE property. The TYPE specifies the colorop type, such as enumerated curve, 1D LUT, CTM, 3D LUT, PWL LUT, etc. For now we're only introducing an enumerated 1D LUT type to illustrate the concept. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_atomic.c | 4 +-- drivers/gpu/drm/drm_atomic_uapi.c | 8 +- drivers/gpu/drm/drm_colorop.c | 44 ++- include/drm/drm_colorop.h | 21 ++- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index d734e9d5bfed..8a5f8cd22c8d 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -627,8 +627,8 @@ drm_atomic_get_colorop_state(struct drm_atomic_state *state, state->colorops[index].new_state = colorop_state; colorop_state->state = state; - drm_dbg_atomic(colorop->dev, "Added [COLOROP:%d] %p state to %p\n", - colorop->base.id, colorop_state, state); + drm_dbg_atomic(colorop->dev, "Added [COLOROP:%d:%d] %p state to %p\n", + colorop->base.id, colorop->type, colorop_state, state); /* TODO is this necessary? */ diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index b1aa752c1848..51072fe2b548 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -660,7 +660,13 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, const struct drm_colorop_state *state, struct drm_property *property, uint64_t *val) { - return -EINVAL; + if (property == colorop->type_property) { + *val = colorop->type; + } else { + return -EINVAL; + } + + return 0; } static int drm_atomic_set_writeback_fb_for_connector( diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 78d6a0067f5b..c028d5426d42 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -32,12 +32,17 @@ /* TODO big colorop doc, including properties, etc. */ +static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { + { DRM_COLOROP_1D_CURVE, "1D Curve" }, +}; + /* Init Helpers */ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, -struct drm_plane *plane) +struct drm_plane *plane, enum drm_colorop_type type) { struct drm_mode_config *config = &dev->mode_config; + struct drm_property *prop; int ret = 0; ret = drm_mode_object_add(dev, &colorop->base, DRM_MODE_OBJECT_COLOROP); @@ -46,12 +51,28 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->base.properties = &colorop->properties; colorop->dev = dev; + colorop->type = type; colorop->plane = plane; list_add_tail(&colorop->head, &config->colorop_list); colorop->index = config->num_colorop++; /* add properties */ + + /* type */ + prop = drm_property_create_enum(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ATOMIC, + "TYPE", drm_colorop_type_enum_list, + ARRAY_SIZE(drm_colorop_type_enum_list)); + if (!prop) + return -ENOMEM; + + colorop->type_property = prop; + + drm_object_attach_property(&colorop->base, + colorop->type_property, + colorop->type); + return ret; } EXPORT_SYMBOL(drm_colorop_init); @@ -167,3 +188,24 @@ void drm_colorop_reset(struct drm_colorop *colorop) __drm_colorop_reset(colorop, colorop->state); } EXPORT_SYMBOL(drm_colorop_reset); + + +static const char * const colorop_type_name[] = { + [DRM_COLOROP_1D_CURVE] = "1D Curve", +}; + +/** + * drm_get_colorop_type_name - return a string for colorop type + * @range: colorop type to compute name of + * + * In contrast to the other drm_get_*_name functions this one here returns a + * const pointer and hence is threadsafe. + */ +const char *drm_get_colorop_type_name(enum drm_colorop_type type) +{ + if (WARN_ON(type >= ARRAY_SIZE(colorop_type_name))) + return "unknown"; + + return colorop_type_name[type]; +} + diff --git a/include/drm/drm_colorop.h b/in
[RFC PATCH 01/10] drm/doc/rfc: Describe why prescriptive color pipeline is needed
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- Documentation/gpu/rfc/color_pipeline.rst | 278 +++ 1 file changed, 278 insertions(+) create mode 100644 Documentation/gpu/rfc/color_pipeline.rst diff --git a/Documentation/gpu/rfc/color_pipeline.rst b/Documentation/gpu/rfc/color_pipeline.rst new file mode 100644 index ..bfa4a8f12087 --- /dev/null +++ b/Documentation/gpu/rfc/color_pipeline.rst @@ -0,0 +1,278 @@ + +Linux Color Pipeline API + + +What problem are we solving? + + +We would like to support pre-, and post-blending complex color transformations +in order to allow for HW-supported HDR use-cases, as well as to provide support +to color-managed applications, such as video or image editors. + +While it is possible to support an HDR output on HW supporting the Colorspace +and HDR Metadata drm_connector properties that requires the compositor or +application to render and compose the content into one final buffer intended for +display. Doing so is costly. + +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other +operations to support color transformations. These operations are often +implemented in fixed-function HW and therefore much more power efficient than +performing similar operations via shaders or CPU. + +We would like to make use of this HW functionality to support complex color +transformations with no, or minimal CPU or shader load. + + +How are other OSes solving this problem? + + +The most widely supported use-cases regard HDR content, whether video or +gaming. + +Most OSes will specify the source content format (color gamut, encoding transfer +function, and other metadata, such as max and average light levels) to a driver. +Drivers will then program their fixed-function HW accordingly to map from a +source content buffer's space to a display's space. + +When fixed-function HW is not available the compositor will assemble a shader to +ask the GPU to perform the transformation from the source content format to the +display's format. + +A compositor's mapping function and a driver's mapping function are usually +entirely separate concepts. On OSes where a HW vendor has no insight into +closed-source compositor code such a vendor will tune their color management +code to visually match the compositor's. On other OSes, where both mapping +functions are open to an implementer they will ensure both mappings match. + + +Why is Linux different? +=== + +Unlike other OSes, where there is one compositor for one or more drivers, on +Linux we have a many-to-many relationship. Many compositors; many drivers. +In addition each compositor vendor or community has their own view of how +color management should be done. This is what makes Linux so beautiful. + +This means that a HW vendor can now no longer tune their driver to one +compositor, as tuning it to one will almost inevitably make it look very +different from another compositor's color mapping. + +We need a better solution. + + +Descriptive API +=== + +An API that describes the source and destination colorspaces is a descriptive +API. It describes the input and output color spaces but does not describe +how precisely they should be mapped. Such a mapping includes many minute +design decision that can greatly affect the look of the final result. + +It is not feasible to describe such mapping with enough detail to ensure the +same result from each implementation. In fact, these mappings are a very active +research area. + + +Prescriptive API + + +A prescriptive API describes not the source and destination colorspaces. It +instead prescribes a recipe for how to manipulate pixel values to arrive at the +desired outcome. + +This recipe is generally an order straight-forward operations, with clear +mathematical definitions, such as 1D LUTs, 3D LUTs, matrices, or other +operations that can be described in a precise manner. + + +The Color Pipeline API +== + +HW color management pipelines can significantly differ between HW +vendors in terms of availability, ordering, and capabilities of HW +blocks. This makes a common definition of color management blocks and +their ordering nigh impossible. Instead we are defining an API that +allows user space to discover the HW capabilities. + + +drm_colorop Object & IOCTLs +=== + +To support the definition of color pipelines we introduce a new DRM core +object, a drm_colorop. Individual drm_c
[RFC PATCH 02/10] drm/colorop: Introduce new drm_colorop mode object
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. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/Makefile| 1 + drivers/gpu/drm/drm_atomic.c| 79 + drivers/gpu/drm/drm_atomic_helper.c | 12 ++ drivers/gpu/drm/drm_atomic_uapi.c | 48 drivers/gpu/drm/drm_colorop.c | 169 drivers/gpu/drm/drm_mode_config.c | 7 ++ drivers/gpu/drm/drm_plane_helper.c | 2 +- include/drm/drm_atomic.h| 82 ++ include/drm/drm_atomic_uapi.h | 1 + include/drm/drm_colorop.h | 157 ++ include/drm/drm_mode_config.h | 18 +++ include/drm/drm_plane.h | 2 + include/uapi/drm/drm.h | 3 + include/uapi/drm/drm_mode.h | 1 + 14 files changed, 581 insertions(+), 1 deletion(-) 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 1855863b4d7a..941de0269709 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 11f3a130f6f4..d734e9d5bfed 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; state->dev = dev; @@ -244,6 +250,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; @@ -562,6 +582,65 @@ 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; + struct drm_plane_state *plane_state; + + WARN_ON(!state->acquire_ctx); + + colorop_state = drm_atomic_get_existing_colorop_state(state, colorop); +
[RFC PATCH 04/10] drm/color: Add 1D Curve subtype
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_atomic_uapi.c | 18 ++ drivers/gpu/drm/drm_colorop.c | 39 +++ include/drm/drm_colorop.h | 20 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 51072fe2b548..9b01f234b04e 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -648,11 +648,17 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, struct drm_colorop_state *state, struct drm_file *file_priv, struct drm_property *property, uint64_t val) { - drm_dbg_atomic(colorop->dev, - "[COLOROP:%d] unknown property [PROP:%d:%s]]\n", - colorop->base.id, - property->base.id, property->name); - return -EINVAL; + if (property == colorop->curve_1d_type_property) { + state->curve_1d_type = val; + } else { + drm_dbg_atomic(colorop->dev, + "[COLOROP:%d:%d] unknown property [PROP:%d:%s]]\n", + colorop->base.id, colorop->type, + property->base.id, property->name); + return -EINVAL; + } + + return 0; } static int @@ -662,6 +668,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, { if (property == colorop->type_property) { *val = colorop->type; + } else if (property == colorop->curve_1d_type_property) { + *val = state->curve_1d_type; } else { return -EINVAL; } diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index c028d5426d42..f665a12a214e 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -36,6 +36,11 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { { DRM_COLOROP_1D_CURVE, "1D Curve" }, }; +static const struct drm_prop_enum_list drm_colorop_curve_1d_type_enum_list[] = { + { DRM_COLOROP_1D_CURVE_SRGB_EOTF, "sRGB EOTF" }, + { DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF, "sRGB Inverse EOTF" }, +}; + /* Init Helpers */ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, @@ -73,6 +78,20 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->type_property, colorop->type); + /* curve_1d_type */ + /* TODO move to mode_config? */ + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, + "CURVE_1D_TYPE", + drm_colorop_curve_1d_type_enum_list, + ARRAY_SIZE(drm_colorop_curve_1d_type_enum_list)); + if (!prop) + return -ENOMEM; + + colorop->curve_1d_type_property = prop; + drm_object_attach_property(&colorop->base, + colorop->curve_1d_type_property, + 0); + return ret; } EXPORT_SYMBOL(drm_colorop_init); @@ -194,6 +213,11 @@ static const char * const colorop_type_name[] = { [DRM_COLOROP_1D_CURVE] = "1D Curve", }; +static const char * const colorop_curve_1d_type_name[] = { + [DRM_COLOROP_1D_CURVE_SRGB_EOTF] = "sRGB EOTF", + [DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF] = "sRGB Inverse EOTF", +}; + /** * drm_get_colorop_type_name - return a string for colorop type * @range: colorop type to compute name of @@ -209,3 +233,18 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type type) return colorop_type_name[type]; } +/** + * drm_get_colorop_curve_1d_type_name - return a string for 1D curve type + * @range: 1d curve type to compute name of + * + * In contrast to the other drm_get_*_name functions this one here returns a + * const pointer and hence is threadsafe. + */ +const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type) +{ + if (WARN_ON(type >= ARRAY_SIZE(colorop_curve_1d_type_name))) + return "unknown"; + + return colorop_curve_1d_type_name[type]; +} + diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 22a217372428..7701b61ff7e9 100644 --- a/
[RFC PATCH 06/10] drm/colorop: Add NEXT property
We'll construct color pipelines out of drm_colorop by chaining them via the NEXT pointer. NEXT will point to the next drm_colorop in the pipeline, or by 0 if we're at the end of the pipeline. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_colorop.c | 27 +++ include/drm/drm_colorop.h | 12 2 files changed, 39 insertions(+) diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 409df022b256..a92e170aed87 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -104,6 +104,15 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->curve_1d_type_property, 0); + prop = drm_property_create_object(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ATOMIC, + "NEXT", DRM_MODE_OBJECT_COLOROP); + if (!prop) + return -ENOMEM; + colorop->next_property = prop; + drm_object_attach_property(&colorop->base, + colorop->next_property, + 0); + return ret; } EXPORT_SYMBOL(drm_colorop_init); @@ -263,3 +272,21 @@ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type ty return colorop_curve_1d_type_name[type]; } + +/** + * drm_colorop_set_next_property - sets the next pointer + * @colorop: drm colorop + * @next: next colorop + * + * Should be used when constructing the color pipeline + */ +void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next) +{ + if (!colorop->next_property) + return; + + drm_object_property_set_value(&colorop->base, + colorop->next_property, + next->base.id); +} +EXPORT_SYMBOL(drm_colorop_set_next_property); diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 69636f6752a0..1ddd0e65fe36 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -162,10 +162,20 @@ struct drm_colorop { */ struct drm_property *curve_1d_type_property; + /** +* @next_property +* +* Read-only property to next colorop in the pipeline +*/ + struct drm_property *next_property; + }; #define obj_to_colorop(x) container_of(x, struct drm_colorop, base) + + + /** * drm_crtc_find - look up a Colorop object from its ID * @dev: DRM device @@ -212,5 +222,7 @@ static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) #define drm_for_each_colorop(colorop, dev) \ list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head) +void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); + #endif /* __DRM_COLOROP_H__ */ -- 2.42.0
[RFC PATCH 07/10] drm/colorop: Add atomic state print for drm_colorop
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_atomic.c | 29 + include/drm/drm_colorop.h| 5 + 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 8a5f8cd22c8d..30308b8dec53 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -783,6 +783,19 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, return 0; } + + +static void drm_atomic_colorop_print_state(struct drm_printer *p, + const struct drm_colorop_state *state) +{ + struct drm_colorop *colorop = state->colorop; + + drm_printf(p, "colorop[%u]:\n", colorop->base.id); + drm_printf(p, "\ttype=%s\n", drm_get_colorop_type_name(colorop->type)); + drm_printf(p, "\tbypass=%u\n", state->bypass); + drm_printf(p, "\tcurve_1d_type=%s\n", drm_get_colorop_curve_1d_type_name(state->curve_1d_type)); +} + static void drm_atomic_plane_print_state(struct drm_printer *p, const struct drm_plane_state *state) { @@ -803,6 +816,13 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_get_color_encoding_name(state->color_encoding)); drm_printf(p, "\tcolor-range=%s\n", drm_get_color_range_name(state->color_range)); +#if 0 + drm_printf(p, "\tcolor-pipeline=%s\n", + drm_get_color_pipeline_name(state->color_pipeline)); +#else + drm_printf(p, "\tcolor-pipeline=%d\n", + state->color_pipeline ? state->color_pipeline->base.id : 0); +#endif if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state); @@ -1779,6 +1799,7 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, bool take_locks) { struct drm_mode_config *config = &dev->mode_config; + struct drm_colorop *colorop; struct drm_plane *plane; struct drm_crtc *crtc; struct drm_connector *connector; @@ -1787,6 +1808,14 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, if (!drm_drv_uses_atomic_modeset(dev)) return; + list_for_each_entry(colorop, &config->colorop_list, head) { + if (take_locks) + drm_modeset_lock(&colorop->plane->mutex, NULL); + drm_atomic_colorop_print_state(p, colorop->state); + if (take_locks) + drm_modeset_unlock(&colorop->plane->mutex); + } + list_for_each_entry(plane, &config->plane_list, head) { if (take_locks) drm_modeset_lock(&plane->mutex, NULL); diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 1ddd0e65fe36..622a671d2458 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -222,6 +222,11 @@ static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) #define drm_for_each_colorop(colorop, dev) \ list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head) +const char *drm_get_color_pipeline_name(struct drm_colorop *colorop); + +const char *drm_get_colorop_type_name(enum drm_colorop_type type); +const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); + void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); -- 2.42.0
[RFC PATCH 05/10] drm/colorop: Add BYPASS property
We want to be able to bypass each colorop at all times. Introduce a new BYPASS boolean property for this. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_atomic_uapi.c | 6 +- drivers/gpu/drm/drm_colorop.c | 15 +++ include/drm/drm_colorop.h | 20 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 9b01f234b04e..ca3512038d4c 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -648,7 +648,9 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, struct drm_colorop_state *state, struct drm_file *file_priv, struct drm_property *property, uint64_t val) { - if (property == colorop->curve_1d_type_property) { + if (property == colorop->bypass_property) { + state->bypass = val; + } else if (property == colorop->curve_1d_type_property) { state->curve_1d_type = val; } else { drm_dbg_atomic(colorop->dev, @@ -668,6 +670,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, { if (property == colorop->type_property) { *val = colorop->type; + } else if (property == colorop->bypass_property) { + *val = state->bypass; } else if (property == colorop->curve_1d_type_property) { *val = state->curve_1d_type; } else { diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index f665a12a214e..409df022b256 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -78,6 +78,18 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->type_property, colorop->type); + /* bypass */ + /* TODO can we reuse the mode_config->active_prop? */ + prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC, + "BYPASS"); + if (!prop) + return -ENOMEM; + + colorop->bypass_property = prop; + drm_object_attach_property(&colorop->base, + colorop->bypass_property, + 1); + /* curve_1d_type */ /* TODO move to mode_config? */ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, @@ -100,6 +112,8 @@ void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop, struct drm_colorop_state *state) { memcpy(state, colorop->state, sizeof(*state)); + + state->bypass = true; } struct drm_colorop_state * @@ -164,6 +178,7 @@ void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state, struct drm_colorop *colorop) { colorop_state->colorop = colorop; + colorop_state->bypass = true; } EXPORT_SYMBOL(__drm_colorop_state_reset); diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 7701b61ff7e9..69636f6752a0 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -48,6 +48,14 @@ struct drm_colorop_state { /* colorop properties */ + /** +* @bypass: +* +* True if colorop shall be bypassed. False if colorop is +* enabled. +*/ + bool bypass; + /** * @curve_1d_type: * @@ -135,6 +143,18 @@ struct drm_colorop { */ struct drm_property *type_property; + /** +* @bypass_property: +* +* Boolean property to control enablement of the color +* operation. Setting bypass to "true" shall always be supported +* in order to allow compositors to quickly fall back to +* alternate methods of color processing. This is important +* since setting color operations can fail due to unique +* HW constraints. +*/ + struct drm_property *bypass_property; + /** * @curve_1d_type: * -- 2.42.0
[RFC PATCH 08/10] drm/colorop: Add new IOCTLs to retrieve drm_colorop objects
Since we created a new DRM object we need new IOCTLs (and new libdrm functions) to retrieve those objects. TODO: Can we make these IOCTLs and libdrm functions generic to allow for new DRM objects in the future without the need for new IOCTLs and libdrm functions? Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_colorop.c | 51 + drivers/gpu/drm/drm_crtc_internal.h | 4 +++ drivers/gpu/drm/drm_ioctl.c | 5 +++ include/uapi/drm/drm_mode.h | 21 4 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index a92e170aed87..fb85b5c41cc4 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -32,6 +32,57 @@ /* TODO big colorop doc, including properties, etc. */ +/* IOCTLs */ + +int drm_mode_getcolorop_res(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_mode_get_colorop_res *colorop_resp = data; + struct drm_colorop *colorop; + uint32_t __user *colorop_ptr; + int count = 0; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EOPNOTSUPP; + + colorop_ptr = u64_to_user_ptr(colorop_resp->colorop_id_ptr); + + /* +* This ioctl is called twice, once to determine how much space is +* needed, and the 2nd time to fill it. +*/ + drm_for_each_colorop(colorop, dev) { + if (drm_lease_held(file_priv, colorop->base.id)) { + if (count < colorop_resp->count_colorops && + put_user(colorop->base.id, colorop_ptr + count)) + return -EFAULT; + count++; + } + } + colorop_resp->count_colorops = count; + + return 0; +} + +int drm_mode_getcolorop(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_mode_get_colorop *colorop_resp = data; + struct drm_colorop *colorop; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EOPNOTSUPP; + + colorop = drm_colorop_find(dev, file_priv, colorop_resp->colorop_id); + if (!colorop) + return -ENOENT; + + colorop_resp->colorop_id = colorop->base.id; + colorop_resp->plane_id = colorop->plane ? colorop->plane->base.id : 0; + + return 0; +} + static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { { DRM_COLOROP_1D_CURVE, "1D Curve" }, }; diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 501a10edd0e1..b68e05c2cf57 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -278,6 +278,10 @@ int drm_mode_getplane(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_file *file_priv); +int drm_mode_getcolorop_res(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_mode_getcolorop(struct drm_device *dev, void *data, + struct drm_file *file_priv); int drm_mode_cursor_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_mode_cursor2_ioctl(struct drm_device *dev, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 7c9d66ee917d..a3c137ac88c6 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -716,6 +716,11 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCOLOROPRESOURCES, drm_mode_getcolorop_res, 0), + /* TODO do we need GETCOLOROP? */ + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCOLOROP, drm_mode_getcolorop, 0), + }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE(drm_ioctls) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 6dcf628def56..9e37eec55291 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -357,6 +357,27 @@ struct drm_mode_get_plane { __u64 format_type_ptr; }; +struct drm_mode_get_colorop_res { + __u64 colorop_id_ptr; + __u32 cou
[RFC PATCH 10/10] drm/vkms: Add enumerated 1D curve colorop
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/vkms/Makefile| 3 +- drivers/gpu/drm/vkms/vkms_colorop.c | 108 + drivers/gpu/drm/vkms/vkms_composer.c | 316 +++ drivers/gpu/drm/vkms/vkms_drv.h | 4 + drivers/gpu/drm/vkms/vkms_plane.c| 2 + 5 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/vkms/vkms_colorop.c diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 1b28a6a32948..bcf508873622 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -6,6 +6,7 @@ vkms-y := \ vkms_formats.o \ vkms_crtc.o \ vkms_composer.o \ - vkms_writeback.o + vkms_writeback.o \ + vkms_colorop.o obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c b/drivers/gpu/drm/vkms/vkms_colorop.c new file mode 100644 index ..b3da0705bca7 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_colorop.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 Advanced Micro Devices, Inc. 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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: AMD + * + */ + +#include +#include +#include +#include +#include + +#define MAX_COLOR_PIPELINES 5 + +const int vkms_initialize_tf_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list) +{ + + struct drm_colorop *op, *prev_op; + struct drm_device *dev = plane->dev; + int ret; + + /* 1st op: 1d curve */ + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + if (!op) { + DRM_ERROR("KMS: Failed to allocate colorop\n"); + return -ENOMEM; + } + + ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); + if (ret) + return ret; + + list->type = op->base.id; + list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", op->base.id); + + prev_op = op; + + /* 2nd op: 1d curve */ + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + if (!op) { + DRM_ERROR("KMS: Failed to allocate colorop\n"); + return -ENOMEM; + } + + ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); + if (ret) + return ret; + + drm_colorop_set_next_property(prev_op, op); + + return 0; +} + +int vkms_initialize_colorops(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES]; + int len = 0; + int ret; + + /* Add "Bypass" (i.e. NULL) pipeline */ + pipelines[len].type = 0; + pipelines[len].name = "Bypass"; + len++; + + /* Add pipeline consisting of transfer functions */ + ret = vkms_initialize_tf_pipeline(plane, &(pipelines[len])); + if (ret) + return ret; + len++; + + /* Create COLOR_PIPELINE property and attach */ + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, + "COLOR_PIPELINE", + pipelines, len); + if (!prop) + return -ENOMEM; + + plane->color_pipeline_property = prop; + + drm_object_attach_property(&plane->base, prop, 0); + + /* TODO do we even need this? */ + if (plane->state) + plane->state->color_pipeline = NULL; + + return 0; +} d
[RFC PATCH 09/10] drm/plane: Add COLOR PIPELINE property
We're adding a new enum COLOR PIPELINE property. This property will have entries for each COLOR PIPELINE by referencing the DRM object ID of the first drm_colorop of the pipeline. 0 disables the entire COLOR PIPELINE. Userspace can use this to discover the available color pipelines, as well as set the desired one. The color pipelines are programmed via properties on the actual drm_colorop objects. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- drivers/gpu/drm/drm_atomic.c | 46 +++ drivers/gpu/drm/drm_atomic_state_helper.c | 5 +++ drivers/gpu/drm/drm_atomic_uapi.c | 44 ++ include/drm/drm_atomic_uapi.h | 2 + include/drm/drm_plane.h | 8 5 files changed, 105 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 30308b8dec53..a8b978e8f3eb 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1403,6 +1403,52 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_add_affected_planes); +/** + * drm_atomic_add_affected_colorops - add colorops for plane + * @state: atomic state + * @plane: DRM plane + * + * This function walks the current configuration and adds all colorops + * currently used by @plane to the atomic configuration @state. This is useful + * when an atomic commit also needs to check all currently enabled colorop on + * @plane, e.g. when changing the mode. It's also useful when re-enabling a plane + * to avoid special code to force-enable all colorops. + * + * Since acquiring a colorop state will always also acquire the w/w mutex of the + * current plane for that colorop (if there is any) adding all the colorop states for + * a plane will not reduce parallelism of atomic updates. + * + * Returns: + * 0 on success or can fail with -EDEADLK or -ENOMEM. 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. + */ +int +drm_atomic_add_affected_colorops(struct drm_atomic_state *state, +struct drm_plane *plane) +{ + struct drm_colorop *colorop; + struct drm_colorop_state *colorop_state; + + WARN_ON(!drm_atomic_get_new_plane_state(state, plane)); + + drm_dbg_atomic(plane->dev, + "Adding all current colorops for [plane:%d:%s] to %p\n", + plane->base.id, plane->name, state); + + drm_for_each_colorop(colorop, plane->dev) { + if (colorop->plane != plane) + continue; + + colorop_state = drm_atomic_get_colorop_state(state, colorop); + if (IS_ERR(colorop_state)) + return PTR_ERR(colorop_state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_add_affected_colorops); + /** * drm_atomic_check_only - check whether a given config would work * @state: atomic configuration to check diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 784e63d70a42..3c5f2c8e33d0 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -267,6 +267,11 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, plane_state->color_range = val; } + if (plane->color_pipeline_property) { + /* default is always NULL, i.e., bypass */ + plane_state->color_pipeline = NULL; + } + if (plane->zpos_property) { if (!drm_object_property_get_default_value(&plane->base, plane->zpos_property, diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index ca3512038d4c..44ceb10acb6f 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -256,6 +256,38 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, } EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); + +/** + * drm_atomic_set_colorop_for_plane - set colorop for plane + * @plane_state: atomic state object for the plane + * @colorop: colorop to use for the plane + * + * Changing the assigned framebuffer for a plane requires us to grab a reference + * to the new fb and drop the reference to the old fb, if there is one. This + * function takes care of all these details besides updating the pointer in the + * state object itself. + */ +void +drm_atomic_
Re: [PATCH v2 2/2] Revert "drm/amd: Disable S/G for APUs when 64GB or more host memory"
Series is Acked-by: Harry Wentland Harry On 2023-09-08 10:55, Hamza Mahfooz wrote: This reverts commit 5b7a256c982636ebc4f16b708b40ff56d33c8a86. Since, we now have an actual fix for this issue, we can get rid of this workaround as it can cause pin failures if enough VRAM isn't carved out by the BIOS. Cc: sta...@vger.kernel.org # 6.1+ Signed-off-by: Hamza Mahfooz --- v2: new to the series --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 26 --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++-- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 83a9607a87b8..3a86d11d1605 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1316,7 +1316,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); int amdgpu_device_pci_reset(struct amdgpu_device *adev); bool amdgpu_device_need_post(struct amdgpu_device *adev); -bool amdgpu_sg_display_supported(struct amdgpu_device *adev); bool amdgpu_device_pcie_dynamic_switching_supported(void); bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); bool amdgpu_device_aspm_support_quirk(void); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5f32e8d4f3d3..3d540b0cf0e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1358,32 +1358,6 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev) return true; } -/* - * On APUs with >= 64GB white flickering has been observed w/ SG enabled. - * Disable S/G on such systems until we have a proper fix. - * https://gitlab.freedesktop.org/drm/amd/-/issues/2354 - * https://gitlab.freedesktop.org/drm/amd/-/issues/2735 - */ -bool amdgpu_sg_display_supported(struct amdgpu_device *adev) -{ - switch (amdgpu_sg_display) { - case -1: - break; - case 0: - return false; - case 1: - return true; - default: - return false; - } - if ((totalram_pages() << (PAGE_SHIFT - 10)) + - (adev->gmc.real_vram_size / 1024) >= 6400) { - DRM_WARN("Disabling S/G due to >=64GB RAM\n"); - return false; - } - return true; -} - /* * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic * speed switching. Until we have confirmation from Intel that a specific host diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 5f14cd9391ca..740a6fcafe4c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1654,8 +1654,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) } break; } - if (init_data.flags.gpu_vm_support) - init_data.flags.gpu_vm_support = amdgpu_sg_display_supported(adev); + if (init_data.flags.gpu_vm_support && + (amdgpu_sg_display == 0)) + init_data.flags.gpu_vm_support = false; if (init_data.flags.gpu_vm_support) adev->mode_info.gpu_vm_support = true;
Re: [RFC PATCH 01/10] drm/doc/rfc: Describe why prescriptive color pipeline is needed
On 2023-09-08 15:30, Sebastian Wick wrote: Hey Harry, Thank you and Simon for this great document. Really happy about it, but obviously I've got a few notes and questions inline. On Fri, Sep 08, 2023 at 11:02:26AM -0400, Harry Wentland wrote: Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Daniel Vetter Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga --- Documentation/gpu/rfc/color_pipeline.rst | 278 +++ 1 file changed, 278 insertions(+) create mode 100644 Documentation/gpu/rfc/color_pipeline.rst diff --git a/Documentation/gpu/rfc/color_pipeline.rst b/Documentation/gpu/rfc/color_pipeline.rst new file mode 100644 index ..bfa4a8f12087 --- /dev/null +++ b/Documentation/gpu/rfc/color_pipeline.rst @@ -0,0 +1,278 @@ + +Linux Color Pipeline API + + +What problem are we solving? + + +We would like to support pre-, and post-blending complex color transformations +in order to allow for HW-supported HDR use-cases, as well as to provide support +to color-managed applications, such as video or image editors. + +While it is possible to support an HDR output on HW supporting the Colorspace +and HDR Metadata drm_connector properties that requires the compositor or +application to render and compose the content into one final buffer intended for +display. Doing so is costly. + +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other +operations to support color transformations. These operations are often +implemented in fixed-function HW and therefore much more power efficient than +performing similar operations via shaders or CPU. + +We would like to make use of this HW functionality to support complex color +transformations with no, or minimal CPU or shader load. + + +How are other OSes solving this problem? + + +The most widely supported use-cases regard HDR content, whether video or +gaming. + +Most OSes will specify the source content format (color gamut, encoding transfer +function, and other metadata, such as max and average light levels) to a driver. +Drivers will then program their fixed-function HW accordingly to map from a +source content buffer's space to a display's space. + +When fixed-function HW is not available the compositor will assemble a shader to +ask the GPU to perform the transformation from the source content format to the +display's format. + +A compositor's mapping function and a driver's mapping function are usually +entirely separate concepts. On OSes where a HW vendor has no insight into +closed-source compositor code such a vendor will tune their color management +code to visually match the compositor's. On other OSes, where both mapping +functions are open to an implementer they will ensure both mappings match. + + +Why is Linux different? +=== + +Unlike other OSes, where there is one compositor for one or more drivers, on +Linux we have a many-to-many relationship. Many compositors; many drivers. +In addition each compositor vendor or community has their own view of how +color management should be done. This is what makes Linux so beautiful. + +This means that a HW vendor can now no longer tune their driver to one +compositor, as tuning it to one will almost inevitably make it look very +different from another compositor's color mapping. + +We need a better solution. + + +Descriptive API +=== + +An API that describes the source and destination colorspaces is a descriptive +API. It describes the input and output color spaces but does not describe +how precisely they should be mapped. Such a mapping includes many minute +design decision that can greatly affect the look of the final result. + +It is not feasible to describe such mapping with enough detail to ensure the +same result from each implementation. In fact, these mappings are a very active +research area. + + +Prescriptive API + + +A prescriptive API describes not the source and destination colorspaces. It +instead prescribes a recipe for how to manipulate pixel values to arrive at the +desired outcome. + +This recipe is generally an order straight-forward operations, with clear +mathematical definitions, such as 1D LUTs, 3D LUTs, matrices, or other +operations that can be described in a precise manner. + + +The Color Pipeline API +== + +HW color management pipelines can significantly differ between HW +vendors in terms of availability, ordering, and capabilities of HW +blocks. This makes a common definition of color management blocks and +their ordering nigh impossible. Instead we are
Re: [PATCH] drm/amd: Drop abm_level property
On 2024-03-06 13:02, Mario Limonciello wrote: > On 3/6/2024 12:00, Xaver Hugl wrote: >> Am Mi., 6. März 2024 um 18:19 Uhr schrieb Mario Limonciello >> : >>> So the idea being if the compositor isn't using it we let >>> power-profiles-daemon (or any other software) take control via sysfs and >>> if the compositor does want to control it then it then it writes a DRM >>> cap and we destroy the sysfs file? >> >> Yes. That way still only one party controls it at a given time, and we >> can get both good default behavior for display servers that don't care >> (like Xorg or compositors without color management support), and >> compositors that want to put in the effort can do more specific things >> with it. > > I think that's a very good solution. > > Harry, Hamza, what do you guys think? In theory I like it. But how will this look in practice? Is PPD or compositor on the scene first? Would it be possible to yank the sysfs away from PPD? DRM client caps are set by the client when the client interacts with DRM. At driver creation there is no client. How will the driver set things up? A user might switch between DRM clients (login manager, to desktop compositor, maybe to another VT with a different compositor). I know everything but the login manager to desktop compositor hand-off is today considered exotic, but what if someone starts building a use-case for it? I've done a bunch of gamescope or IGT work in a different VT while I've had Plasma running on its default VT. If someone can sketch this out, with answers to all the questions above and any other questions you can come up (be creative), I'd be happy to review. Alternatively we can discuss this at the hackfest and maybe arrive at a solution. Harry
Re: [PATCH 1/7] drm: Fix drm_fixp2int_round() making it add 0.5
On 2024-03-06 15:03, Arthur Grillo wrote: As well noted by Pekka[1], the rounding of drm_fixp2int_round is wrong. To round a number, you need to add 0.5 to the number and floor that, drm_fixp2int_round() is adding 0.076. Make it add 0.5. [1]: https://lore.kernel.org/all/20240301135327.22efe0dd.pekka.paala...@collabora.com/ Suggested-by: Pekka Paalanen Signed-off-by: Arthur Grillo Reviewed-by: Harry Wentland I had a different jab at this [1], but your patch is cleaner. https://patchwork.freedesktop.org/patch/579978/?series=123446&rev=4 Harry --- include/drm/drm_fixed.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h index 0c9f917a4d4b..de3a79909ac9 100644 --- a/include/drm/drm_fixed.h +++ b/include/drm/drm_fixed.h @@ -90,7 +90,7 @@ static inline int drm_fixp2int(s64 a) static inline int drm_fixp2int_round(s64 a) { - return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1))); + return drm_fixp2int(a + DRM_FIXED_ONE / 2); } static inline int drm_fixp2int_ceil(s64 a)
Re: [PATCH 1/7] drm: Fix drm_fixp2int_round() making it add 0.5
On 2024-03-14 09:31, Melissa Wen wrote: > On 03/14, Melissa Wen wrote: >> On 03/13, Arthur Grillo wrote: >>> >>> >>> On 12/03/24 15:27, Melissa Wen wrote: On 03/06, Arthur Grillo wrote: > As well noted by Pekka[1], the rounding of drm_fixp2int_round is wrong. > To round a number, you need to add 0.5 to the number and floor that, > drm_fixp2int_round() is adding 0.076. Make it add 0.5. > > [1]: > https://lore.kernel.org/all/20240301135327.22efe0dd.pekka.paala...@collabora.com/ > Hi Arthur, thanks for addressing this issue. Please, add a fix tag to the commit that you are fixing, so we can easily backport. Might be this commit: https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/vkms?id=ab87f558dcfb2562c3497e89600dec798a446665 > Suggested-by: Pekka Paalanen > Signed-off-by: Arthur Grillo > --- > include/drm/drm_fixed.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h > index 0c9f917a4d4b..de3a79909ac9 100644 > --- a/include/drm/drm_fixed.h > +++ b/include/drm/drm_fixed.h > @@ -90,7 +90,7 @@ static inline int drm_fixp2int(s64 a) > > static inline int drm_fixp2int_round(s64 a) > { > - return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1))); Also, this is the only usage of DRM_FIXED_POINT_HALF. Can you also remove it as it won't be used anymore? > + return drm_fixp2int(a + DRM_FIXED_ONE / 2); Would this division be equivalent to just shifting 1ULL by 31 instead of 32 as done in DRM_FIXED_ONE? >>> >>> Yes, but I think the division makes it easier to understand what is >>> going on. >> >> Right. I was thinking about slightly better performance, but I don't >> have any data. We can go with this since you consider more readable, >> anyway. > > Just checked that Harry proposed in another patch[1] this: > `#define DRM_FIXED_HALF 0x8000ll` for the 0.5 const > > Doesn't it sounds better? > I tend to agree with Arthur and Pekka. DRM_FIXED_ONE / 2 makes it really clear what's happening here. And I'd imagine compilers would optimize it out anyways. Obviously not opposed to a define but if it's only used in one place I don't think it matters much. Harry > [1] > https://lore.kernel.org/dri-devel/20240226211100.100108-4-harry.wentl...@amd.com/ >> >> Can you send another version addressing the other comments? Then I can >> cherry-pick and already apply the fix. >> >> Thanks, >> >> Melissa >> >>> >>> Best Regards, >>> ~Arthur Grillo >>> Melissa > } > > static inline int drm_fixp2int_ceil(s64 a) > > -- > 2.43.0 >
Re: [PATCH 2/2] drm/amd/display: Move PRIMARY plane zpos higher
On 2024-03-15 13:09, sunpeng...@amd.com wrote: > From: Leo Li > > [Why] > > Compositors have different ways of assigning surfaces to DRM planes for > render offloading. It may decide between various strategies: overlay, > underlay, or a mix of both > > One way for compositors to implement the underlay strategy is to assign > a higher zpos to the DRM_PRIMARY plane than the DRM_OVERLAY planes, > effectively turning the DRM_OVERLAY plane into an underlay plane. > > Today, amdgpu attaches an immutable zpos of 0 to the DRM_PRIMARY plane. > This however, is an arbitrary restriction. DCN pipes are general > purpose, and can be arranged in any z-order. To support compositors > using this allocation scheme, we can set a non-zero immutable zpos for > the PRIMARY, allowing the placement of OVERLAYS (mutable zpos range > 0-254) beneath the PRIMARY. > > [How] > > Assign a zpos = #no of OVERLAY planes to the PRIMARY plane. Then, clean > up any assumptions in the driver of PRIMARY plane having the lowest > zpos. > > Signed-off-by: Leo Li With the typo mentioned below fixes this is Reviewed-by: Harry Wentland Before merging we should run a full promotion test (especially the IGT tests) on it as this could break things in subtle ways. Harry > --- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 ++- > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 17 +++- > 2 files changed, 104 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index 09ab330aed17..01b00f587701 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -80,6 +80,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -369,6 +370,20 @@ static inline void reverse_planes_order(struct > dc_surface_update *array_of_surfa > swap(array_of_surface_update[i], array_of_surface_update[j]); > } > > +/* > + * DC will program planes with their z-order determined by their ordering > + * in the dc_surface_updates array. This comparator is used to sort them > + * by descending zpos. > + */ > +static int dm_plane_layer_index_cmp(const void *a, const void *b) > +{ > + const struct dc_surface_update *sa = (struct dc_surface_update *)a; > + const struct dc_surface_update *sb = (struct dc_surface_update *)b; > + > + /* Sort by descending dc_plane layer_index (i.e. normalized_zpos) */ > + return sb->surface->layer_index - sa->surface->layer_index; > +} > + > /** > * update_planes_and_stream_adapter() - Send planes to be updated in DC > * > @@ -393,7 +408,8 @@ static inline bool > update_planes_and_stream_adapter(struct dc *dc, > struct dc_stream_update > *stream_update, > struct dc_surface_update > *array_of_surface_update) > { > - reverse_planes_order(array_of_surface_update, planes_count); > + sort(array_of_surface_update, planes_count, > + sizeof(*array_of_surface_update), dm_plane_layer_index_cmp, NULL); > > /* >* Previous frame finished and HW is ready for optimization. > @@ -9363,6 +9379,8 @@ static void amdgpu_dm_atomic_commit_tail(struct > drm_atomic_state *state) > for (j = 0; j < status->plane_count; j++) > dummy_updates[j].surface = status->plane_states[0]; > > + sort(dummy_updates, status->plane_count, > + sizeof(*dummy_updates), dm_plane_layer_index_cmp, NULL); > > mutex_lock(&dm->dc_lock); > dc_update_planes_and_stream(dm->dc, > @@ -10097,6 +10115,17 @@ static bool should_reset_plane(struct > drm_atomic_state *state, > if (new_crtc_state->color_mgmt_changed) > return true; > > + /* > + * On zpos change, planes need to be reordered by removing and re-adding > + * them one by one to the dc state, in order of descending zpos. > + * > + * TODO: We can likely skip bandwidth validation if the only thing that > + * changed about the plane was it'z z-ordering. > + */ > + if (new_crtc_state->zpos_changed) { > + return true; > + } > + > if (drm_atomic_crtc_needs_modeset(new_crtc_state)) > return true; > > @@ -10509,6 +10538,65 @@ dm_get_plane_scale(struct drm_plane_state > *plane_state, > *out_plane_scale_h = plane_state->crtc_h * 1000 / plane_src_h; > } > >
Re: [PATCH 1/2] drm/amd/display: Introduce overlay cursor mode
On 2024-03-15 13:09, sunpeng...@amd.com wrote: > From: Leo Li > > [Why] > > DCN is the display hardware for amdgpu. DRM planes are backed by DCN > hardware pipes, which carry pixel data from one end (memory), to the > other (output encoder). > > Each DCN pipe has the ability to blend in a cursor early on in the > pipeline. In other words, there are no dedicated cursor planes in DCN, > which makes cursor behavior somewhat unintuitive for compositors. > > For example, if the cursor is in RGB format, but the top-most DRM plane > is in YUV format, DCN will not be able to blend them. Because of this, > amdgpu_dm rejects all configurations where a cursor needs to be enabled > on top of a YUV formatted plane. > > From a compositor's perspective, when computing an allocation for > hardware plane offloading, this cursor-on-yuv configuration result in an > atomic test failure. Since the failure reason is not obvious at all, > compositors will likely fall back to full rendering, which is not ideal. > > Instead, amdgpu_dm can try to accommodate the cursor-on-yuv > configuration by opportunistically reserving a separate DCN pipe just > for the cursor. We can refer to this as "overlay cursor mode". It is > contrasted with "native cursor mode", where the native DCN per-pipe > cursor is used. > > [How] > > On each crtc, compute whether the cursor plane should be enabled in > overlay mode (which currently, is iff the immediate plane below has a > YUV format). If it is, mark the CRTC as requesting overlay cursor mode. > > During DC validation, attempt to enable a separate DCN pipe for the > cursor if it's in overlay mode. If that fails, or if no overlay mode is > requested, then fallback to native mode. > > Signed-off-by: Leo Li We should run this through our usual testing cycle, and I need to go over it a bit more closely than I have, but I like it, so it's Acked-by: Harry Wentland Harry > --- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 309 +++--- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 + > .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 1 + > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 13 +- > 4 files changed, 288 insertions(+), 42 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index 21a61454c878..09ab330aed17 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -8359,8 +8359,19 @@ static void amdgpu_dm_commit_planes(struct > drm_atomic_state *state, >* Disable the cursor first if we're disabling all the planes. >* It'll remain on the screen after the planes are re-enabled >* if we don't. > + * > + * If the cursor is transitioning from native to overlay mode, the > + * native cursor needs to be disabled first. >*/ > - if (acrtc_state->active_planes == 0) > + if (acrtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE && > + dm_old_crtc_state->cursor_mode == DM_CURSOR_NATIVE_MODE) { > + struct dc_cursor_position cursor_position = {0}; > + dc_stream_set_cursor_position(acrtc_state->stream, > + &cursor_position); > + } > + > + if (acrtc_state->active_planes == 0 && > + dm_old_crtc_state->cursor_mode == DM_CURSOR_NATIVE_MODE) > amdgpu_dm_commit_cursors(state); > > /* update planes when needed */ > @@ -8374,7 +8385,8 @@ static void amdgpu_dm_commit_planes(struct > drm_atomic_state *state, > struct dm_plane_state *dm_new_plane_state = > to_dm_plane_state(new_plane_state); > > /* Cursor plane is handled after stream updates */ > - if (plane->type == DRM_PLANE_TYPE_CURSOR) { > + if (plane->type == DRM_PLANE_TYPE_CURSOR && > + acrtc_state->cursor_mode == DM_CURSOR_NATIVE_MODE) { > if ((fb && crtc == pcrtc) || > (old_plane_state->fb && old_plane_state->crtc == > pcrtc)) > cursor_update = true; > @@ -8727,7 +8739,8 @@ static void amdgpu_dm_commit_planes(struct > drm_atomic_state *state, >* This avoids redundant programming in the case where we're going >* to be disabling a single plane - those pipes are being disabled. >*/ > - if (acrtc_state->active_planes) > + if (acrtc_state->active_planes && > + acrtc_state->cursor_m
Re: [PATCH] drm/edid: add 8 bpc quirk to the BenQ GW2765
On 2023-10-12 14:49, Hamza Mahfooz wrote: > The BenQ GW2765 reports that it supports higher (> 8) bpc modes, but > when trying to set them we end up with a black screen. So, limit it to 8 > bpc modes. > > Cc: sta...@vger.kernel.org # 6.5+ > Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2610 > Signed-off-by: Hamza Mahfooz Reviewed-by: Harry Wentland Harry > --- > drivers/gpu/drm/drm_edid.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 0454da505687..bca2af4fe1fc 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -123,6 +123,9 @@ static const struct edid_quirk { > /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */ > EDID_QUIRK('A', 'E', 'O', 0, EDID_QUIRK_FORCE_6BPC), > > + /* BenQ GW2765 */ > + EDID_QUIRK('B', 'N', 'Q', 0x78d6, EDID_QUIRK_FORCE_8BPC), > + > /* BOE model on HP Pavilion 15-n233sl reports 8 bpc, but is a 6 bpc > panel */ > EDID_QUIRK('B', 'O', 'E', 0x78b, EDID_QUIRK_FORCE_6BPC), >
Re: [RFC PATCH 01/10] drm/doc/rfc: Describe why prescriptive color pipeline is needed
On 2023-09-13 07:29, Pekka Paalanen wrote: > On Fri, 8 Sep 2023 11:02:26 -0400 > Harry Wentland wrote: > >> Signed-off-by: Harry Wentland >> Cc: Ville Syrjala >> Cc: Pekka Paalanen >> Cc: Simon Ser >> Cc: Harry Wentland >> Cc: Melissa Wen >> Cc: Jonas Ådahl >> Cc: Sebastian Wick >> Cc: Shashank Sharma >> Cc: Alexander Goins >> Cc: Joshua Ashton >> Cc: Michel Dänzer >> Cc: Aleix Pol >> Cc: Xaver Hugl >> Cc: Victoria Brekenfeld >> Cc: Daniel Vetter >> Cc: Uma Shankar >> Cc: Naseer Ahmed >> Cc: Christopher Braga >> --- >> Documentation/gpu/rfc/color_pipeline.rst | 278 +++ >> 1 file changed, 278 insertions(+) >> create mode 100644 Documentation/gpu/rfc/color_pipeline.rst > > Hi Harry, > > it's really nice to see this! > Thanks for the feedback. I'm just putting a v2 together with comments (partially) addressed. > Sebastian started on the backward/forward compatibility, so I'll > comment on everything else here, and leave the compatibility for that > thread. > >> diff --git a/Documentation/gpu/rfc/color_pipeline.rst >> b/Documentation/gpu/rfc/color_pipeline.rst >> new file mode 100644 >> index ..bfa4a8f12087 >> --- /dev/null >> +++ b/Documentation/gpu/rfc/color_pipeline.rst ... >> +COLOR_PIPELINE Plane Property >> += >> + >> +Because we don't have existing KMS color properties in the pre-blending >> +portion of display pipelines (i.e. on drm_planes) we are introducing >> +color pipelines here first. Eventually we'll want to use the same >> +concept for the post-blending portion, i.e. drm_crtcs. > > This paragraph might fit better in a cover letter. > >> + >> +Color Pipelines are created by a driver and advertised via a new >> +COLOR_PIPELINE enum property on each plane. Values of the property >> +always include '0', which is the default and means all color processing >> +is disabled. Additional values will be the object IDs of the first >> +drm_colorop in a pipeline. A driver can create and advertise none, one, >> +or more possible color pipelines. A DRM client will select a color >> +pipeline by setting the COLOR PIPELINE to the respective value. >> + >> +In the case where drivers have custom support for pre-blending color >> +processing those drivers shall reject atomic commits that are trying to >> +set both the custom color properties, as well as the COLOR_PIPELINE > > s/set/use/ because one of them could be carried-over state from > previous commits while not literally set in this one. > >> +property. >> + >> +An example of a COLOR_PIPELINE property on a plane might look like this:: >> + >> +Plane 10 >> +├─ "type": immutable enum {Overlay, Primary, Cursor} = Primary >> +├─ … >> +└─ "color_pipeline": enum {0, 42, 52} = 0 > > Enum values are string names. I presume the intention here is that the > strings will never need to be parsed, and the uint64_t is always equal > to the string representation, right? > > That needs a statement here. It differs from all previous uses of > enums, and e.g. requires a little bit of new API in libweston's > DRM-backend to handle since it has its own enums referring to the > string names that get mapped to the uint64_t per owning KMS object. > I'm currently putting the DRM object ID in the "value" and use the "name" as a descriptive name. > struct drm_mode_property_enum { > __u64 value; > char name[DRM_PROP_NAME_LEN]; > }; This works well in IGT and gives us a nice descriptive name for debugging, but I could consider changing this if it'd simplify people's lives. >> + >> + >> +Color Pipeline Discovery >> + >> + >> +A DRM client wanting color management on a drm_plane will: >> + >> +1. Read all drm_colorop objects > > What does this do? We probably don't need this, and with it we probably don't need the new IOCTLs. I added this to align with IGT's current init procedure where it reads all DRM core objects, like planes, etc., before using them. But realistically we can just look at the colorop ID from the COLOR_PIPELINE property and then retrieve the other colorops through the NEXT pointer. > >> +2. Get the COLOR_PIPELINE property of the plane >> +3. iterate all COLOR_PIPELINE enum values >> +4. for each enum value walk the color pipeline (via the NEXT pointers) >> + and see if the available color
Re: [RFC PATCH 01/10] drm/doc/rfc: Describe why prescriptive color pipeline is needed
On 2023-10-10 12:13, Melissa Wen wrote: > O 09/08, Harry Wentland wrote: >> Signed-off-by: Harry Wentland >> Cc: Ville Syrjala >> Cc: Pekka Paalanen >> Cc: Simon Ser >> Cc: Harry Wentland >> Cc: Melissa Wen >> Cc: Jonas Ådahl >> Cc: Sebastian Wick >> Cc: Shashank Sharma >> Cc: Alexander Goins >> Cc: Joshua Ashton >> Cc: Michel Dänzer >> Cc: Aleix Pol >> Cc: Xaver Hugl >> Cc: Victoria Brekenfeld >> Cc: Daniel Vetter >> Cc: Uma Shankar >> Cc: Naseer Ahmed >> Cc: Christopher Braga >> --- >> Documentation/gpu/rfc/color_pipeline.rst | 278 +++ >> 1 file changed, 278 insertions(+) >> create mode 100644 Documentation/gpu/rfc/color_pipeline.rst >> >> diff --git a/Documentation/gpu/rfc/color_pipeline.rst >> b/Documentation/gpu/rfc/color_pipeline.rst >> new file mode 100644 >> index ..bfa4a8f12087 >> --- /dev/null >> +++ b/Documentation/gpu/rfc/color_pipeline.rst >> @@ -0,0 +1,278 @@ >> + >> +Linux Color Pipeline API >> + >> + >> +What problem are we solving? >> + >> + >> +We would like to support pre-, and post-blending complex color >> transformations >> +in order to allow for HW-supported HDR use-cases, as well as to provide >> support >> +to color-managed applications, such as video or image editors. >> + >> +While it is possible to support an HDR output on HW supporting the >> Colorspace >> +and HDR Metadata drm_connector properties that requires the compositor or >> +application to render and compose the content into one final buffer >> intended for >> +display. Doing so is costly. >> + >> +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other >> +operations to support color transformations. These operations are often >> +implemented in fixed-function HW and therefore much more power efficient >> than >> +performing similar operations via shaders or CPU. >> + >> +We would like to make use of this HW functionality to support complex color >> +transformations with no, or minimal CPU or shader load. >> + >> + >> +How are other OSes solving this problem? >> + >> + >> +The most widely supported use-cases regard HDR content, whether video or >> +gaming. >> + >> +Most OSes will specify the source content format (color gamut, encoding >> transfer >> +function, and other metadata, such as max and average light levels) to a >> driver. >> +Drivers will then program their fixed-function HW accordingly to map from a >> +source content buffer's space to a display's space. >> + >> +When fixed-function HW is not available the compositor will assemble a >> shader to >> +ask the GPU to perform the transformation from the source content format to >> the >> +display's format. >> + >> +A compositor's mapping function and a driver's mapping function are usually >> +entirely separate concepts. On OSes where a HW vendor has no insight into >> +closed-source compositor code such a vendor will tune their color management >> +code to visually match the compositor's. On other OSes, where both mapping >> +functions are open to an implementer they will ensure both mappings match. >> + >> + >> +Why is Linux different? >> +=== >> + >> +Unlike other OSes, where there is one compositor for one or more drivers, on >> +Linux we have a many-to-many relationship. Many compositors; many drivers. >> +In addition each compositor vendor or community has their own view of how >> +color management should be done. This is what makes Linux so beautiful. >> + >> +This means that a HW vendor can now no longer tune their driver to one >> +compositor, as tuning it to one will almost inevitably make it look very >> +different from another compositor's color mapping. >> + >> +We need a better solution. >> + >> + >> +Descriptive API >> +=== >> + >> +An API that describes the source and destination colorspaces is a >> descriptive >> +API. It describes the input and output color spaces but does not describe >> +how precisely they should be mapped. Such a mapping includes many minute >> +design decision that can greatly affect the look of the final result. >> + >> +It is not feasible to describe such mapping with enough detail to ensur
Re: [RFC PATCH 02/10] drm/colorop: Introduce new drm_colorop mode object
On 2023-10-10 12:19, Melissa Wen wrote: > On 09/08, 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. >> >> Signed-off-by: Harry Wentland >> Cc: Ville Syrjala >> Cc: Pekka Paalanen >> Cc: Simon Ser >> Cc: Harry Wentland >> Cc: Melissa Wen >> Cc: Jonas Ådahl >> Cc: Sebastian Wick >> Cc: Shashank Sharma >> Cc: Alexander Goins >> Cc: Joshua Ashton >> Cc: Michel Dänzer >> Cc: Aleix Pol >> Cc: Xaver Hugl >> Cc: Victoria Brekenfeld >> Cc: Daniel Vetter >> Cc: Uma Shankar >> Cc: Naseer Ahmed >> Cc: Christopher Braga >> --- >> drivers/gpu/drm/Makefile| 1 + >> drivers/gpu/drm/drm_atomic.c| 79 + >> drivers/gpu/drm/drm_atomic_helper.c | 12 ++ >> drivers/gpu/drm/drm_atomic_uapi.c | 48 >> drivers/gpu/drm/drm_colorop.c | 169 >> drivers/gpu/drm/drm_mode_config.c | 7 ++ >> drivers/gpu/drm/drm_plane_helper.c | 2 +- >> include/drm/drm_atomic.h| 82 ++ >> include/drm/drm_atomic_uapi.h | 1 + >> include/drm/drm_colorop.h | 157 ++ >> include/drm/drm_mode_config.h | 18 +++ >> include/drm/drm_plane.h | 2 + >> include/uapi/drm/drm.h | 3 + >> include/uapi/drm/drm_mode.h | 1 + >> 14 files changed, 581 insertions(+), 1 deletion(-) >> 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 1855863b4d7a..941de0269709 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 11f3a130f6f4..d734e9d5bfed 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; >> >> state->dev = dev; >> >> @@ -244,6 +250,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; >> >> @@ -562,6 +582,65 @@ drm_atomic_get_plane_state(struct drm_atomic_state >> *state, >> } >> EXPORT_SYMBOL(drm_atomic_get_plane_state); >> >&
Re: [RFC PATCH 10/10] drm/vkms: Add enumerated 1D curve colorop
On 2023-10-10 12:27, Melissa Wen wrote: > On 09/08, Harry Wentland wrote: >> Signed-off-by: Harry Wentland >> Cc: Ville Syrjala >> Cc: Pekka Paalanen >> Cc: Simon Ser >> Cc: Harry Wentland >> Cc: Melissa Wen >> Cc: Jonas Ådahl >> Cc: Sebastian Wick >> Cc: Shashank Sharma >> Cc: Alexander Goins >> Cc: Joshua Ashton >> Cc: Michel Dänzer >> Cc: Aleix Pol >> Cc: Xaver Hugl >> Cc: Victoria Brekenfeld >> Cc: Daniel Vetter >> Cc: Uma Shankar >> Cc: Naseer Ahmed >> Cc: Christopher Braga >> --- >> drivers/gpu/drm/vkms/Makefile| 3 +- >> drivers/gpu/drm/vkms/vkms_colorop.c | 108 + >> drivers/gpu/drm/vkms/vkms_composer.c | 316 +++ >> drivers/gpu/drm/vkms/vkms_drv.h | 4 + >> drivers/gpu/drm/vkms/vkms_plane.c| 2 + >> 5 files changed, 432 insertions(+), 1 deletion(-) >> create mode 100644 drivers/gpu/drm/vkms/vkms_colorop.c >> >> diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile >> index 1b28a6a32948..bcf508873622 100644 >> --- a/drivers/gpu/drm/vkms/Makefile >> +++ b/drivers/gpu/drm/vkms/Makefile >> @@ -6,6 +6,7 @@ vkms-y := \ >> vkms_formats.o \ >> vkms_crtc.o \ >> vkms_composer.o \ >> -vkms_writeback.o >> +vkms_writeback.o \ >> +vkms_colorop.o >> >> obj-$(CONFIG_DRM_VKMS) += vkms.o >> diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c >> b/drivers/gpu/drm/vkms/vkms_colorop.c >> new file mode 100644 >> index ..b3da0705bca7 >> --- /dev/null >> +++ b/drivers/gpu/drm/vkms/vkms_colorop.c >> @@ -0,0 +1,108 @@ >> +/* >> + * Copyright (C) 2023 Advanced Micro Devices, Inc. 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, sublicense, >> + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL >> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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: AMD >> + * >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define MAX_COLOR_PIPELINES 5 >> + >> +const int vkms_initialize_tf_pipeline(struct drm_plane *plane, struct >> drm_prop_enum_list *list) >> +{ >> + >> +struct drm_colorop *op, *prev_op; >> +struct drm_device *dev = plane->dev; >> +int ret; >> + >> +/* 1st op: 1d curve */ >> +op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); >> +if (!op) { >> +DRM_ERROR("KMS: Failed to allocate colorop\n"); >> +return -ENOMEM; >> +} >> + >> +ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); >> +if (ret) >> +return ret; >> + >> +list->type = op->base.id; >> +list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", op->base.id); >> + >> +prev_op = op; >> + >> +/* 2nd op: 1d curve */ >> +op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); >> +if (!op) { >> +DRM_ERROR("KMS: Failed to allocate colorop\n"); >> +return -ENOMEM; >> +} >> + >> +ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); >> +if (ret) >> +return ret; >> + >> +drm_colorop_set_next_property(prev_op, op); >> + >> +return 0; >> +} >> + >> +int vkms_initialize_colorops(struct drm_plane *plane)
[RFC PATCH v2 00/17] Color Pipeline API w/ VKMS
This is an early 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 we have an IGT test that confirms that sRGB EOTF, followed by its inverse gives us expected results within +/- 1 8 bpc codepoint value. This patchset is grouped as follows: - Patches 1-2: couple general patches/fixes - Patches 3-5: introduce kunit to VKMS - Patch 6: 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-15: Add core DRM API bits - Patches 15-17: VKMS implementation 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: - Abandon IOCTLs and discover colorops as clients iterate the pipeline - Add color_pipeline client cap and deprecate existing color encoding and color range properties. See https://lists.freedesktop.org/archives/dri-devel/2023-September/422643.html - Add CTM colorop to VKMS - Add custom LUT colorops to VKMS - Add pre-blending 3DLUT with tetrahedral interpolation to VKMS - 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)? 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. libdrm changes to support the new IOCTLs are at https://gitlab.freedesktop.org/hwentland/drm/-/merge_requests/1 If you prefer a gitlab MR for review you can find it at https://gitlab.freedesktop.org/hwentland/linux/-/merge_requests/5 A slightly different approach for a Color Pipeline API was sent by Uma Shankar and can be found at https://patchwork.freedesktop.org/series/123024/ The main difference is that his approach is not introducing a new DRM core object but instead exposes color pipelines via blob properties. There are pros and cons to both approaches. v2: - Rebased on drm-misc-next - Introduce a VKMS Kunit so we can test LUT functionality in vkms_composer - Incorporate feedback in color_pipeline.rst doc - Add support for sRGB inverse EOTF - Add 2nd enumerated TF colorop to VKMS - Fix LUTs and some issues with applying LUTs in VKMS Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh Harry Wentland (17): drm/atomic: Allow get_value for immutable properties on atomic drivers drm: Don't treat 0 as -1 in drm_fixp2int_ceil drm/vkms: Create separate Kconfig file for VKMS drm/vkms: Add kunit tests for VKMS LUT handling drm/vkms: Avoid reading beyond LUT array drm/doc/rfc: Describe why prescriptive color pipeline is needed drm/colorop: Introduce new drm_colorop mode object drm/colorop: Add TYPE property drm/color: Add 1D Curve subtype drm/colorop: Add BYPASS property drm/colorop: Add NEXT property drm/colorop: Add atomic state print for drm_colorop drm/colorop: Add new IOCTLs to retrieve drm_colorop objects drm/plane: Add COLOR PIPELINE property drm/colorop: Add NEXT to colorop state print drm/vkms: Add enumerated 1D curve colorop drm/vkms: Add kunit tests for linear and sRGB LUTs Documentation/gpu/rfc/color_pipeline.rst | 347 drivers/gpu/drm/Kconfig | 14 +- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_atomic.c | 155 drivers/gpu/drm/drm_atomic_helper.c | 12 + drivers/gpu/drm/drm_atomic_state_helper.c | 5 + drivers/gpu/drm/drm_atomic_uapi.c | 110 +++ drivers/gpu/drm/drm_colorop.c | 384 + drivers/gpu/drm/drm_crtc_internal.h | 4 + drivers/gpu/drm/drm_ioctl.c | 5 + drivers/gpu/drm/drm_mode_config.c | 7 + drivers/gpu/drm/drm_mode_object.c | 3 +- drivers/gpu/drm/drm_plane_helper.c| 2 +- drivers/gpu/drm/vkms/Kconfig | 20 + drivers/gpu/drm/vkms/Makefile | 6 +- drivers/gpu/drm/vkms/tests/.kunitconfig | 4 + drivers/gpu/drm/vkms/tests/Makefile | 4 + drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 100 +++ drivers/gpu/drm/vkms/vkms_colorop.c | 85 ++ drivers/gpu/drm/vkms/vkms_composer.c | 77 +- drivers/gpu/drm/vkms/vkms_composer.h | 25 + drivers/gpu/drm/vkms/vkms_
[RFC PATCH v2 03/17] drm/vkms: Create separate Kconfig file for VKMS
This aligns with most other DRM drivers and will allow us to add new VKMS config options without polluting the DRM Kconfig. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/Kconfig | 14 +- drivers/gpu/drm/vkms/Kconfig | 15 +++ 2 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 drivers/gpu/drm/vkms/Kconfig diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 48ca28a2e4ff..61ebd682c9b0 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -286,19 +286,7 @@ config DRM_VGEM as used by Mesa's software renderer for enhanced performance. If M is selected the module will be called vgem. -config DRM_VKMS - tristate "Virtual KMS (EXPERIMENTAL)" - depends on DRM && MMU - select DRM_KMS_HELPER - select DRM_GEM_SHMEM_HELPER - select CRC32 - default n - help - Virtual Kernel Mode-Setting (VKMS) is used for testing or for - running GPU in a headless machines. Choose this option to get - a VKMS. - - If M is selected the module will be called vkms. +source "drivers/gpu/drm/vkms/Kconfig" source "drivers/gpu/drm/exynos/Kconfig" diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig new file mode 100644 index ..1816562381a2 --- /dev/null +++ b/drivers/gpu/drm/vkms/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0+ + +config DRM_VKMS + tristate "Virtual KMS (EXPERIMENTAL)" + depends on DRM && MMU + select DRM_KMS_HELPER + select DRM_GEM_SHMEM_HELPER + select CRC32 + default n + help + Virtual Kernel Mode-Setting (VKMS) is used for testing or for + running GPU in a headless machines. Choose this option to get + a VKMS. + + If M is selected the module will be called vkms. -- 2.42.0
[RFC PATCH v2 02/17] drm: Don't treat 0 as -1 in drm_fixp2int_ceil
Unit testing this in VKMS shows that passing 0 into this function returns -1, which is highly counter- intuitive. Fix it by checking whether the input is >= 0 instead of > 0. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- include/drm/drm_fixed.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h index 6ea339d5de08..0c9f917a4d4b 100644 --- a/include/drm/drm_fixed.h +++ b/include/drm/drm_fixed.h @@ -95,7 +95,7 @@ static inline int drm_fixp2int_round(s64 a) static inline int drm_fixp2int_ceil(s64 a) { - if (a > 0) + if (a >= 0) return drm_fixp2int(a + DRM_FIXED_ALMOST_ONE); else return drm_fixp2int(a - DRM_FIXED_ALMOST_ONE); -- 2.42.0
[RFC PATCH v2 01/17] drm/atomic: Allow get_value for immutable properties on atomic drivers
drm_colorops use immutable properties, for type and next. Even though drivers create these properties at initialization they will need to look at the properties when parsing a color pipeline for programming during an atomic check or commit operation. This aligns the get_value call with behavior of the set_value call. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_mode_object.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index ac0d2ce3f870..c9b1cd48547a 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -351,7 +351,8 @@ static int __drm_object_property_get_value(struct drm_mode_object *obj, int drm_object_property_get_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t *val) { - WARN_ON(drm_drv_uses_atomic_modeset(property->dev)); + WARN_ON(drm_drv_uses_atomic_modeset(property->dev) && + !(property->flags & DRM_MODE_PROP_IMMUTABLE)); return __drm_object_property_get_value(obj, property, val); } -- 2.42.0
[RFC PATCH v2 08/17] drm/colorop: Add TYPE property
Add a read-only TYPE property. The TYPE specifies the colorop type, such as enumerated curve, 1D LUT, CTM, 3D LUT, PWL LUT, etc. For now we're only introducing an enumerated 1D LUT type to illustrate the concept. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_atomic.c | 4 +-- drivers/gpu/drm/drm_atomic_uapi.c | 8 +- drivers/gpu/drm/drm_colorop.c | 43 ++- include/drm/drm_colorop.h | 21 ++- 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index d55db5a06940..524bec520287 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -636,8 +636,8 @@ drm_atomic_get_colorop_state(struct drm_atomic_state *state, state->colorops[index].new_state = colorop_state; colorop_state->state = state; - drm_dbg_atomic(colorop->dev, "Added [COLOROP:%d] %p state to %p\n", - colorop->base.id, colorop_state, state); + drm_dbg_atomic(colorop->dev, "Added [COLOROP:%d:%d] %p state to %p\n", + colorop->base.id, colorop->type, colorop_state, state); /* TODO is this necessary? */ diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 21da1b327ee9..f22bd8671236 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -682,7 +682,13 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, const struct drm_colorop_state *state, struct drm_property *property, uint64_t *val) { - return -EINVAL; + if (property == colorop->type_property) { + *val = colorop->type; + } else { + return -EINVAL; + } + + return 0; } static int drm_atomic_set_writeback_fb_for_connector( diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 78d6a0067f5b..33e7dbf4dbe4 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -32,12 +32,17 @@ /* TODO big colorop doc, including properties, etc. */ +static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { + { DRM_COLOROP_1D_CURVE, "1D Curve" }, +}; + /* Init Helpers */ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, -struct drm_plane *plane) +struct drm_plane *plane, enum drm_colorop_type type) { struct drm_mode_config *config = &dev->mode_config; + struct drm_property *prop; int ret = 0; ret = drm_mode_object_add(dev, &colorop->base, DRM_MODE_OBJECT_COLOROP); @@ -46,12 +51,28 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->base.properties = &colorop->properties; colorop->dev = dev; + colorop->type = type; colorop->plane = plane; list_add_tail(&colorop->head, &config->colorop_list); colorop->index = config->num_colorop++; /* add properties */ + + /* type */ + prop = drm_property_create_enum(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ATOMIC, + "TYPE", drm_colorop_type_enum_list, + ARRAY_SIZE(drm_colorop_type_enum_list)); + if (!prop) + return -ENOMEM; + + colorop->type_property = prop; + + drm_object_attach_property(&colorop->base, + colorop->type_property, + colorop->type); + return ret; } EXPORT_SYMBOL(drm_colorop_init); @@ -167,3 +188,23 @@ void drm_colorop_reset(struct drm_colorop *colorop) __drm_colorop_reset(colorop, colorop->state); } EXPORT_SYMBOL(drm_colorop_reset); + + +static const char * const colorop_type_name[] = { + [DRM_COLOROP_1D_CURVE] = "1D Curve", +}; + +/** + * drm_get_colorop_type_name - return a string for colorop type + * @range: colorop type to compute name of + * + * In contrast to the other drm_get_*_name functions this one here returns a + * const pointer and hence is threadsafe. + */ +const char *drm_get_colorop_type_name(enum drm_colorop_type type) +{ + if (WARN_ON(type >= ARRAY_SIZE(colorop_type_name))) + return "unknown"; +
[RFC PATCH v2 05/17] drm/vkms: Avoid reading beyond LUT array
When the floor LUT index (drm_fixp2int(lut_index) is the last index of the array the ceil LUT index will point to an entry beyond the array. Make sure we guard against it and use the value of the floot LUT index. Blurb about LUT creation and how first element should be 0x0 and last one 0x. Hold on, is that even correct? What should the ends of a LUT be? How does UNORM work and how does it apply to LUTs? Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/vkms/vkms_composer.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index a0a3a6fd2926..cf1dff162920 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -123,6 +123,8 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan enum lut_channel channel) { s64 lut_index = get_lut_index(lut, channel_value); + u16 *floor_lut_value, *ceil_lut_value; + u16 floor_channel_value, ceil_channel_value; /* * This checks if `struct drm_color_lut` has any gap added by the compiler @@ -130,11 +132,15 @@ static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 chan */ static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4); - u16 *floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)]; - u16 *ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)]; + floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)]; + if (drm_fixp2int(lut_index) == (lut->lut_length - 1)) + /* We're at the end of the LUT array, use same value for ceil and floor */ + ceil_lut_value = floor_lut_value; + else + ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)]; - u16 floor_channel_value = floor_lut_value[channel]; - u16 ceil_channel_value = ceil_lut_value[channel]; + floor_channel_value = floor_lut_value[channel]; + ceil_channel_value = ceil_lut_value[channel]; return lerp_u16(floor_channel_value, ceil_channel_value, lut_index & DRM_FIXED_DECIMAL_MASK); -- 2.42.0
[RFC PATCH v2 07/17] drm/colorop: Introduce new drm_colorop mode object
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. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/Makefile| 1 + drivers/gpu/drm/drm_atomic.c| 79 + drivers/gpu/drm/drm_atomic_helper.c | 12 ++ drivers/gpu/drm/drm_atomic_uapi.c | 48 drivers/gpu/drm/drm_colorop.c | 169 drivers/gpu/drm/drm_mode_config.c | 7 ++ drivers/gpu/drm/drm_plane_helper.c | 2 +- include/drm/drm_atomic.h| 82 ++ include/drm/drm_atomic_uapi.h | 1 + include/drm/drm_colorop.h | 157 ++ include/drm/drm_mode_config.h | 18 +++ include/drm/drm_plane.h | 2 + include/uapi/drm/drm.h | 3 + include/uapi/drm/drm_mode.h | 1 + 14 files changed, 581 insertions(+), 1 deletion(-) 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 8e1bde059170..7ba67f9775e7 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 f1a503aafe5a..d55db5a06940 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,65 @@ 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; + struct drm_
[RFC PATCH v2 04/17] drm/vkms: Add kunit tests for VKMS LUT handling
Debugging LUT math is much easier when we can unit test it. Add kunit functionality to VKMS and add tests for - get_lut_index - lerp_u16 Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/vkms/Kconfig | 5 ++ drivers/gpu/drm/vkms/Makefile | 2 + drivers/gpu/drm/vkms/tests/.kunitconfig | 4 ++ drivers/gpu/drm/vkms/tests/Makefile | 4 ++ drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 64 +++ drivers/gpu/drm/vkms/vkms_composer.c | 4 +- drivers/gpu/drm/vkms/vkms_composer.h | 11 7 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/vkms/tests/.kunitconfig create mode 100644 drivers/gpu/drm/vkms/tests/Makefile create mode 100644 drivers/gpu/drm/vkms/tests/vkms_color_tests.c create mode 100644 drivers/gpu/drm/vkms/vkms_composer.h diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index 1816562381a2..372cc5fa92f1 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -13,3 +13,8 @@ config DRM_VKMS a VKMS. If M is selected the module will be called vkms. + +config DRM_VKMS_KUNIT_TESTS + tristate "Tests for VKMS" if !KUNIT_ALL_TESTS + depends on DRM_VKMS && KUNIT + default KUNIT_ALL_TESTS diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index 1b28a6a32948..d3440f228f46 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -9,3 +9,5 @@ vkms-y := \ vkms_writeback.o obj-$(CONFIG_DRM_VKMS) += vkms.o + +obj-y += tests/ \ No newline at end of file diff --git a/drivers/gpu/drm/vkms/tests/.kunitconfig b/drivers/gpu/drm/vkms/tests/.kunitconfig new file mode 100644 index ..70e378228cbd --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/.kunitconfig @@ -0,0 +1,4 @@ +CONFIG_KUNIT=y +CONFIG_DRM=y +CONFIG_DRM_VKMS=y +CONFIG_DRM_VKMS_KUNIT_TESTS=y diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile new file mode 100644 index ..761465332ff2 --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_DRM_VKMS_KUNIT_TESTS) += \ + vkms_color_tests.o \ No newline at end of file diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c new file mode 100644 index ..843b2e1d607e --- /dev/null +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#include + +#include + +#include "../vkms_composer.h" + +#define TEST_LUT_SIZE 16 + +static struct drm_color_lut test_linear_array[TEST_LUT_SIZE] = { + { 0x0, 0x0, 0x0, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, + { 0x, 0x, 0x, 0 }, +}; + +const struct vkms_color_lut test_linear_lut = { + .base = test_linear_array, + .lut_length = TEST_LUT_SIZE, + .channel_value2index_ratio = 0xf000fll +}; + + +static void vkms_color_test_get_lut_index(struct kunit *test) +{ + int i; + + KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&test_linear_lut, test_linear_array[0].red)), 0); + + for (i = 0; i < TEST_LUT_SIZE; i++) + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&test_linear_lut, test_linear_array[i].red)), i); +} + +static void vkms_color_test_lerp(struct kunit *test) +{ + KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, 0x8000), 0x8); +} + +static struct kunit_case vkms_color_test_cases[] = { + KUNIT_CASE(vkms_color_test_get_lut_index), + KUNIT_CASE(vkms_color_test_lerp), + {} +}; + +static struct kunit_suite vkms_color_test_suite = { + .name = "vkms-color", + .test_cases = vkms_color_test_cases, +}; +kunit_test_suite(vkms_color_test_suite); + +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.
[RFC PATCH v2 06/17] drm/doc/rfc: Describe why prescriptive color pipeline is needed
v2: - Update colorop visualizations to match reality (Sebastian, Alex Hung) - Updated wording (Pekka) - Change BYPASS wording to make it non-mandatory (Sebastian) - Drop cover-letter-like paragraph from COLOR_PIPELINE Plane Property section (Pekka) - Use PQ EOTF instead of its inverse in Pipeline Programming example (Melissa) - Add "Driver Implementer's Guide" section (Pekka) - Add "Driver Forward/Backward Compatibility" section (Sebastian, Pekka) Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- Documentation/gpu/rfc/color_pipeline.rst | 347 +++ 1 file changed, 347 insertions(+) create mode 100644 Documentation/gpu/rfc/color_pipeline.rst diff --git a/Documentation/gpu/rfc/color_pipeline.rst b/Documentation/gpu/rfc/color_pipeline.rst new file mode 100644 index ..af5f2ea29116 --- /dev/null +++ b/Documentation/gpu/rfc/color_pipeline.rst @@ -0,0 +1,347 @@ + +Linux Color Pipeline API + + +What problem are we solving? + + +We would like to support pre-, and post-blending complex color +transformations in display controller hardware in order to allow for +HW-supported HDR use-cases, as well as to provide support to +color-managed applications, such as video or image editors. + +It is possible to support an HDR output on HW supporting the Colorspace +and HDR Metadata drm_connector properties, but that requires the +compositor or application to render and compose the content into one +final buffer intended for display. Doing so is costly. + +Most modern display HW offers various 1D LUTs, 3D LUTs, matrices, and other +operations to support color transformations. These operations are often +implemented in fixed-function HW and therefore much more power efficient than +performing similar operations via shaders or CPU. + +We would like to make use of this HW functionality to support complex color +transformations with no, or minimal CPU or shader load. + + +How are other OSes solving this problem? + + +The most widely supported use-cases regard HDR content, whether video or +gaming. + +Most OSes will specify the source content format (color gamut, encoding transfer +function, and other metadata, such as max and average light levels) to a driver. +Drivers will then program their fixed-function HW accordingly to map from a +source content buffer's space to a display's space. + +When fixed-function HW is not available the compositor will assemble a shader to +ask the GPU to perform the transformation from the source content format to the +display's format. + +A compositor's mapping function and a driver's mapping function are usually +entirely separate concepts. On OSes where a HW vendor has no insight into +closed-source compositor code such a vendor will tune their color management +code to visually match the compositor's. On other OSes, where both mapping +functions are open to an implementer they will ensure both mappings match. + +This results in mapping algorithm lock-in, meaning that no-one alone can +experiment with or introduce new mapping algorithms and achieve +consistent results regardless of which implementation path is taken. + +Why is Linux different? +=== + +Unlike other OSes, where there is one compositor for one or more drivers, on +Linux we have a many-to-many relationship. Many compositors; many drivers. +In addition each compositor vendor or community has their own view of how +color management should be done. This is what makes Linux so beautiful. + +This means that a HW vendor can now no longer tune their driver to one +compositor, as tuning it to one could make it look fairly different from +another compositor's color mapping. + +We need a better solution. + + +Descriptive API +=== + +An API that describes the source and destination colorspaces is a descriptive +API. It describes the input and output color spaces but does not describe +how precisely they should be mapped. Such a mapping includes many minute +design decision that can greatly affect the look of the final result. + +It is not feasible to describe such mapping with enough detail to ensure the +same result from each implementation. In fact, these mappings are a very active +research area. + + +Prescriptive API + + +A prescriptive API describes not the source and destination colorspaces. It +instead prescribes a recipe for how to manipulate pixel values to ar
[RFC PATCH v2 09/17] drm/color: Add 1D Curve subtype
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_atomic_uapi.c | 18 ++ drivers/gpu/drm/drm_colorop.c | 39 +++ include/drm/drm_colorop.h | 20 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index f22bd8671236..52b9b48e5757 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -670,11 +670,17 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, struct drm_colorop_state *state, struct drm_file *file_priv, struct drm_property *property, uint64_t val) { - drm_dbg_atomic(colorop->dev, - "[COLOROP:%d] unknown property [PROP:%d:%s]]\n", - colorop->base.id, - property->base.id, property->name); - return -EINVAL; + if (property == colorop->curve_1d_type_property) { + state->curve_1d_type = val; + } else { + drm_dbg_atomic(colorop->dev, + "[COLOROP:%d:%d] unknown property [PROP:%d:%s]]\n", + colorop->base.id, colorop->type, + property->base.id, property->name); + return -EINVAL; + } + + return 0; } static int @@ -684,6 +690,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, { if (property == colorop->type_property) { *val = colorop->type; + } else if (property == colorop->curve_1d_type_property) { + *val = state->curve_1d_type; } else { return -EINVAL; } diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 33e7dbf4dbe4..8d8f9461950f 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -36,6 +36,11 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { { DRM_COLOROP_1D_CURVE, "1D Curve" }, }; +static const struct drm_prop_enum_list drm_colorop_curve_1d_type_enum_list[] = { + { DRM_COLOROP_1D_CURVE_SRGB_EOTF, "sRGB EOTF" }, + { DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF, "sRGB Inverse EOTF" }, +}; + /* Init Helpers */ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, @@ -73,6 +78,20 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->type_property, colorop->type); + /* curve_1d_type */ + /* TODO move to mode_config? */ + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, + "CURVE_1D_TYPE", + drm_colorop_curve_1d_type_enum_list, + ARRAY_SIZE(drm_colorop_curve_1d_type_enum_list)); + if (!prop) + return -ENOMEM; + + colorop->curve_1d_type_property = prop; + drm_object_attach_property(&colorop->base, + colorop->curve_1d_type_property, + 0); + return ret; } EXPORT_SYMBOL(drm_colorop_init); @@ -194,6 +213,11 @@ static const char * const colorop_type_name[] = { [DRM_COLOROP_1D_CURVE] = "1D Curve", }; +static const char * const colorop_curve_1d_type_name[] = { + [DRM_COLOROP_1D_CURVE_SRGB_EOTF] = "sRGB EOTF", + [DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF] = "sRGB Inverse EOTF", +}; + /** * drm_get_colorop_type_name - return a string for colorop type * @range: colorop type to compute name of @@ -208,3 +232,18 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type type) return colorop_type_name[type]; } + +/** + * drm_get_colorop_curve_1d_type_name - return a string for 1D curve type + * @range: 1d curve type to compute name of + * + * In contrast to the other drm_get_*_name functions this one here returns a + * const pointer and hence is threadsafe. + */ +const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type) +{ + if (WARN_ON(type >= ARRAY_SIZE(colorop_curve_1d_type_name))) + return "unknown"; + + return colorop_curve_1d_type_name[type]; +} diff --git a/include/drm/drm_colorop.h b/inc
[RFC PATCH v2 10/17] drm/colorop: Add BYPASS property
We want to be able to bypass each colorop at all times. Introduce a new BYPASS boolean property for this. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_atomic_uapi.c | 6 +- drivers/gpu/drm/drm_colorop.c | 15 +++ include/drm/drm_colorop.h | 20 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 52b9b48e5757..a8f7a8a6639a 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -670,7 +670,9 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop, struct drm_colorop_state *state, struct drm_file *file_priv, struct drm_property *property, uint64_t val) { - if (property == colorop->curve_1d_type_property) { + if (property == colorop->bypass_property) { + state->bypass = val; + } else if (property == colorop->curve_1d_type_property) { state->curve_1d_type = val; } else { drm_dbg_atomic(colorop->dev, @@ -690,6 +692,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop, { if (property == colorop->type_property) { *val = colorop->type; + } else if (property == colorop->bypass_property) { + *val = state->bypass; } else if (property == colorop->curve_1d_type_property) { *val = state->curve_1d_type; } else { diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 8d8f9461950f..ff6331fe5d5e 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -78,6 +78,18 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->type_property, colorop->type); + /* bypass */ + /* TODO can we reuse the mode_config->active_prop? */ + prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC, + "BYPASS"); + if (!prop) + return -ENOMEM; + + colorop->bypass_property = prop; + drm_object_attach_property(&colorop->base, + colorop->bypass_property, + 1); + /* curve_1d_type */ /* TODO move to mode_config? */ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, @@ -100,6 +112,8 @@ void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop, struct drm_colorop_state *state) { memcpy(state, colorop->state, sizeof(*state)); + + state->bypass = true; } struct drm_colorop_state * @@ -164,6 +178,7 @@ void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state, struct drm_colorop *colorop) { colorop_state->colorop = colorop; + colorop_state->bypass = true; } EXPORT_SYMBOL(__drm_colorop_state_reset); diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 7701b61ff7e9..69636f6752a0 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -48,6 +48,14 @@ struct drm_colorop_state { /* colorop properties */ + /** +* @bypass: +* +* True if colorop shall be bypassed. False if colorop is +* enabled. +*/ + bool bypass; + /** * @curve_1d_type: * @@ -135,6 +143,18 @@ struct drm_colorop { */ struct drm_property *type_property; + /** +* @bypass_property: +* +* Boolean property to control enablement of the color +* operation. Setting bypass to "true" shall always be supported +* in order to allow compositors to quickly fall back to +* alternate methods of color processing. This is important +* since setting color operations can fail due to unique +* HW constraints. +*/ + struct drm_property *bypass_property; + /** * @curve_1d_type: * -- 2.42.0
[RFC PATCH v2 11/17] drm/colorop: Add NEXT property
We'll construct color pipelines out of drm_colorop by chaining them via the NEXT pointer. NEXT will point to the next drm_colorop in the pipeline, or by 0 if we're at the end of the pipeline. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_colorop.c | 27 +++ include/drm/drm_colorop.h | 12 2 files changed, 39 insertions(+) diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index ff6331fe5d5e..bc1250718baf 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -104,6 +104,15 @@ int drm_colorop_init(struct drm_device *dev, struct drm_colorop *colorop, colorop->curve_1d_type_property, 0); + prop = drm_property_create_object(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ATOMIC, + "NEXT", DRM_MODE_OBJECT_COLOROP); + if (!prop) + return -ENOMEM; + colorop->next_property = prop; + drm_object_attach_property(&colorop->base, + colorop->next_property, + 0); + return ret; } EXPORT_SYMBOL(drm_colorop_init); @@ -262,3 +271,21 @@ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type ty return colorop_curve_1d_type_name[type]; } + +/** + * drm_colorop_set_next_property - sets the next pointer + * @colorop: drm colorop + * @next: next colorop + * + * Should be used when constructing the color pipeline + */ +void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next) +{ + if (!colorop->next_property) + return; + + drm_object_property_set_value(&colorop->base, + colorop->next_property, + next->base.id); +} +EXPORT_SYMBOL(drm_colorop_set_next_property); diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 69636f6752a0..1ddd0e65fe36 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -162,10 +162,20 @@ struct drm_colorop { */ struct drm_property *curve_1d_type_property; + /** +* @next_property +* +* Read-only property to next colorop in the pipeline +*/ + struct drm_property *next_property; + }; #define obj_to_colorop(x) container_of(x, struct drm_colorop, base) + + + /** * drm_crtc_find - look up a Colorop object from its ID * @dev: DRM device @@ -212,5 +222,7 @@ static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) #define drm_for_each_colorop(colorop, dev) \ list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head) +void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); + #endif /* __DRM_COLOROP_H__ */ -- 2.42.0
[RFC PATCH v2 13/17] drm/colorop: Add new IOCTLs to retrieve drm_colorop objects
Since we created a new DRM object we need new IOCTLs (and new libdrm functions) to retrieve those objects. TODO: Can we make these IOCTLs and libdrm functions generic to allow for new DRM objects in the future without the need for new IOCTLs and libdrm functions? Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_colorop.c | 51 + drivers/gpu/drm/drm_crtc_internal.h | 4 +++ drivers/gpu/drm/drm_ioctl.c | 5 +++ include/uapi/drm/drm_mode.h | 21 4 files changed, 81 insertions(+) diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index bc1250718baf..1afd5fbe8776 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -32,6 +32,57 @@ /* TODO big colorop doc, including properties, etc. */ +/* IOCTLs */ + +int drm_mode_getcolorop_res(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_mode_get_colorop_res *colorop_resp = data; + struct drm_colorop *colorop; + uint32_t __user *colorop_ptr; + int count = 0; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EOPNOTSUPP; + + colorop_ptr = u64_to_user_ptr(colorop_resp->colorop_id_ptr); + + /* +* This ioctl is called twice, once to determine how much space is +* needed, and the 2nd time to fill it. +*/ + drm_for_each_colorop(colorop, dev) { + if (drm_lease_held(file_priv, colorop->base.id)) { + if (count < colorop_resp->count_colorops && + put_user(colorop->base.id, colorop_ptr + count)) + return -EFAULT; + count++; + } + } + colorop_resp->count_colorops = count; + + return 0; +} + +int drm_mode_getcolorop(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_mode_get_colorop *colorop_resp = data; + struct drm_colorop *colorop; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EOPNOTSUPP; + + colorop = drm_colorop_find(dev, file_priv, colorop_resp->colorop_id); + if (!colorop) + return -ENOENT; + + colorop_resp->colorop_id = colorop->base.id; + colorop_resp->plane_id = colorop->plane ? colorop->plane->base.id : 0; + + return 0; +} + static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = { { DRM_COLOROP_1D_CURVE, "1D Curve" }, }; diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 8556c3b3ff88..252cd7e607e3 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -278,6 +278,10 @@ int drm_mode_getplane(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_file *file_priv); +int drm_mode_getcolorop_res(struct drm_device *dev, void *data, + struct drm_file *file_priv); +int drm_mode_getcolorop(struct drm_device *dev, void *data, + struct drm_file *file_priv); int drm_mode_cursor_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_mode_cursor2_ioctl(struct drm_device *dev, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 77590b0f38fa..8a4b7d8d8a0b 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -717,6 +717,11 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCOLOROPRESOURCES, drm_mode_getcolorop_res, 0), + /* TODO do we need GETCOLOROP? */ + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCOLOROP, drm_mode_getcolorop, 0), + }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE(drm_ioctls) diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 009a800676ac..5c71eb011181 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -357,6 +357,27 @@ struct drm_mode_get_plane { __u64 format_type_pt
[RFC PATCH v2 12/17] drm/colorop: Add atomic state print for drm_colorop
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_atomic.c | 29 + include/drm/drm_colorop.h| 5 + 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 524bec520287..15bd18c9e2be 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -792,6 +792,19 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, return 0; } + + +static void drm_atomic_colorop_print_state(struct drm_printer *p, + const struct drm_colorop_state *state) +{ + struct drm_colorop *colorop = state->colorop; + + drm_printf(p, "colorop[%u]:\n", colorop->base.id); + drm_printf(p, "\ttype=%s\n", drm_get_colorop_type_name(colorop->type)); + drm_printf(p, "\tbypass=%u\n", state->bypass); + drm_printf(p, "\tcurve_1d_type=%s\n", drm_get_colorop_curve_1d_type_name(state->curve_1d_type)); +} + static void drm_atomic_plane_print_state(struct drm_printer *p, const struct drm_plane_state *state) { @@ -812,6 +825,13 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, drm_get_color_encoding_name(state->color_encoding)); drm_printf(p, "\tcolor-range=%s\n", drm_get_color_range_name(state->color_range)); +#if 0 + drm_printf(p, "\tcolor-pipeline=%s\n", + drm_get_color_pipeline_name(state->color_pipeline)); +#else + drm_printf(p, "\tcolor-pipeline=%d\n", + state->color_pipeline ? state->color_pipeline->base.id : 0); +#endif if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state); @@ -1848,6 +1868,7 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, bool take_locks) { struct drm_mode_config *config = &dev->mode_config; + struct drm_colorop *colorop; struct drm_plane *plane; struct drm_crtc *crtc; struct drm_connector *connector; @@ -1856,6 +1877,14 @@ static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p, if (!drm_drv_uses_atomic_modeset(dev)) return; + list_for_each_entry(colorop, &config->colorop_list, head) { + if (take_locks) + drm_modeset_lock(&colorop->plane->mutex, NULL); + drm_atomic_colorop_print_state(p, colorop->state); + if (take_locks) + drm_modeset_unlock(&colorop->plane->mutex); + } + list_for_each_entry(plane, &config->plane_list, head) { if (take_locks) drm_modeset_lock(&plane->mutex, NULL); diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 1ddd0e65fe36..622a671d2458 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -222,6 +222,11 @@ static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) #define drm_for_each_colorop(colorop, dev) \ list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head) +const char *drm_get_color_pipeline_name(struct drm_colorop *colorop); + +const char *drm_get_colorop_type_name(enum drm_colorop_type type); +const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); + void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); -- 2.42.0
[RFC PATCH v2 14/17] drm/plane: Add COLOR PIPELINE property
We're adding a new enum COLOR PIPELINE property. This property will have entries for each COLOR PIPELINE by referencing the DRM object ID of the first drm_colorop of the pipeline. 0 disables the entire COLOR PIPELINE. Userspace can use this to discover the available color pipelines, as well as set the desired one. The color pipelines are programmed via properties on the actual drm_colorop objects. Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_atomic.c | 46 +++ drivers/gpu/drm/drm_atomic_state_helper.c | 5 +++ drivers/gpu/drm/drm_atomic_uapi.c | 44 ++ include/drm/drm_atomic_uapi.h | 2 + include/drm/drm_plane.h | 8 5 files changed, 105 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 15bd18c9e2be..781bd3aa1849 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1472,6 +1472,52 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_add_affected_planes); +/** + * drm_atomic_add_affected_colorops - add colorops for plane + * @state: atomic state + * @plane: DRM plane + * + * This function walks the current configuration and adds all colorops + * currently used by @plane to the atomic configuration @state. This is useful + * when an atomic commit also needs to check all currently enabled colorop on + * @plane, e.g. when changing the mode. It's also useful when re-enabling a plane + * to avoid special code to force-enable all colorops. + * + * Since acquiring a colorop state will always also acquire the w/w mutex of the + * current plane for that colorop (if there is any) adding all the colorop states for + * a plane will not reduce parallelism of atomic updates. + * + * Returns: + * 0 on success or can fail with -EDEADLK or -ENOMEM. 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. + */ +int +drm_atomic_add_affected_colorops(struct drm_atomic_state *state, +struct drm_plane *plane) +{ + struct drm_colorop *colorop; + struct drm_colorop_state *colorop_state; + + WARN_ON(!drm_atomic_get_new_plane_state(state, plane)); + + drm_dbg_atomic(plane->dev, + "Adding all current colorops for [plane:%d:%s] to %p\n", + plane->base.id, plane->name, state); + + drm_for_each_colorop(colorop, plane->dev) { + if (colorop->plane != plane) + continue; + + colorop_state = drm_atomic_get_colorop_state(state, colorop); + if (IS_ERR(colorop_state)) + return PTR_ERR(colorop_state); + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_add_affected_colorops); + /** * drm_atomic_check_only - check whether a given config would work * @state: atomic configuration to check diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 784e63d70a42..3c5f2c8e33d0 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -267,6 +267,11 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, plane_state->color_range = val; } + if (plane->color_pipeline_property) { + /* default is always NULL, i.e., bypass */ + plane_state->color_pipeline = NULL; + } + if (plane->zpos_property) { if (!drm_object_property_get_default_value(&plane->base, plane->zpos_property, diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index a8f7a8a6639a..c6629fdaa114 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -256,6 +256,38 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, } EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); + +/** + * drm_atomic_set_colorop_for_plane - set colorop for plane + * @plane_state: atomic state object for the plane + * @colorop: colorop to use for the plane + * + * Changing the assigned framebuffer for a plane requires us to grab a reference + * to the new fb and drop the reference to the old fb, if there is one. This + * function takes care of all these details be
[RFC PATCH v2 16/17] drm/vkms: Add enumerated 1D curve colorop
This patch introduces a VKMS color pipeline that includes two drm_colorops for named transfer functions. For now the only ones supported are sRGB EOTF, sRGB Inverse EOTF, and a Linear TF. We will expand this in the future but I don't want to do so without accompanying IGT tests. We introduce a new vkms_luts.c file that hard-codes sRGB EOTF, sRGB Inverse EOTF, and a linear EOTF LUT. These have been generated with 256 entries each as IGT is currently testing only 8 bpc surfaces. We will likely need higher precision but I'm reluctant to make that change without clear indication that we need it. We'll revisit and, if necessary, regenerate the LUTs when we have IGT tests for higher precision buffers. v2: - Add commit description - Fix sRGB EOTF LUT definition - Add linear and sRGB inverse EOTF LUTs Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/vkms/Makefile| 4 +- drivers/gpu/drm/vkms/vkms_colorop.c | 85 +++ drivers/gpu/drm/vkms/vkms_composer.c | 46 ++ drivers/gpu/drm/vkms/vkms_drv.h | 4 + drivers/gpu/drm/vkms/vkms_luts.c | 802 +++ drivers/gpu/drm/vkms/vkms_luts.h | 12 + drivers/gpu/drm/vkms/vkms_plane.c| 2 + 7 files changed, 954 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/vkms/vkms_colorop.c create mode 100644 drivers/gpu/drm/vkms/vkms_luts.c create mode 100644 drivers/gpu/drm/vkms/vkms_luts.h diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index d3440f228f46..eb208f3e6780 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -6,7 +6,9 @@ vkms-y := \ vkms_formats.o \ vkms_crtc.o \ vkms_composer.o \ - vkms_writeback.o + vkms_writeback.o \ + vkms_colorop.o \ + vkms_luts.o obj-$(CONFIG_DRM_VKMS) += vkms.o diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c b/drivers/gpu/drm/vkms/vkms_colorop.c new file mode 100644 index ..9a26b9fdc4a2 --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_colorop.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#include +#include +#include +#include +#include + +#define MAX_COLOR_PIPELINES 5 + +const int vkms_initialize_tf_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list) +{ + + struct drm_colorop *op, *prev_op; + struct drm_device *dev = plane->dev; + int ret; + + /* 1st op: 1d curve */ + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + if (!op) { + DRM_ERROR("KMS: Failed to allocate colorop\n"); + return -ENOMEM; + } + + ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); + if (ret) + return ret; + + list->type = op->base.id; + list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", op->base.id); + + prev_op = op; + + /* 2nd op: 1d curve */ + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + if (!op) { + DRM_ERROR("KMS: Failed to allocate colorop\n"); + return -ENOMEM; + } + + ret = drm_colorop_init(dev, op, plane, DRM_COLOROP_1D_CURVE); + if (ret) + return ret; + + drm_colorop_set_next_property(prev_op, op); + + return 0; +} + +int vkms_initialize_colorops(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES]; + int len = 0; + int ret; + + /* Add "Bypass" (i.e. NULL) pipeline */ + pipelines[len].type = 0; + pipelines[len].name = "Bypass"; + len++; + + /* Add pipeline consisting of transfer functions */ + ret = vkms_initialize_tf_pipeline(plane, &(pipelines[len])); + if (ret) + return ret; + len++; + + /* Create COLOR_PIPELINE property and attach */ + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, + "COLOR_PIPELINE", + pipelines, len); + if (!prop) + return -ENOMEM; + + plane->color_pipeline_property = prop; + + drm_object_attach_property(&plane->base, prop, 0); + + /* TODO do we even need this? */ + if (plane->state) + plane->state->color_pipeline = NULL; + + return 0; +} diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/dri
[RFC PATCH v2 15/17] drm/colorop: Add NEXT to colorop state print
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/drm_atomic.c | 1 + drivers/gpu/drm/drm_colorop.c | 42 +++ include/drm/drm_colorop.h | 2 ++ 3 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 781bd3aa1849..cfe9199a15d2 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -803,6 +803,7 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p, drm_printf(p, "\ttype=%s\n", drm_get_colorop_type_name(colorop->type)); drm_printf(p, "\tbypass=%u\n", state->bypass); drm_printf(p, "\tcurve_1d_type=%s\n", drm_get_colorop_curve_1d_type_name(state->curve_1d_type)); + drm_printf(p, "\tnext=%d\n", drm_colorop_get_next_property(colorop)); } static void drm_atomic_plane_print_state(struct drm_printer *p, diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 1afd5fbe8776..ff6f938cc28c 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -340,3 +340,45 @@ void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_color next->base.id); } EXPORT_SYMBOL(drm_colorop_set_next_property); + +/** + * drm_colorop_set_next_property - gets the next colorop ID + * @colorop: drm colorop + * + * Returns: + * The DRM object ID of the next colorop + */ +uint32_t drm_colorop_get_next_property(struct drm_colorop *colorop) +{ + uint64_t next_id = 0; + + if (!colorop->next_property) + return 0; + + drm_object_property_get_value(&colorop->base, + colorop->next_property, + &next_id); + + return (uint32_t) next_id; +} +EXPORT_SYMBOL(drm_colorop_get_next_property); + + +/** + * drm_colorop_set_next_property - gets the next colorop ID + * @colorop: drm colorop + * + * Returns: + * The DRM object ID of the next colorop + */ +struct drm_colorop *drm_colorop_get_next(struct drm_colorop *colorop) +{ + uint64_t next_id = drm_colorop_get_next_property(colorop); + + if (!next_id) + return NULL; + + return drm_colorop_find(colorop->dev, NULL, next_id); + +} +EXPORT_SYMBOL(drm_colorop_get_next); \ No newline at end of file diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 622a671d2458..2ba506a0ea4d 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -228,6 +228,8 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type type); const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); +uint32_t drm_colorop_get_next_property(struct drm_colorop *colorop); +struct drm_colorop *drm_colorop_get_next(struct drm_colorop *colorop); #endif /* __DRM_COLOROP_H__ */ -- 2.42.0
[RFC PATCH v2 17/17] drm/vkms: Add kunit tests for linear and sRGB LUTs
Signed-off-by: Harry Wentland Cc: Ville Syrjala Cc: Pekka Paalanen Cc: Simon Ser Cc: Harry Wentland Cc: Melissa Wen Cc: Jonas Ådahl Cc: Sebastian Wick Cc: Shashank Sharma Cc: Alexander Goins Cc: Joshua Ashton Cc: Michel Dänzer Cc: Aleix Pol Cc: Xaver Hugl Cc: Victoria Brekenfeld Cc: Sima Cc: Uma Shankar Cc: Naseer Ahmed Cc: Christopher Braga Cc: Abhinav Kumar Cc: Arthur Grillo Cc: Hector Martin Cc: Liviu Dudau Cc: Sasha McIntosh --- drivers/gpu/drm/vkms/tests/vkms_color_tests.c | 38 ++- drivers/gpu/drm/vkms/vkms_composer.c | 13 +-- drivers/gpu/drm/vkms/vkms_composer.h | 14 +++ 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c index 843b2e1d607e..14decb5d1b64 100644 --- a/drivers/gpu/drm/vkms/tests/vkms_color_tests.c +++ b/drivers/gpu/drm/vkms/tests/vkms_color_tests.c @@ -5,6 +5,7 @@ #include #include "../vkms_composer.h" +#include "../vkms_luts.h" #define TEST_LUT_SIZE 16 @@ -33,7 +34,6 @@ const struct vkms_color_lut test_linear_lut = { .channel_value2index_ratio = 0xf000fll }; - static void vkms_color_test_get_lut_index(struct kunit *test) { int i; @@ -42,6 +42,19 @@ static void vkms_color_test_get_lut_index(struct kunit *test) for (i = 0; i < TEST_LUT_SIZE; i++) KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&test_linear_lut, test_linear_array[i].red)), i); + + KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&srgb_eotf, 0x0)), 0x0); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x0)), 0x0); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x101)), 0x1); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x202)), 0x2); + + KUNIT_EXPECT_EQ(test, drm_fixp2int(get_lut_index(&srgb_inv_eotf, 0x0)), 0x0); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x0)), 0x0); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x101)), 0x1); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_inv_eotf, 0x202)), 0x2); + + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0xfefe)), 0xfe); + KUNIT_EXPECT_EQ(test, drm_fixp2int_ceil(get_lut_index(&srgb_eotf, 0x)), 0xff); } static void vkms_color_test_lerp(struct kunit *test) @@ -49,9 +62,32 @@ static void vkms_color_test_lerp(struct kunit *test) KUNIT_EXPECT_EQ(test, lerp_u16(0x0, 0x10, 0x8000), 0x8); } +static void vkms_color_test_linear(struct kunit *test) +{ + for (int i = 0; i < LUT_SIZE; i++) { + int linear = apply_lut_to_channel_value(&linear_eotf, i * 0x101, LUT_RED); + KUNIT_EXPECT_EQ(test, DIV_ROUND_CLOSEST(linear, 0x101), i); + } +} + +static void vkms_color_srgb_inv_srgb(struct kunit *test) +{ + u16 srgb, final; + + for (int i = 0; i < LUT_SIZE; i++) { + srgb = apply_lut_to_channel_value(&srgb_eotf, i * 0x101, LUT_RED); + final = apply_lut_to_channel_value(&srgb_inv_eotf, srgb, LUT_RED); + + KUNIT_EXPECT_GE(test, final / 0x101, i-1); + KUNIT_EXPECT_LE(test, final / 0x101, i+1); + } +} + static struct kunit_case vkms_color_test_cases[] = { KUNIT_CASE(vkms_color_test_get_lut_index), KUNIT_CASE(vkms_color_test_lerp), + KUNIT_CASE(vkms_color_test_linear), + KUNIT_CASE(vkms_color_srgb_inv_srgb), {} }; diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 73b7d5e94021..24c984f2876f 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -110,18 +110,7 @@ s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value) return drm_fixp_mul(color_channel_fp, lut->channel_value2index_ratio); } -/* - * This enum is related to the positions of the variables inside - * `struct drm_color_lut`, so the order of both needs to be the same. - */ -enum lut_channel { - LUT_RED = 0, - LUT_GREEN, - LUT_BLUE, - LUT_RESERVED -}; - -static u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value, +u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value, enum lut_channel channel) { s64 lut_index = get_lut_index(lut, channel_value); diff --git a/drivers/gpu/drm/vkms/vkms_composer.h b/drivers/gpu/drm/vkms/vkms_composer.h index 11c5de9cc961..d92497c555eb 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.h +++ b/drivers/gpu/drm/vkms/vkms_composer.h @@ -8,4 +8,18 @@ s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value); u16 lerp_u16(u16 a, u16 b, s64
Re: [RFC PATCH v2 06/17] drm/doc/rfc: Describe why prescriptive color pipeline is needed
On 2023-10-20 10:57, Pekka Paalanen wrote: > On Fri, 20 Oct 2023 16:22:56 +0200 > Sebastian Wick wrote: > >> Thanks for continuing to work on this! >> >> On Thu, Oct 19, 2023 at 05:21:22PM -0400, Harry Wentland wrote: >>> v2: >>> - Update colorop visualizations to match reality (Sebastian, Alex Hung) >>> - Updated wording (Pekka) >>> - Change BYPASS wording to make it non-mandatory (Sebastian) >>> - Drop cover-letter-like paragraph from COLOR_PIPELINE Plane Property >>>section (Pekka) >>> - Use PQ EOTF instead of its inverse in Pipeline Programming example >>> (Melissa) >>> - Add "Driver Implementer's Guide" section (Pekka) >>> - Add "Driver Forward/Backward Compatibility" section (Sebastian, Pekka) >>> > > ... > >>> +Driver Forward/Backward Compatibility >>> += >>> + >>> +As this is uAPI drivers can't regress color pipelines that have been >>> +introduced for a given HW generation. New HW generations are free to >>> +abandon color pipelines advertised for previous generations. >>> +Nevertheless, it can be beneficial to carry support for existing color >>> +pipelines forward as those will likely already have support in DRM >>> +clients. >>> + >>> +Introducing new colorops to a pipeline is fine, as long as they can be >>> +disabled or are purely informational. DRM clients implementing support >>> +for the pipeline can always skip unknown properties as long as they can >>> +be confident that doing so will not cause unexpected results. >>> + >>> +If a new colorop doesn't fall into one of the above categories >>> +(bypassable or informational) the modified pipeline would be unusable >>> +for user space. In this case a new pipeline should be defined. >> >> How can user space detect an informational element? Should we just add a >> BYPASS property to informational elements, make it read only and set to >> true maybe? Or something more descriptive? > > Read-only BYPASS set to true would be fine by me, I guess. > Don't you mean set to false? An informational element will always do something, so it can't be bypassed. > I think we also need a definition of "informational". > > Counter-example 1: a colorop that represents a non-configurable Not sure what's "counter" for these examples? > YUV<->RGB conversion. Maybe it determines its operation from FB pixel > format. It cannot be set to bypass, it cannot be configured, and it > will alter color values. > > Counter-example 2: image size scaling colorop. It might not be > configurable, it is controlled by the plane CRTC_* and SRC_* > properties. You still need to understand what it does, so you can > arrange the scaling to work correctly. (Do not want to scale an image > with PQ-encoded values as Josh demonstrated in XDC.) > IMO the position of the scaling operation is the thing that's important here as the color pipeline won't define scaling properties. > Counter-example 3: image sampling colorop. Averages FB originated color > values to produce a color sample. Again do not want to do this with > PQ-encoded values. > Wouldn't this only happen during a scaling op? Harry > > Thanks, > pq