Re: [PATCH] drm: rename u32 in __u32 in uapi
On 17-08-24 17:55:35, Emil Velikov wrote: On 24 August 2017 at 16:08, Lionel Landwerlin <lionel.g.landwer...@intel.com> wrote: All other fields use __ Fairly sure I mentioned it at some point - I might have been tad vague though :-\ Thanks for the fix, Lionel. Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> I'm sure it was fixed at some point. v5: Rename modifiers to modifiers_property (Ville) Use sizeof(__u32) instead to reflect UAPI nature (Ville) Make BUILD_BUG_ON for blob header size Reviewed-by: Ben Widawsky <b...@bwidawsk.net> -Emil ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] i915,drm/fourcc: Improve the CCS modifier documentation
On 17-08-18 11:34:40, Jason Ekstrand wrote: This updates the documentation on the intel CCS modifiers for a couple of reasons: 1) The old documentation required that the CCS modifier only be used with formats. While i915 currently only supports CCS scanout with formats (and advertises such through the blob format), CCS can be used with many other formats. Mesa, in particular, can handle CCS on the full range of formats supported by the hardware. For image sharing entirely within userspace, we don't want this restriction. 2) The old documentation specified the scaling factor in terms of pixels which breaks down when you start using formats which are not 32-bit. By specifying it in terms of cache lines and tiles, we can properly specify the scale-down relationship with no format size assumptions. 3) The new comment provides more detail about the "real" layout of CCS on Sky Lake and also points out that the reason why Y tiling is important is because it affects row pitch calculations. 4) We shouldn't be documenting the Yf CCS modifier yet. Userspace is incapable of generating it right now and we don't fully know how it works yet. Trying to fully describe it is premature. Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> --- include/uapi/drm/drm_fourcc.h | 35 ++- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 3ad838d..9670da4 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -266,21 +266,30 @@ extern "C" { /* * Intel color control surface (CCS) for render compression * - * The framebuffer format must be one of the 8:8:8:8 RGB formats. - * The main surface will be plane index 0 and must be Y/Yf-tiled, - * the CCS will be plane index 1. - * - * Each CCS tile matches a 1024x512 pixel area of the main surface. - * To match certain aspects of the 3D hardware the CCS is - * considered to be made up of normal 128Bx32 Y tiles, Thus - * the CCS pitch must be specified in multiples of 128 bytes. - * - * In reality the CCS tile appears to be a 64Bx64 Y tile, composed - * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks. - * But that fact is not relevant unless the memory is accessed - * directly. + * The image format must be compatible with CCS_E (lossless render + * compression) as specified in the PRM for the relevant hardware. + * The main surface will be plane index 0 and must be Y-tiled, + * the CCS will be plane index 1 and is also Y-tiled. I guess if you're future proofing, you might want to bake in the language for planar formats. + * + * Each 64B cache line in the CCS (a region of 16B x 4 rows when + * Y-tiled) corresponds to a region of 32x16 cache lines in the main + * surface. (As a corollary, each CCS tile corresponds to an area of + * 32x16 tiles in the main surface.) This relationship holds regardless + * of the size of the number of bits per pixel of the image format. + * + * In reality, the cache lines in the CCS tile are proportioned in an + * 8B x 8 row configuration with each byte being 2x2 2-bit CCS entries. + * However, CCS is documented as Y-tiled with the scaling relationship + * described in terms of cache lines as above so we consider it to be + * Y-tiled for the purpose of specifying this modifier. This means that + * the row pitch for the CCS assumes 128B/tile. */ #define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4) + +/* Reserved for the Yf version of the TILED_CCS modifier. + * + * Exact definition TBD. + */ #define I915_FORMAT_MOD_Yf_TILED_CCSfourcc_mod_code(INTEL, 5) Can we just rename this to RSVD, or does Mesa build already require this? /* ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 6/6] [v4] drm/i915: Add support for CCS modifiers
On 17-08-03 12:00:56, Daniel Stone wrote: Hi, On 1 August 2017 at 17:58, Ben Widawsky <b...@bwidawsk.net> wrote: @@ -1240,6 +1253,19 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane_formats = skl_plane_formats; num_plane_formats = ARRAY_SIZE(skl_plane_formats); modifiers = skl_plane_format_modifiers; + } else if (INTEL_GEN(dev_priv) >= 9) { + intel_plane->can_scale = true; + state->scaler_id = -1; + + intel_plane->update_plane = skl_update_plane; + intel_plane->disable_plane = skl_disable_plane; + + plane_formats = skl_plane_formats; + num_plane_formats = ARRAY_SIZE(skl_plane_formats); + if (pipe >= PIPE_C) if (pipe >= PIPE_C || plane >= PLANE_SPRITE1) cf. skl_check_ccs_aux_surface() which rejects CCS on anything other than PRIMARY/SPRITE0. I'll squash when pushing. Cheers, Daniel Okay, thanks. With universal planes however, I don't think we need such a restriction, but whatevs ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 6/6] drm/i915: Add support for CCS modifiers
On 17-08-03 10:08:51, Daniel Vetter wrote: On Wed, Aug 2, 2017 at 5:43 PM, Ben Widawsky <b...@bwidawsk.net> wrote: On 17-08-02 12:14:15, Daniel Vetter wrote: On Tue, Aug 01, 2017 at 09:14:50AM -0700, Ben Widawsky wrote: On 17-07-31 10:29:55, Daniel Vetter wrote: > On Sat, Jul 29, 2017 at 09:25:50AM -0700, Ben Widawsky wrote: > > On 17-07-29 13:53:10, Daniel Stone wrote: > > > Hi Ben, > > > > > > On 26 July 2017 at 19:08, Ben Widawsky <b...@bwidawsk.net> wrote: > > > > + } else if (INTEL_GEN(dev_priv) >= 9) { > > > > intel_primary_formats = skl_primary_formats; > > > > num_formats = ARRAY_SIZE(skl_primary_formats); > > > > - modifiers = skl_format_modifiers; > > > > + if (pipe >= PIPE_C) > > > > + modifiers = skl_format_modifiers_ccs; > > > > + else > > > > + modifiers = skl_format_modifiers_noccs; > > > > > > Shouldn't that be (pipe < PIPE_C)? > > > > > > Cheers, > > > Daniel > > > > Yep. It was wrong in v7 too :/. I have it fixed locally. > > Shouldn't the igt catch this, or does it not try to exercise all the > plane/crtc combos there are? > -Daniel I don't know whether or not IGT should have caught this, but it wouldn't have because I had been sending these without Ville's patches, so my patches alone don't even build (since his patches defined the modifiers). You can run igt testcases locally. I expect you to do that, at least for the stuff you're touching. Does this mean there's no igts for this at all? -Daniel I haven't been running IGT locally, so I don't know if they touch this path. We've done all testing so far with kmscube, X, and weston; then measure the overall bandwidth. In this case, I'd stop testing these since Jason/Daniel took over my other patches. I don't even know how to locally make sure I get a display on pipe C. You could easily make an IGT make sure that you get back the right list of modifiers for a given pipe on a given GEN. Probably should do one. That's not a terribly interesting testcase (we have none of this kind I think). But I thought there was a CCS igt that created some simple compressed buffers and tried to display them, and then checked it all looked good using crcs, i.e. an actual functional testcase, and that should have caught the mislisten on pipe C (if it bothered to test all planes that expose the CCS modifier). Iirc Ville had that. We do need that for merging the kernel side. Thanks, Daniel Yeah, we did have that already - just nothing for blobifiers specifically. It sounds like igt_ccs is broken at the moment. -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 6/6] drm/i915: Add support for CCS modifiers
On 17-08-02 12:14:15, Daniel Vetter wrote: On Tue, Aug 01, 2017 at 09:14:50AM -0700, Ben Widawsky wrote: On 17-07-31 10:29:55, Daniel Vetter wrote: > On Sat, Jul 29, 2017 at 09:25:50AM -0700, Ben Widawsky wrote: > > On 17-07-29 13:53:10, Daniel Stone wrote: > > > Hi Ben, > > > > > > On 26 July 2017 at 19:08, Ben Widawsky <b...@bwidawsk.net> wrote: > > > > + } else if (INTEL_GEN(dev_priv) >= 9) { > > > > intel_primary_formats = skl_primary_formats; > > > > num_formats = ARRAY_SIZE(skl_primary_formats); > > > > - modifiers = skl_format_modifiers; > > > > + if (pipe >= PIPE_C) > > > > + modifiers = skl_format_modifiers_ccs; > > > > + else > > > > + modifiers = skl_format_modifiers_noccs; > > > > > > Shouldn't that be (pipe < PIPE_C)? > > > > > > Cheers, > > > Daniel > > > > Yep. It was wrong in v7 too :/. I have it fixed locally. > > Shouldn't the igt catch this, or does it not try to exercise all the > plane/crtc combos there are? > -Daniel I don't know whether or not IGT should have caught this, but it wouldn't have because I had been sending these without Ville's patches, so my patches alone don't even build (since his patches defined the modifiers). You can run igt testcases locally. I expect you to do that, at least for the stuff you're touching. Does this mean there's no igts for this at all? -Daniel I haven't been running IGT locally, so I don't know if they touch this path. We've done all testing so far with kmscube, X, and weston; then measure the overall bandwidth. In this case, I'd stop testing these since Jason/Daniel took over my other patches. I don't even know how to locally make sure I get a display on pipe C. You could easily make an IGT make sure that you get back the right list of modifiers for a given pipe on a given GEN. Probably should do one. -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 6/6] [v4] drm/i915: Add support for CCS modifiers
On 17-08-01 15:43:50, Kenneth Graunke wrote: On Tuesday, August 1, 2017 9:58:17 AM PDT Ben Widawsky wrote: v2: - Support sprite plane. - Support pipe C/D limitation on GEN9. v3: - Rename structure (Ville) - Handle GLK (Ville) v4: - Fix PIPE_C check, introduced in v2 (Daniel) - Whitespace fix (Daniel) Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 30 +++--- drivers/gpu/drm/i915/intel_sprite.c | 28 +++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ad49b99ef25f..0dc9f40edc7e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -93,7 +93,17 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; -static const uint64_t skl_format_modifiers[] = { +static const uint64_t skl_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +static const uint64_t skl_format_modifiers_ccs[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -13853,6 +13863,10 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: + if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_CCS) + return true; + /* fall through */ case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: @@ -14099,10 +14113,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + intel_primary_formats = skl_primary_formats; + num_formats = ARRAY_SIZE(skl_primary_formats); + modifiers = skl_format_modifiers_ccs; + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; + } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); - modifiers = skl_format_modifiers; + if (pipe < PIPE_C) + modifiers = skl_format_modifiers_ccs; + else + modifiers = skl_format_modifiers_noccs; primary->update_plane = skylake_update_primary_plane; primary->disable_plane = skylake_disable_primary_plane; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b1cc4835b963..5a2b3f3693a6 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1085,7 +1085,17 @@ static uint32_t skl_plane_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_plane_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_plane_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -1148,6 +1158,9 @@ static bool skl_sprite_plane_format_mod_supported(struct drm_plane *plane, case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: + if (modifier == I915_FORMAT_MOD_Y_TILED_CCS || + modifier == I915_FORMAT_MOD_Yf_TILED_CCS) + return true; case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: @@ -1230,7 +1243,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, } intel_plane->base.state = >base; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10) { I think this should be INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv). With that fixed, this patch would be: Reviewed-by: Kenneth Graunke <kenn...@whitecape.org> for what it's worth (I'm not that familiar with display). Thanks. Here is what I've changed locally which didn't match the
[PATCH 6/6] [v4] drm/i915: Add support for CCS modifiers
v2: - Support sprite plane. - Support pipe C/D limitation on GEN9. v3: - Rename structure (Ville) - Handle GLK (Ville) v4: - Fix PIPE_C check, introduced in v2 (Daniel) - Whitespace fix (Daniel) Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 30 +++--- drivers/gpu/drm/i915/intel_sprite.c | 28 +++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ad49b99ef25f..0dc9f40edc7e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -93,7 +93,17 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; -static const uint64_t skl_format_modifiers[] = { +static const uint64_t skl_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +static const uint64_t skl_format_modifiers_ccs[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -13853,6 +13863,10 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: + if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_CCS) + return true; + /* fall through */ case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: @@ -14099,10 +14113,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + intel_primary_formats = skl_primary_formats; + num_formats = ARRAY_SIZE(skl_primary_formats); + modifiers = skl_format_modifiers_ccs; + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; + } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); - modifiers = skl_format_modifiers; + if (pipe < PIPE_C) + modifiers = skl_format_modifiers_ccs; + else + modifiers = skl_format_modifiers_noccs; primary->update_plane = skylake_update_primary_plane; primary->disable_plane = skylake_disable_primary_plane; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b1cc4835b963..5a2b3f3693a6 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1085,7 +1085,17 @@ static uint32_t skl_plane_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_plane_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_plane_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -1148,6 +1158,9 @@ static bool skl_sprite_plane_format_mod_supported(struct drm_plane *plane, case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: + if (modifier == I915_FORMAT_MOD_Y_TILED_CCS || + modifier == I915_FORMAT_MOD_Yf_TILED_CCS) + return true; case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: @@ -1230,7 +1243,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, } intel_plane->base.state = >base; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10) { intel_plane->can_scale = true; state->scaler_id = -1; @@ -1240,6 +1253,19 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane_formats = skl_plane_formats; num_plane_formats = ARRAY_SIZE(skl_plane_formats); modifiers = skl_plane_format_modifiers; + } else if (INTEL_GEN(dev_priv) >= 9) { +
[PATCH 3/6] [v7] drm: Plumb modifiers through plane init
This is the plumbing for supporting fb modifiers on planes. Modifiers have already been introduced to some extent, but this series will extend this to allow querying modifiers per plane. Based on this, the client to enable optimal modifications for framebuffers. This patch simply allows the DRM drivers to initialize their list of supported modifiers upon initializing the plane. v2: A minor addition from Daniel v3: * Updated commit message * s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu) * Remove some excess newlines (Liviu) * Update comment for > 64 modifiers (Liviu) v4: Minor comment adjustments (Liviu) v5: Some new platforms added due to rebase v6: Add some missed plane inits (or maybe they're new - who knows at this point) (Daniel) v7: Add sun8i (Daniel) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <liviu.du...@arm.com> Acked-by: Philippe Cornu <philippe.co...@st.com> (for stm) Tested-by: Philippe Cornu <philippe.co...@st.com> (for stm) --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 ++- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 36 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 5 +++- drivers/gpu/drm/i915/intel_sprite.c | 4 +-- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++-- drivers/gpu/drm/omapdrm/omap_plane.c| 2 +- drivers/gpu/drm/pl111/pl111_display.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +-- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/sun4i/sun8i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 - drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +-- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 22 ++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 45 files changed, 131 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 1859dd3ad622..799416651f2f 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -217,6 +217,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 16e1e20cf04c..72b22b805412 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/malid
[PATCH 5/6] [v10] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) v6: - Actually use the sprite funcs (Emil) - Use unreachable (Emil) v7: - Only allow Intel modifiers and LINEAR (Ben) v8 - Fix spite assert introduced in v6 (Daniel) v9 - Change vendor check logic to avoid magic 56 (Emil) - Reorder skl_mod_support (Ville) - make intel_plane_funcs static, could be done as of v5 (Ville) - rename local variable intel_format_modifiers to modifiers (Ville) - actually use sprite modifiers - split out modifier/formats by platform (Ville) v10: - Undo vendor check from v9 Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v8) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 127 +-- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_sprite.c | 141 ++- 3 files changed, 259 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b9dda03678c0..ad49b99ef25f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,11 +93,24 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, }; +static const uint64_t cursor_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); static void ironlake_pch_clock_get(struct intel_crtc *crtc, @@ -13797,7 +13816,98 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } -const struct drm_plane_funcs intel_plane_funcs = { +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + if (modifier == I915_FORMAT_MOD_Yf_TILED) + return true; + /* fall through */ + case DRM_FORMAT_C8: + if (modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED || + modifier == I915_FORMAT_MOD_Y_TILED) + return true; + /* fall through */ + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +
[PATCH 1/6] drm/i915: Implement .get_format_info() hook for CCS
From: Ville Syrjälä <ville.syrj...@linux.intel.com> SKL+ display engine can scan out certain kinds of compressed surfaces produced by the render engine. This involved telling the display engine the location of the color control surfae (CCS) which describes which parts of the main surface are compressed and which are not. The location of CCS is provided by userspace as just another plane with its own offset. By providing our own format information for the CCS formats, we should be able to make framebuffer_check() do the right thing for the CCS surface as well. Note that we'll return the same format info for both Y and Yf tiled format as that's what happens with the non-CCS Y vs. Yf as well. If desired, we could potentially return a unique pointer for each pixel_format+tiling+ccs combination, in which case we immediately be able to tell if any of that stuff changed by just comparing the pointers. But that does sound a bit wasteful space wise. v2: Drop the 'dev' argument from the hook v3: Include the description of the CCS surface layout v4: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason) Cc: Daniel Vetter <dan...@ffwll.ch> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Reviewed-by: Ben Widawsky <b...@bwidawsk.net> (v3) Signed-off-by: Ville Syrjä <ville.syrj...@linux.intel.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/drm_fourcc.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 37 include/drm/drm_mode_config.h| 3 ++- include/uapi/drm/drm_fourcc.h| 3 +++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index 9c0152df45ad..50da6180c495 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -222,7 +222,7 @@ drm_get_format_info(struct drm_device *dev, const struct drm_format_info *info = NULL; if (dev->mode_config.funcs->get_format_info) - info = dev->mode_config.funcs->get_format_info(mode_cmd); + info = dev->mode_config.funcs->get_format_info(dev, mode_cmd); if (!info) info = drm_format_info(mode_cmd->pixel_format); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e92fd14c06c7..6b00689ef6e0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2433,6 +2433,42 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier) } } +static const struct drm_format_info ccs_formats[] = { + { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, + { .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, + { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, + { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, +}; + +static const struct drm_format_info * +lookup_format_info(const struct drm_format_info formats[], + int num_formats, u32 format) +{ + int i; + + for (i = 0; i < num_formats; i++) { + if (formats[i].format == format) + return [i]; + } + + return NULL; +} + +static const struct drm_format_info * +intel_get_format_info(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *cmd) +{ + switch (cmd->modifier[0]) { + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Yf_TILED_CCS: + return lookup_format_info(ccs_formats, + ARRAY_SIZE(ccs_formats), + cmd->pixel_format); + default: + return NULL; + } +} + static int intel_fill_fb_info(struct drm_i915_private *dev_priv, struct drm_framebuffer *fb) @@ -14630,6 +14666,7 @@ static void intel_atomic_state_free(struct drm_atomic_state *state) static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_create = intel_user_framebuffer_create, + .get_format_info = intel_get_format_info, .output_poll_changed = intel_fbdev_output_poll_changed, .atomic_check = intel_atomic_check, .atomic_commit = intel_atomic_commit, diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 42981711189b..f0d3d3857ae2 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -81,7 +81,8 @@ struct drm_mode_config_funcs { * The format information specific to the given fb metadata, or * NULL if none is found. */ - const struct drm_format_info *(*get_format_info)(const s
[PATCH 4/6] [v5] drm: Create a format/modifier blob
Updated blob layout (Rob, Daniel, Kristian, xerpi) v2: * Removed __packed, and alignment (.+) * Fix indent in drm_format_modifier fields (Liviu) * Remove duplicated modifier > 64 check (Liviu) * Change comment about modifier (Liviu) * Remove arguments to blob creation, use plane instead (Liviu) * Fix data types (Ben) * Make the blob part of uapi (Daniel) v3: Remove unused ret field. Change i, and j to unsigned int (Emil) v4: Use plane->modifier_count instead of recounting (Daniel) v5: Rename modifiers to modifiers_property (Ville) Use sizeof(__u32) instead to reflect UAPI nature (Ville) Make BUILD_BUG_ON for blob header size Cc: Rob Clark <robdcl...@gmail.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <li...@dudau.co.uk> (v2) Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v3) --- drivers/gpu/drm/drm_mode_config.c | 7 drivers/gpu/drm/drm_plane.c | 84 +++ include/drm/drm_mode_config.h | 6 +++ include/uapi/drm/drm_mode.h | 50 +++ 4 files changed, 147 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..74f6ff5df656 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers_property = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index d3fc561d7b48..5c14beee52ff 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +{ + const struct drm_mode_config *config = >mode_config; + struct drm_property_blob *blob; + struct drm_format_modifier *mod; + size_t blob_size, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + unsigned int i, j; + + formats_size = sizeof(__u32) * plane->format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * plane->modifier_count; + + blob_size = sizeof(struct drm_format_modifier_blob); + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = plane->format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = plane->modifier_count; + + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), plane->format_types, formats_size); + + /* If we can't determine support, just bail */ + if (!plane->funcs->format_mod_supported) + goto done; + + mod = modifiers_ptr(blob_data); + for (i = 0; i < plane->modifier_count; i++) { + for (j = 0; j < plane->format_count; j++) { + if (plane->funcs->format_mod_supported(plane, + plane->format_types[j], + plane->modifiers[i])) { + + mod->formats |= 1 << j; + } + } + + mod->modifier = plane->modifiers[i]; +
[PATCH 2/6] drm/i915: Add render decompression support
From: Ville Syrjälä <ville.syrj...@linux.intel.com> SKL+ display engine can scan out certain kinds of compressed surfaces produced by the render engine. This involved telling the display engine the location of the color control surfae (CCS) which describes which parts of the main surface are compressed and which are not. The location of CCS is provided by userspace as just another plane with its own offset. Add the required stuff to validate the user provided AUX plane metadata and convert the user provided linear offset into something the hardware can consume. Due to hardware limitations we require that the main surface and the AUX surface (CCS) be part of the same bo. The hardware also makes life hard by not allowing you to provide separate x/y offsets for the main and AUX surfaces (excpet with NV12), so finding suitable offsets for both requires a bit of work. Assuming we still want keep playing tricks with the offsets. I've just gone with a dumb "search backward for suitable offsets" approach, which is far from optimal, but it works. Also not all planes will be capable of scanning out compressed surfaces, and eg. 90/270 degree rotation is not supported in combination with decompression either. This patch may contain work from at least the following people: * Vandana Kannan <vandana.kan...@intel.com> * Daniel Vetter <dan...@ffwll.ch> * Ben Widawsky <b...@bwidawsk.net> v2: Deal with display workarounds 0390, 0531, 1125 (Paulo) v3: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason) Put the AUX register defines to the correct place Fix up the slightly bogus rotation check v4: Use I915_WRITE_FW() due to plane update locking changes s/return -EINVAL/goto err/ in intel_framebuffer_init() Eliminate a bunch hardcoded numbers in CCS code v5: (By Ben) conflict resolution + - res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum); + res_blocks += fixed16_to_u32_round_up(y_tile_minimum); Cc: Paulo Zanoni <paulo.r.zan...@intel.com> Cc: Daniel Vetter <dan...@ffwll.ch> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Signed-off-by: Ville Syrjä <ville.syrj...@linux.intel.com> Reviewed-by: Ben Widawsky <b...@bwidawsk.net> (v1) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/i915_reg.h | 23 drivers/gpu/drm/i915/intel_display.c | 233 --- drivers/gpu/drm/i915/intel_pm.c | 29 - drivers/gpu/drm/i915/intel_sprite.c | 5 + 4 files changed, 272 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c712d01f92ab..cea4f941a56e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6106,6 +6106,10 @@ enum { #define _PLANE_KEYMSK_2_A 0x70298 #define _PLANE_KEYMAX_1_A 0x701a0 #define _PLANE_KEYMAX_2_A 0x702a0 +#define _PLANE_AUX_DIST_1_A0x701c0 +#define _PLANE_AUX_DIST_2_A0x702c0 +#define _PLANE_AUX_OFFSET_1_A 0x701c4 +#define _PLANE_AUX_OFFSET_2_A 0x702c4 #define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */ #define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */ #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ @@ -6212,6 +6216,24 @@ enum { #define PLANE_NV12_BUF_CFG(pipe, plane)\ _MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe)) +#define _PLANE_AUX_DIST_1_B0x711c0 +#define _PLANE_AUX_DIST_2_B0x712c0 +#define _PLANE_AUX_DIST_1(pipe) \ + _PIPE(pipe, _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B) +#define _PLANE_AUX_DIST_2(pipe) \ + _PIPE(pipe, _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B) +#define PLANE_AUX_DIST(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe)) + +#define _PLANE_AUX_OFFSET_1_B 0x711c4 +#define _PLANE_AUX_OFFSET_2_B 0x712c4 +#define _PLANE_AUX_OFFSET_1(pipe) \ + _PIPE(pipe, _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B) +#define _PLANE_AUX_OFFSET_2(pipe) \ + _PIPE(pipe, _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B) +#define PLANE_AUX_OFFSET(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe)) + #define _PLANE_COLOR_CTL_1_B 0x711CC #define _PLANE_COLOR_CTL_2_B 0x712CC #define _PLANE_COLOR_CTL_3_B 0x713CC @@ -6695,6 +6717,7 @@ enum { # define CHICKEN3_DGMG_DONE_FIX_DISABLE(1 << 2) #define CHICKE
Re: [Intel-gfx] [PATCH 6/6] drm/i915: Add support for CCS modifiers
On 17-07-31 10:29:55, Daniel Vetter wrote: On Sat, Jul 29, 2017 at 09:25:50AM -0700, Ben Widawsky wrote: On 17-07-29 13:53:10, Daniel Stone wrote: > Hi Ben, > > On 26 July 2017 at 19:08, Ben Widawsky <b...@bwidawsk.net> wrote: > > + } else if (INTEL_GEN(dev_priv) >= 9) { > > intel_primary_formats = skl_primary_formats; > > num_formats = ARRAY_SIZE(skl_primary_formats); > > - modifiers = skl_format_modifiers; > > + if (pipe >= PIPE_C) > > + modifiers = skl_format_modifiers_ccs; > > + else > > + modifiers = skl_format_modifiers_noccs; > > Shouldn't that be (pipe < PIPE_C)? > > Cheers, > Daniel Yep. It was wrong in v7 too :/. I have it fixed locally. Shouldn't the igt catch this, or does it not try to exercise all the plane/crtc combos there are? -Daniel I don't know whether or not IGT should have caught this, but it wouldn't have because I had been sending these without Ville's patches, so my patches alone don't even build (since his patches defined the modifiers). -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 6/6] drm/i915: Add support for CCS modifiers
On 17-07-29 13:53:10, Daniel Stone wrote: Hi Ben, On 26 July 2017 at 19:08, Ben Widawsky <b...@bwidawsk.net> wrote: + } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); - modifiers = skl_format_modifiers; + if (pipe >= PIPE_C) + modifiers = skl_format_modifiers_ccs; + else + modifiers = skl_format_modifiers_noccs; Shouldn't that be (pipe < PIPE_C)? Cheers, Daniel Yep. It was wrong in v7 too :/. I have it fixed locally. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 5/6] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) v6: - Actually use the sprite funcs (Emil) - Use unreachable (Emil) v7: - Only allow Intel modifiers and LINEAR (Ben) v8 - Fix spite assert introduced in v6 (Daniel) v9 - Change vendor check logic to avoid magic 56 (Emil) - Reorder skl_mod_support (Ville) - make intel_plane_funcs static, could be done as of v5 (Ville) - rename local variable intel_format_modifiers to modifiers (Ville) - actually use sprite modifiers - split out modifier/formats by platform (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v8) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 127 +-- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_sprite.c | 141 ++- 3 files changed, 259 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0381a1734396..40cb02c0ac2b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -67,6 +67,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -82,11 +88,24 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, }; +static const uint64_t cursor_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); static void ironlake_pch_clock_get(struct intel_crtc *crtc, @@ -12843,7 +12862,98 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } -const struct drm_plane_funcs intel_plane_funcs = { +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + if (modifier == I915_FORMAT_MOD_Yf_TILED) + return true; + /* fall through */ + case DRM_FORMAT_C8: + if (modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED || + modifier == I915_FORMAT_MOD_Y_TILED) + return true; + /* fall through */ + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +
[PATCH 6/6] drm/i915: Add support for CCS modifiers
v2: Support sprite plane. Support pipe C/D limitation on GEN9. v3: Rename structure (Ville) Handle GLK (Ville) This requires rebase on the correct Ville patches Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 30 +++--- drivers/gpu/drm/i915/intel_sprite.c | 25 - 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 40cb02c0ac2b..fc990189c97d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -88,7 +88,17 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; -static const uint64_t skl_format_modifiers[] = { +static const uint64_t skl_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +static const uint64_t skl_format_modifiers_ccs[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -12899,6 +12909,10 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: + if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_CCS) + return true; + /* fall through */ case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: @@ -13144,10 +13158,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + intel_primary_formats = skl_primary_formats; + num_formats = ARRAY_SIZE(skl_primary_formats); + modifiers = skl_format_modifiers_ccs; + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; + } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); - modifiers = skl_format_modifiers; + if (pipe >= PIPE_C) + modifiers = skl_format_modifiers_ccs; + else + modifiers = skl_format_modifiers_noccs; primary->update_plane = skylake_update_primary_plane; primary->disable_plane = skylake_disable_primary_plane; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 05a15063ee97..97d29cc061ad 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1079,7 +1079,17 @@ static uint32_t skl_plane_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_plane_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_plane_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -1224,7 +1234,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, } intel_plane->base.state = >base; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10) { intel_plane->can_scale = true; state->scaler_id = -1; @@ -1234,6 +1244,19 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane_formats = skl_plane_formats; num_plane_formats = ARRAY_SIZE(skl_plane_formats); modifiers = skl_plane_format_modifiers; + } else if (INTEL_GEN(dev_priv) >= 9) { + intel_plane->can_scale = true; + state->scaler_id = -1; + + intel_plane->update_plane = skl_update_plane; + intel_plane->disable_plane = skl_disable_plane; + + plane_formats = skl_plane_formats; + num_plane_formats = ARRAY_SIZE(skl_plane_formats); + if (pipe >= PIPE_C) + modifiers = skl_plane_format_modifiers_noccs; + else + modifiers = skl_plane_fo
[PATCH 4/6] drm: Create a format/modifier blob
Updated blob layout (Rob, Daniel, Kristian, xerpi) v2: * Removed __packed, and alignment (.+) * Fix indent in drm_format_modifier fields (Liviu) * Remove duplicated modifier > 64 check (Liviu) * Change comment about modifier (Liviu) * Remove arguments to blob creation, use plane instead (Liviu) * Fix data types (Ben) * Make the blob part of uapi (Daniel) v3: Remove unused ret field. Change i, and j to unsigned int (Emil) v4: Use plane->modifier_count instead of recounting (Daniel) v5: Rename modifiers to modifiers_property (Ville) Use sizeof(__u32) instead to reflect UAPI nature (Ville) Make BUILD_BUG_ON for blob header size Cc: Rob Clark <robdcl...@gmail.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <li...@dudau.co.uk> (v2) Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v3) --- drivers/gpu/drm/drm_mode_config.c | 7 drivers/gpu/drm/drm_plane.c | 84 +++ include/drm/drm_mode_config.h | 6 +++ include/uapi/drm/drm_mode.h | 50 +++ 4 files changed, 147 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..74f6ff5df656 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers_property = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index d3fc561d7b48..5c14beee52ff 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +{ + const struct drm_mode_config *config = >mode_config; + struct drm_property_blob *blob; + struct drm_format_modifier *mod; + size_t blob_size, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + unsigned int i, j; + + formats_size = sizeof(__u32) * plane->format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * plane->modifier_count; + + blob_size = sizeof(struct drm_format_modifier_blob); + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = plane->format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = plane->modifier_count; + + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), plane->format_types, formats_size); + + /* If we can't determine support, just bail */ + if (!plane->funcs->format_mod_supported) + goto done; + + mod = modifiers_ptr(blob_data); + for (i = 0; i < plane->modifier_count; i++) { + for (j = 0; j < plane->format_count; j++) { + if (plane->funcs->format_mod_supported(plane, + plane->format_types[j], + plane->modifiers[i])) { + + mod->formats |= 1 << j; + } + } + + mod->modifier = plane->modifiers[i]; +
[PATCH 3/6] drm: Plumb modifiers through plane init
This is the plumbing for supporting fb modifiers on planes. Modifiers have already been introduced to some extent, but this series will extend this to allow querying modifiers per plane. Based on this, the client to enable optimal modifications for framebuffers. This patch simply allows the DRM drivers to initialize their list of supported modifiers upon initializing the plane. v2: A minor addition from Daniel v3: * Updated commit message * s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu) * Remove some excess newlines (Liviu) * Update comment for > 64 modifiers (Liviu) v4: Minor comment adjustments (Liviu) v5: Some new platforms added due to rebase v6: Add some missed plane inits (or maybe they're new - who knows at this point) (Daniel) v7: Add sun8i (Daniel) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <liviu.du...@arm.com> Acked-by: Philippe Cornu <philippe.co...@st.com> (for stm) Tested-by: Philippe Cornu <philippe.co...@st.com> (for stm) --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 ++- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 36 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 5 +++- drivers/gpu/drm/i915/intel_sprite.c | 4 +-- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++-- drivers/gpu/drm/omapdrm/omap_plane.c| 2 +- drivers/gpu/drm/pl111/pl111_display.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +-- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/sun4i/sun8i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 - drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +-- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 22 ++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 45 files changed, 131 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 1859dd3ad622..799416651f2f 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -217,6 +217,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 16e1e20cf04c..72b22b805412 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/malid
[PATCH 2/6] drm/i915: Add render decompression support
From: Ville Syrjälä <ville.syrj...@linux.intel.com> SKL+ display engine can scan out certain kinds of compressed surfaces produced by the render engine. This involved telling the display engine the location of the color control surfae (CCS) which describes which parts of the main surface are compressed and which are not. The location of CCS is provided by userspace as just another plane with its own offset. Add the required stuff to validate the user provided AUX plane metadata and convert the user provided linear offset into something the hardware can consume. Due to hardware limitations we require that the main surface and the AUX surface (CCS) be part of the same bo. The hardware also makes life hard by not allowing you to provide separate x/y offsets for the main and AUX surfaces (excpet with NV12), so finding suitable offsets for both requires a bit of work. Assuming we still want keep playing tricks with the offsets. I've just gone with a dumb "search backward for suitable offsets" approach, which is far from optimal, but it works. Also not all planes will be capable of scanning out compressed surfaces, and eg. 90/270 degree rotation is not supported in combination with decompression either. This patch may contain work from at least the following people: * Vandana Kannan <vandana.kan...@intel.com> * Daniel Vetter <dan...@ffwll.ch> * Ben Widawsky <b...@bwidawsk.net> v2: Deal with display workarounds 0390, 0531, 1125 (Paulo) v3: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason) Put the AUX register defines to the correct place Fix up the slightly bogus rotation check v4: Use I915_WRITE_FW() due to plane update locking changes s/return -EINVAL/goto err/ in intel_framebuffer_init() Eliminate a bunch hardcoded numbers in CCS code v5: (By Ben) conflict resolution + - res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum); + res_blocks += fixed16_to_u32_round_up(y_tile_minimum); Cc: Paulo Zanoni <paulo.r.zan...@intel.com> Cc: Daniel Vetter <dan...@ffwll.ch> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Signed-off-by: Ville Syrjä <ville.syrj...@linux.intel.com> Reviewed-by: Ben Widawsky <b...@bwidawsk.net> (v1) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/i915_reg.h | 23 drivers/gpu/drm/i915/intel_display.c | 233 --- drivers/gpu/drm/i915/intel_pm.c | 29 - drivers/gpu/drm/i915/intel_sprite.c | 5 + 4 files changed, 272 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1dc7e7a2a23b..c2a6c107f551 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6134,6 +6134,10 @@ enum { #define _PLANE_KEYMSK_2_A 0x70298 #define _PLANE_KEYMAX_1_A 0x701a0 #define _PLANE_KEYMAX_2_A 0x702a0 +#define _PLANE_AUX_DIST_1_A0x701c0 +#define _PLANE_AUX_DIST_2_A0x702c0 +#define _PLANE_AUX_OFFSET_1_A 0x701c4 +#define _PLANE_AUX_OFFSET_2_A 0x702c4 #define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */ #define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */ #define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ @@ -6240,6 +6244,24 @@ enum { #define PLANE_NV12_BUF_CFG(pipe, plane)\ _MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe)) +#define _PLANE_AUX_DIST_1_B0x711c0 +#define _PLANE_AUX_DIST_2_B0x712c0 +#define _PLANE_AUX_DIST_1(pipe) \ + _PIPE(pipe, _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B) +#define _PLANE_AUX_DIST_2(pipe) \ + _PIPE(pipe, _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B) +#define PLANE_AUX_DIST(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe)) + +#define _PLANE_AUX_OFFSET_1_B 0x711c4 +#define _PLANE_AUX_OFFSET_2_B 0x712c4 +#define _PLANE_AUX_OFFSET_1(pipe) \ + _PIPE(pipe, _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B) +#define _PLANE_AUX_OFFSET_2(pipe) \ + _PIPE(pipe, _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B) +#define PLANE_AUX_OFFSET(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe)) + #define _PLANE_COLOR_CTL_1_B 0x711CC #define _PLANE_COLOR_CTL_2_B 0x712CC #define _PLANE_COLOR_CTL_3_B 0x713CC @@ -6723,6 +6745,7 @@ enum { # define CHICKEN3_DGMG_DONE_FIX_DISABLE(1 << 2) #define CHICKE
[PATCH 1/6] drm/i915: Implement .get_format_info() hook for CCS
From: Ville Syrjälä <ville.syrj...@linux.intel.com> SKL+ display engine can scan out certain kinds of compressed surfaces produced by the render engine. This involved telling the display engine the location of the color control surfae (CCS) which describes which parts of the main surface are compressed and which are not. The location of CCS is provided by userspace as just another plane with its own offset. By providing our own format information for the CCS formats, we should be able to make framebuffer_check() do the right thing for the CCS surface as well. Note that we'll return the same format info for both Y and Yf tiled format as that's what happens with the non-CCS Y vs. Yf as well. If desired, we could potentially return a unique pointer for each pixel_format+tiling+ccs combination, in which case we immediately be able to tell if any of that stuff changed by just comparing the pointers. But that does sound a bit wasteful space wise. v2: Drop the 'dev' argument from the hook v3: Include the description of the CCS surface layout v4: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason) Cc: Daniel Vetter <dan...@ffwll.ch> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Reviewed-by: Ben Widawsky <b...@bwidawsk.net> (v3) Signed-off-by: Ville Syrjä <ville.syrj...@linux.intel.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/drm_fourcc.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 37 include/drm/drm_mode_config.h| 3 ++- include/uapi/drm/drm_fourcc.h| 3 +++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c index 9c0152df45ad..50da6180c495 100644 --- a/drivers/gpu/drm/drm_fourcc.c +++ b/drivers/gpu/drm/drm_fourcc.c @@ -222,7 +222,7 @@ drm_get_format_info(struct drm_device *dev, const struct drm_format_info *info = NULL; if (dev->mode_config.funcs->get_format_info) - info = dev->mode_config.funcs->get_format_info(mode_cmd); + info = dev->mode_config.funcs->get_format_info(dev, mode_cmd); if (!info) info = drm_format_info(mode_cmd->pixel_format); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f93d9a13b13a..0e71c7207258 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2428,6 +2428,42 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier) } } +static const struct drm_format_info ccs_formats[] = { + { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, + { .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, + { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, + { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 16, .vsub = 8, }, +}; + +static const struct drm_format_info * +lookup_format_info(const struct drm_format_info formats[], + int num_formats, u32 format) +{ + int i; + + for (i = 0; i < num_formats; i++) { + if (formats[i].format == format) + return [i]; + } + + return NULL; +} + +static const struct drm_format_info * +intel_get_format_info(struct drm_device *dev, + const struct drm_mode_fb_cmd2 *cmd) +{ + switch (cmd->modifier[0]) { + case I915_FORMAT_MOD_Y_TILED_CCS: + case I915_FORMAT_MOD_Yf_TILED_CCS: + return lookup_format_info(ccs_formats, + ARRAY_SIZE(ccs_formats), + cmd->pixel_format); + default: + return NULL; + } +} + static int intel_fill_fb_info(struct drm_i915_private *dev_priv, struct drm_framebuffer *fb) @@ -13675,6 +13711,7 @@ static void intel_atomic_state_free(struct drm_atomic_state *state) static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_create = intel_user_framebuffer_create, + .get_format_info = intel_get_format_info, .output_poll_changed = intel_fbdev_output_poll_changed, .atomic_check = intel_atomic_check, .atomic_commit = intel_atomic_commit, diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 42981711189b..f0d3d3857ae2 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -81,7 +81,8 @@ struct drm_mode_config_funcs { * The format information specific to the given fb metadata, or * NULL if none is found. */ - const struct drm_format_info *(*get_format_info)(const s
[PATCH 2/4] drm: Create a format/modifier blob
Updated blob layout (Rob, Daniel, Kristian, xerpi) v2: * Removed __packed, and alignment (.+) * Fix indent in drm_format_modifier fields (Liviu) * Remove duplicated modifier > 64 check (Liviu) * Change comment about modifier (Liviu) * Remove arguments to blob creation, use plane instead (Liviu) * Fix data types (Ben) * Make the blob part of uapi (Daniel) v3: Remove unused ret field. Change i, and j to unsigned int (Emil) v4: Use plane->modifier_count instead of recounting (Daniel) v5: Rename modifiers to modifiers_property (Ville) Use sizeof(__u32) instead to reflect UAPI nature (Ville) Make BUILD_BUG_ON for blob header size Cc: Rob Clark <robdcl...@gmail.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <li...@dudau.co.uk> (v2) Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v3) --- drivers/gpu/drm/drm_mode_config.c | 7 drivers/gpu/drm/drm_plane.c | 84 +++ include/drm/drm_mode_config.h | 6 +++ include/uapi/drm/drm_mode.h | 50 +++ 4 files changed, 147 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..74f6ff5df656 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers_property = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index d3fc561d7b48..5c14beee52ff 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +{ + const struct drm_mode_config *config = >mode_config; + struct drm_property_blob *blob; + struct drm_format_modifier *mod; + size_t blob_size, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + unsigned int i, j; + + formats_size = sizeof(__u32) * plane->format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * plane->modifier_count; + + blob_size = sizeof(struct drm_format_modifier_blob); + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = plane->format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = plane->modifier_count; + + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), plane->format_types, formats_size); + + /* If we can't determine support, just bail */ + if (!plane->funcs->format_mod_supported) + goto done; + + mod = modifiers_ptr(blob_data); + for (i = 0; i < plane->modifier_count; i++) { + for (j = 0; j < plane->format_count; j++) { + if (plane->funcs->format_mod_supported(plane, + plane->format_types[j], + plane->modifiers[i])) { + + mod->formats |= 1 << j; + } + } + + mod->modifier = plane->modifiers[i]; +
[PATCH 3/4] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) v6: - Actually use the sprite funcs (Emil) - Use unreachable (Emil) v7: - Only allow Intel modifiers and LINEAR (Ben) v8 - Fix spite assert introduced in v6 (Daniel) v9 - Change vendor check logic to avoid magic 56 (Emil) - Reorder skl_mod_support (Ville) - make intel_plane_funcs static, could be done as of v5 (Ville) - rename local variable intel_format_modifiers to modifiers (Ville) - actually use sprite modifiers - split out modifier/formats by platform (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v8) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 127 +-- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_sprite.c | 141 ++- 3 files changed, 259 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 28e5f350db02..34c37f82acb2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -67,6 +67,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -82,11 +88,24 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, }; +static const uint64_t cursor_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); static void ironlake_pch_clock_get(struct intel_crtc *crtc, @@ -12806,7 +12825,98 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } -const struct drm_plane_funcs intel_plane_funcs = { +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + if (modifier == I915_FORMAT_MOD_Yf_TILED) + return true; + /* fall through */ + case DRM_FORMAT_C8: + if (modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED || + modifier == I915_FORMAT_MOD_Y_TILED) + return true; + /* fall through */ + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +
[PATCH 1/4] drm: Plumb modifiers through plane init
This is the plumbing for supporting fb modifiers on planes. Modifiers have already been introduced to some extent, but this series will extend this to allow querying modifiers per plane. Based on this, the client to enable optimal modifications for framebuffers. This patch simply allows the DRM drivers to initialize their list of supported modifiers upon initializing the plane. v2: A minor addition from Daniel v3: * Updated commit message * s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu) * Remove some excess newlines (Liviu) * Update comment for > 64 modifiers (Liviu) v4: Minor comment adjustments (Liviu) v5: Some new platforms added due to rebase v6: Add some missed plane inits (or maybe they're new - who knows at this point) (Daniel) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <liviu.du...@arm.com> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 ++- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 36 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 5 +++- drivers/gpu/drm/i915/intel_sprite.c | 4 +-- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++-- drivers/gpu/drm/omapdrm/omap_plane.c| 2 +- drivers/gpu/drm/pl111/pl111_display.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +-- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 - drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +-- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 22 ++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 44 files changed, 130 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 1859dd3ad622..799416651f2f 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -217,6 +217,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 16e1e20cf04c..72b22b805412 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 600fa7bd7f52..60402e27882f 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -398,7 +398,7 @@ int malidp_
[PATCH 4/4] drm/i915: Add support for CCS modifiers
v2: Support sprite plane. Support pipe C/D limitation on GEN9. v3: Rename structure (Ville) Handle GLK (Ville) This requires rebase on the correct Ville patches Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 30 +++--- drivers/gpu/drm/i915/intel_sprite.c | 25 - 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 34c37f82acb2..44747ed9ee38 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -88,7 +88,17 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; -static const uint64_t skl_format_modifiers[] = { +static const uint64_t skl_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +static const uint64_t skl_format_modifiers_ccs[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -12862,6 +12872,10 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: + if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_CCS) + return true; + /* fall through */ case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: @@ -13108,10 +13122,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + intel_primary_formats = skl_primary_formats; + num_formats = ARRAY_SIZE(skl_primary_formats); + modifiers = skl_format_modifiers_ccs; + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; + } else if (INTEL_GEN(dev_priv) >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); - modifiers = skl_format_modifiers; + if (pipe >= PIPE_C) + modifiers = skl_format_modifiers_ccs; + else + modifiers = skl_format_modifiers_noccs; primary->update_plane = skylake_update_primary_plane; primary->disable_plane = skylake_disable_primary_plane; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 05a15063ee97..97d29cc061ad 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1079,7 +1079,17 @@ static uint32_t skl_plane_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_plane_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_plane_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -1224,7 +1234,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, } intel_plane->base.state = >base; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10) { intel_plane->can_scale = true; state->scaler_id = -1; @@ -1234,6 +1244,19 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, plane_formats = skl_plane_formats; num_plane_formats = ARRAY_SIZE(skl_plane_formats); modifiers = skl_plane_format_modifiers; + } else if (INTEL_GEN(dev_priv) >= 9) { + intel_plane->can_scale = true; + state->scaler_id = -1; + + intel_plane->update_plane = skl_update_plane; + intel_plane->disable_plane = skl_disable_plane; + + plane_formats = skl_plane_formats; + num_plane_formats = ARRAY_SIZE(skl_plane_formats); + if (pipe >= PIPE_C) + modifiers = skl_plane_format_modifiers_noccs; + else + modifiers = skl_plane_fo
[PATCH 0/4] [v2] Blobifiers (FKA GET_PLANE2)
Second attempt (although most patches are much further along than that) and the blob property for modifiers. This small series adds the DRM blob property that allows clients to be made aware of per plane modifiers and the formats which are supported in conjunction with those modifiers. This interface will allow clients to create buffers for scanout with a good set of modifiers, and later import those buffers (through EGL already, and Vulkan WSI later) into a graphics runtime. EGL/WSI will provide similar interfaces for rendering - modifiers which can be used for rendering. Ben Widawsky (4): drm: Plumb modifiers through plane init drm: Create a format/modifier blob drm/i915: Add format modifiers for Intel drm/i915: Add support for CCS modifiers drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 +- drivers/gpu/drm/drm_mode_config.c | 7 + drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 120 +- drivers/gpu/drm/drm_simple_kms_helper.c | 3 + drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 148 +- drivers/gpu/drm/i915/intel_drv.h| 1 - drivers/gpu/drm/i915/intel_sprite.c | 162 +++- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 2 +- drivers/gpu/drm/pl111/pl111_display.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 +- drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_mode_config.h | 6 + include/drm/drm_plane.h | 22 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 ++ include/uapi/drm/drm_mode.h | 50 48 files changed, 576 insertions(+), 52 deletions(-) -- 2.13.3 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/4] drm/i915: Add support for CCS modifiers
On 17-06-29 23:02:08, Ville Syrjälä wrote: On Fri, Jun 23, 2017 at 09:45:44AM -0700, Ben Widawsky wrote: v2: Support sprite plane. Support pipe C/D limitation on GEN9. This requires rebase on the correct Ville patches Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 34 +-- drivers/gpu/drm/i915/intel_sprite.c | 39 +++- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 877a51514c61..2a0e5cd26059 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -93,7 +93,17 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_format_modifiers[] = { Maybe calls this _ccs[] then? + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -13872,17 +13882,13 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) return false; } case DRM_FORMAT_RGB565: - case DRM_FORMAT_XRGB: - case DRM_FORMAT_XBGR: - case DRM_FORMAT_ARGB: - case DRM_FORMAT_ABGR: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: case DRM_FORMAT_UYVY: case DRM_FORMAT_VYUY: - /* All i915 modifiers are fine */ + /* All non-ccs i915 modifiers are fine */ switch (modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: @@ -13892,6 +13898,12 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) default: return false; } + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + /* All i915 modifiers are fine */ + return true; default: return false; } @@ -14123,13 +14135,23 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); intel_format_modifiers = skl_format_modifiers; primary->update_plane = skylake_update_primary_plane; primary->disable_plane = skylake_disable_primary_plane; + } else if (INTEL_GEN(dev_priv) >= 9) { + intel_primary_formats = skl_primary_formats; + num_formats = ARRAY_SIZE(skl_primary_formats); + if (pipe >= PIPE_C) I think I'd keep the gen10 stuff in the same branch still. Also this misses GLK. So maybe something like this: if (GEN >= 10 || IS_GLK || pipe != PIPE_C) I'd really like to keep the pipe C limitation in the gen9 block, but yes, it was missing GLK. (Patches were originally written before GLK, I believe) Thanks for catching that. I really suspect we're going to need to split display version out of INTEL_GEN. Maybe you guys are already doing this. I'm fine with ccs rename, and you were right in the previous patch about how reorganizing made this diff nicer. + intel_format_modifiers = skl_format_modifiers; + else + intel_format_modifiers = skl_format_modifiers_noccs; + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; } else if (INTEL_GEN(dev_priv) >= 4) { intel_primary_formats = i965_primary_formats; num_formats = ARRAY_SIZE(i965_primary_formats); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index e80834cb1f4c..de4454a8ef9e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1085,7 +1085,17 @@ static uint32_t skl_plane_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_plane_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, +
Re: [Intel-gfx] [PATCH 2/4] drm: Create a format/modifier blob
On 17-07-14 22:10:15, Ville Syrjälä wrote: On Fri, Jul 14, 2017 at 11:41:49AM -0700, Ben Widawsky wrote: On 17-06-29 22:49:44, Ville Syrjälä wrote: [snip] > >... but here it's ALIGN(formats_offset+formats_size). I think we should >be aligning the same thing in both cases, or we add a BUILD_BUG_ON to >make sure the header size always stays a multiple of 8 bytes. > >That's mainly because the design of the structure seems geared towards >expanding the header in the future (as in why else would you have the >offsets?). > I guess I don't quite understand what you're asking for. The first thing is determining a size, the second is finding an offset into the blob. If I remember my thinking correctly, then what I was trying to say was ALIGN(multiple_of_4, 8) + ALIGN(multiple_of_4, 8) != ALIGN(multiple_of_4 + multiple_of_4, 8) but the code was assuming that it's true, or that at least one of those things is a multiple of 8 already. Going with this and calling it sufficient. diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 0da6707a8cf7..5c14beee52ff 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -96,6 +96,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane /* Modifiers offset is a pointer to a struct with a 64 bit field so it * should be naturally aligned to 8B. */ + BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8); blob_size += ALIGN(formats_size, 8); blob_size += modifiers_size; I don't mind changing this, but tell me what you want. BUILD_BUG_ON sounds good to me regardless. [snip] -- Ben Widawsky, Intel Open Source Technology Center -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 2/4] drm: Create a format/modifier blob
On 17-06-29 22:49:44, Ville Syrjälä wrote: [snip] ... but here it's ALIGN(formats_offset+formats_size). I think we should be aligning the same thing in both cases, or we add a BUILD_BUG_ON to make sure the header size always stays a multiple of 8 bytes. That's mainly because the design of the structure seems geared towards expanding the header in the future (as in why else would you have the offsets?). I guess I don't quite understand what you're asking for. The first thing is determining a size, the second is finding an offset into the blob. I don't mind changing this, but tell me what you want. BUILD_BUG_ON sounds good to me regardless. [snip] -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/4] drm: Create a format/modifier blob
Updated blob layout (Rob, Daniel, Kristian, xerpi) v2: * Removed __packed, and alignment (.+) * Fix indent in drm_format_modifier fields (Liviu) * Remove duplicated modifier > 64 check (Liviu) * Change comment about modifier (Liviu) * Remove arguments to blob creation, use plane instead (Liviu) * Fix data types (Ben) * Make the blob part of uapi (Daniel) v3: Remove unused ret field. Change i, and j to unsigned int (Emil) v4: Use plane->modifier_count instead of recounting (Daniel) Cc: Rob Clark <robdcl...@gmail.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <li...@dudau.co.uk> (v2) Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> (v3) --- drivers/gpu/drm/drm_mode_config.c | 7 drivers/gpu/drm/drm_plane.c | 83 +++ include/drm/drm_mode_config.h | 6 +++ include/uapi/drm/drm_mode.h | 50 +++ 4 files changed, 146 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..6bfbc3839df5 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index d3fc561d7b48..8a2d5765837a 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,86 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +{ + const struct drm_mode_config *config = >mode_config; + struct drm_property_blob *blob; + struct drm_format_modifier *mod; + size_t blob_size, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + unsigned int i, j; + + formats_size = sizeof(*plane->format_types) * plane->format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * plane->modifier_count; + + blob_size = sizeof(struct drm_format_modifier_blob); + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = plane->format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = plane->modifier_count; + + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), plane->format_types, formats_size); + + /* If we can't determine support, just bail */ + if (!plane->funcs->format_mod_supported) + goto done; + + mod = modifiers_ptr(blob_data); + for (i = 0; i < plane->modifier_count; i++) { + for (j = 0; j < plane->format_count; j++) { + if (plane->funcs->format_mod_supported(plane, + plane->format_types[j], + plane->modifiers[i])) { + + mod->formats |= 1 << j; + } + } + + mod->modifier = plane->modifiers[i]; + mod->offset = 0; + mod->pad = 0; + mod++; + } + +done: + drm_object_attach_property(>base, config->modifiers, +
[PATCH v4 0/4] Blobifiers (FKA GET_PLANE2)
These patches create the blob property for modifiers, and the implementation for i915 modifiers. This [generally] has been tested in Weston by Daniel Stone as well as an earlier version of kmscube. This patch series was formerly known as "GET_PLANE2" because the interface for obtaining the modifiers was extended throug GET_PLANE instead of a blob property. The modifier blob (blobifier) presents a list of modifiers per plane, and a related bitmask [1] back to userspace, via KMS, so that a client such as a compositor may utilize those modifiers for buffer creation via GBM, or buffer import via dmabuf/EGL. All vendors may optimize via their supported modifiers. For Intel, this is one of the pieces required to support end to end lossless compression (a memory bandwidth saving technique semi-common across GPUs). I do apologize if I missed some previous review comments. A ton of things came up and it took a while to spin this rev. Nothing was missing intentionally. [1] The bitmask is used to show the connection between which modifiers are supported by which formats. Ben Widawsky (4): drm: Plumb modifiers through plane init drm: Create a format/modifier blob drm/i915: Add format modifiers for Intel drm/i915: Add support for CCS modifiers drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 +- drivers/gpu/drm/drm_mode_config.c | 7 ++ drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 119 +- drivers/gpu/drm/drm_simple_kms_helper.c | 3 + drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 155 +++- drivers/gpu/drm/i915/intel_sprite.c | 117 +- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 2 +- drivers/gpu/drm/pl111/pl111_display.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 +- drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_mode_config.h | 6 + include/drm/drm_plane.h | 22 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 ++ include/uapi/drm/drm_mode.h | 50 47 files changed, 539 insertions(+), 49 deletions(-) -- 2.13.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/4] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) v6: - Actually use the sprite funcs (Emil) - Use unreachable (Emil) v7: - Only allow Intel modifiers and LINEAR (Ben) v8 - Fix spite assert introduced in v6 (Daniel) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Cc: Emil Velikov <emil.l.veli...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 136 +-- drivers/gpu/drm/i915/intel_sprite.c | 82 - 2 files changed, 211 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7d55c5e3df28..877a51514c61 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,11 +93,24 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, }; +static const uint64_t cursor_format_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); static void ironlake_pch_clock_get(struct intel_crtc *crtc, @@ -13810,6 +13829,108 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + return true; + default: + return false; + } + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + /* All i915 modifiers are fine */ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return true; + default: + return false; + } + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + +
[PATCH 4/4] drm/i915: Add support for CCS modifiers
v2: Support sprite plane. Support pipe C/D limitation on GEN9. This requires rebase on the correct Ville patches Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 34 +-- drivers/gpu/drm/i915/intel_sprite.c | 39 +++- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 877a51514c61..2a0e5cd26059 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -93,7 +93,17 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -13872,17 +13882,13 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) return false; } case DRM_FORMAT_RGB565: - case DRM_FORMAT_XRGB: - case DRM_FORMAT_XBGR: - case DRM_FORMAT_ARGB: - case DRM_FORMAT_ABGR: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: case DRM_FORMAT_UYVY: case DRM_FORMAT_VYUY: - /* All i915 modifiers are fine */ + /* All non-ccs i915 modifiers are fine */ switch (modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: @@ -13892,6 +13898,12 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) default: return false; } + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + /* All i915 modifiers are fine */ + return true; default: return false; } @@ -14123,13 +14135,23 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - if (INTEL_GEN(dev_priv) >= 9) { + if (INTEL_GEN(dev_priv) >= 10) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); intel_format_modifiers = skl_format_modifiers; primary->update_plane = skylake_update_primary_plane; primary->disable_plane = skylake_disable_primary_plane; + } else if (INTEL_GEN(dev_priv) >= 9) { + intel_primary_formats = skl_primary_formats; + num_formats = ARRAY_SIZE(skl_primary_formats); + if (pipe >= PIPE_C) + intel_format_modifiers = skl_format_modifiers; + else + intel_format_modifiers = skl_format_modifiers_noccs; + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; } else if (INTEL_GEN(dev_priv) >= 4) { intel_primary_formats = i965_primary_formats; num_formats = ARRAY_SIZE(i965_primary_formats); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index e80834cb1f4c..de4454a8ef9e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1085,7 +1085,17 @@ static uint32_t skl_plane_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_plane_format_modifiers_noccs[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint64_t skl_plane_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, @@ -1108,6 +1118,20 @@ static bool intel_sprite_plane_format_mod_supported(struct drm_plane *plane, modifier != DRM_FORMAT_MOD_LINEAR) return false; + switch (modifier) { + case I915_FORMAT_MOD_Yf_TILED_CCS: + case I915_FORMAT_MOD_Y_TILED_CCS: + switch (format) { + case DRM_FORMAT_ABGR: + case DRM_FORMAT_ARGB: +
[PATCH 1/4] drm: Plumb modifiers through plane init
This is the plumbing for supporting fb modifiers on planes. Modifiers have already been introduced to some extent, but this series will extend this to allow querying modifiers per plane. Based on this, the client to enable optimal modifications for framebuffers. This patch simply allows the DRM drivers to initialize their list of supported modifiers upon initializing the plane. v2: A minor addition from Daniel v3: * Updated commit message * s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu) * Remove some excess newlines (Liviu) * Update comment for > 64 modifiers (Liviu) v4: Minor comment adjustments (Liviu) v5: Some new platforms added due to rebase v6: Add some missed plane inits (or maybe they're new - who knows at this point) (Daniel) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Reviewed-by: Liviu Dudau <liviu.du...@arm.com> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 3 ++- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 36 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 5 +++- drivers/gpu/drm/i915/intel_sprite.c | 4 +-- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++-- drivers/gpu/drm/omapdrm/omap_plane.c| 2 +- drivers/gpu/drm/pl111/pl111_display.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +-- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 - drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 2 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +-- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 22 ++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 44 files changed, 130 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 611af74a31c0..d0e3671a71ed 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -217,6 +217,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 1a3359c0f6cd..9b9c0913f55f 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -320,6 +320,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 600fa7bd7f52..60402e27882f 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -398,7 +398,7 @@ int malidp_
Re: [PATCH v5 3/3] drm/i915: Add format modifiers for Intel
On 17-05-17 01:20:50, Emil Velikov wrote: Hi Ben, A couple of small questions/suggestions that I hope you find useful. Please don't block any of this work based on my comments. On 16 May 2017 at 22:31, Ben Widawsky <b...@bwidawsk.net> wrote: +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + if (INTEL_GEN(dev_priv) >= 9) + return skl_mod_supported(format, modifier); + else if (INTEL_GEN(dev_priv) >= 4) + return i965_mod_supported(format, modifier); + else + return i8xx_mod_supported(format, modifier); + Nit: if you rewrite this as below, the control flow should be clearer. Thus the 'return false;' at the end, will be [more] obvious that it's unreachable ;-) if (INTEL_GEN(dev_priv) >= 9) return skl_mod_supported(format, modifier); if (INTEL_GEN(dev_priv) >= 4) return i965_mod_supported(format, modifier); return i8xx_mod_supported(format, modifier); It's a good point, however many other blocks of code do the same thing, and I think the nature of if/else if/else implies unreachable. I can add unreachable()... In fact, I just did. + return false; +} + --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c +static bool intel_sprite_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + BUG_ON(plane->base.type != DRM_PLANE_TYPE_OVERLAY); + + switch (format) { + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + return true; + break; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_ARGB: + if (INTEL_GEN(dev_priv) >= 9 || IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + return true; + break; + case DRM_FORMAT_XBGR: + if (INTEL_GEN(dev_priv) >= 6) + return true; + break; + case DRM_FORMAT_XRGB: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + return true; + } + + return false; +} + +const struct drm_plane_funcs intel_sprite_plane_funcs = { +.update_plane = drm_atomic_helper_update_plane, +.disable_plane = drm_atomic_helper_disable_plane, +.destroy = intel_plane_destroy, +.set_property = drm_atomic_helper_plane_set_property, +.atomic_get_property = intel_plane_atomic_get_property, +.atomic_set_property = intel_plane_atomic_set_property, +.atomic_duplicate_state = intel_plane_duplicate_state, +.atomic_destroy_state = intel_plane_destroy_state, +.format_mod_supported = intel_sprite_plane_format_mod_supported, +}; + Having a dull moment - is intel_sprite_plane_funcs (+ intel_sprite_plane_format_mod_supported) unused or I'm seeing things? If one is to keep it, for future work, perhaps it's worth adding a 2-3 word comment, Regards, Emil Not sure how this happened, it is a mistake. Thanks for spotting it. Here's what I got locally: diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3519c10abcc3..a8f4c5783ec2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13479,7 +13479,7 @@ static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, else return i8xx_mod_supported(format, modifier); - return false; + unreachable(); } static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index e7c5c0a94bbd..1d582b436b59 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1233,7 +1233,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, if (INTEL_GEN(dev_priv) >= 9) ret = drm_universal_
Re: [Intel-gfx] [PATCH v2 2/3] drm: Create a format/modifier blob
On 17-05-17 01:06:16, Emil Velikov wrote: Hi Ben, On 16 May 2017 at 22:31, Ben Widawsky <b...@bwidawsk.net> wrote: Updated blob layout (Rob, Daniel, Kristian, xerpi) v2: * Removed __packed, and alignment (.+) * Fix indent in drm_format_modifier fields (Liviu) * Remove duplicated modifier > 64 check (Liviu) * Change comment about modifier (Liviu) * Remove arguments to blob creation, use plane instead (Liviu) * Fix data types (Ben) * Make the blob part of uapi (Daniel) Cc: Rob Clark <robdcl...@gmail.com> Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Cc: Liviu Dudau <li...@dudau.co.uk> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> I think this is almost perfect, barring the UAPI nitpick. The rest is somewhat of a bikeshedding. With the UAPI resolved, regardless of the rest Reviewed-by: Emil Velikov <emil.l.veli...@gmail.com> --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +{ + const struct drm_mode_config *config = >mode_config; + const uint64_t *temp_modifiers = plane->modifiers; + unsigned int format_modifier_count = 0; + struct drm_property_blob *blob = NULL; + struct drm_format_modifier *mod; + size_t blob_size = 0, formats_size, modifiers_size; There's no need to initialize blob and blob_size here. + struct drm_format_modifier_blob *blob_data; + int i, j, ret = 0; Make i and j unsigned to match format_modifier_count and plane->format_count respectively. Then expand ret in the only place where it's used? Oh. ret has lost it's utility over the iterations of this patch. Make i and j unsigned and dropped ret. + + if (plane->modifiers) + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + + formats_size = sizeof(*plane->format_types) * plane->format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * format_modifier_count; + + blob_size = sizeof(struct drm_format_modifier_blob); + blob_size += ALIGN(formats_size, 8); Worth having the "Modifiers offset is a pointer..." comment moved/copied here? Yes it is. + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + Maybe propagate the exact error... Hmm we don't seem to check if create_in_format_blob fails either so perhaps it's not worth it. In this case it's almost definitely ENOMEM. All values should be verified - I think the other errors are there for when userspace is utilizing blob creation. So I'll just leave it. --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -665,6 +665,56 @@ struct drm_mode_atomic { __u64 user_data; }; +struct drm_format_modifier_blob { +#define FORMAT_BLOB_CURRENT 1 + /* Version of this blob format */ + u32 version; + + /* Flags */ + u32 flags; + + /* Number of fourcc formats supported */ + u32 count_formats; + + /* Where in this blob the formats exist (in bytes) */ + u32 formats_offset; + + /* Number of drm_format_modifiers */ + u32 count_modifiers; + + /* Where in this blob the modifiers exist (in bytes) */ + u32 modifiers_offset; + + /* u32 formats[] */ + /* struct drm_format_modifier modifiers[] */ +}; + +struct drm_format_modifier { + /* Bitmask of formats in get_plane format list this info applies to. The +* offset allows a sliding window of which 64 formats (bits). +* +* Some examples: +* In today's world with < 65 formats, and formats 0, and 2 are +* supported +* 0x0005 +*^-offset = 0, formats = 5 +* +* If the number formats grew to 128, and formats 98-102 are +* supported with the modifier: G>> +* +* 0x003c +*^ +*|__offset = 64, formats = 0x3c +* +*/ + __u64 formats; + __u32 offset; + __u32 pad; + + /* The modifier that applies to the >get_plane format list bitmask. */ + __u64 modifier; Please drop the leading __ from the type names in UAPI headers. Many other structures have the __, can you explain why please (this has probably been beaten to death already; but I don't know)? Regards, Emil -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 2/3] drm: Create a format/modifier blob
On 17-05-17 13:31:44, Daniel Vetter wrote: On Tue, May 16, 2017 at 02:19:12PM -0700, Ben Widawsky wrote: On 17-05-03 17:08:27, Daniel Vetter wrote: > On Tue, May 02, 2017 at 10:14:27PM -0700, Ben Widawsky wrote: > > +struct drm_format_modifier_blob { > > +#define FORMAT_BLOB_CURRENT 1 > > + /* Version of this blob format */ > > + u32 version; > > + > > + /* Flags */ > > + u32 flags; > > + > > + /* Number of fourcc formats supported */ > > + u32 count_formats; > > + > > + /* Where in this blob the formats exist (in bytes) */ > > + u32 formats_offset; > > + > > + /* Number of drm_format_modifiers */ > > + u32 count_modifiers; > > + > > + /* Where in this blob the modifiers exist (in bytes) */ > > + u32 modifiers_offset; > > + > > + /* u32 formats[] */ > > + /* struct drm_format_modifier modifiers[] */ > > +} __packed; > > The struct should be in the uapi header. Otherwise it won't show up in > libdrm headers when following the proper process. > -Daniel > I don't agree that blobs are ever really part of the API, but it doesn't hurt to move it... in other words, done. Userspace writes them, the kernel reads them (or maybe even the other way round). How exactly is a specific blob and its layout not part of uapi? Can you explain your reasoning here pls? -Daniel The API says there is a blob. If we wanted the fields in the blob to be explicit we'd make an API that has the exact structure. -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/3] drm: Plumb modifiers through plane init
This is the plumbing for supporting fb modifiers on planes. Modifiers have already been introduced to some extent, but this series will extend this to allow querying modifiers per plane. Based on this, the client to enable optimal modifications for framebuffers. This patch simply allows the DRM drivers to initialize their list of supported modifiers upon initializing the plane. v2: A minor addition from Daniel v3: Updated commit message s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu) Remove some excess newlines (Liviu) Update comment for > 64 modifiers (Liviu) Cc: Liviu Dudau <liviu.du...@arm.com> Reviewed-by: Daniel Stone <dani...@collabora.com> (v2) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 ++- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 35 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 5 +++- drivers/gpu/drm/i915/intel_sprite.c | 4 +-- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++-- drivers/gpu/drm/omapdrm/omap_plane.c| 3 ++- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +-- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 - drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 +-- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 20 +- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 41 files changed, 126 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a95916f1f..cd8a24c7c67d 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 798a3cc480a2..0caa03ae8708 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -303,6 +303,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { devm_kfree(drm->dev, plane); diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 814fda23cead..b156610c68a5 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -400,7 +400,7 @@ int malidp_de_planes_init(struct drm_device *drm) DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(drm, >base, crtcs, _de_plane_funcs, formats, - n, plane_type, NULL); +
[PATCH v2 2/3] drm: Create a format/modifier blob
Updated blob layout (Rob, Daniel, Kristian, xerpi) v2: * Removed __packed, and alignment (.+) * Fix indent in drm_format_modifier fields (Liviu) * Remove duplicated modifier > 64 check (Liviu) * Change comment about modifier (Liviu) * Remove arguments to blob creation, use plane instead (Liviu) * Fix data types (Ben) * Make the blob part of uapi (Daniel) Cc: Rob Clark <robdcl...@gmail.com> Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Cc: Liviu Dudau <li...@dudau.co.uk> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> Reviewed-by: Daniel Stone <dani...@collabora.com> --- drivers/gpu/drm/drm_mode_config.c | 7 +++ drivers/gpu/drm/drm_plane.c | 89 +++ include/drm/drm_mode_config.h | 6 +++ include/uapi/drm/drm_mode.h | 50 ++ 4 files changed, 152 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..6bfbc3839df5 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 20203871e06d..f5b032b5f761 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,92 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane) +{ + const struct drm_mode_config *config = >mode_config; + const uint64_t *temp_modifiers = plane->modifiers; + unsigned int format_modifier_count = 0; + struct drm_property_blob *blob = NULL; + struct drm_format_modifier *mod; + size_t blob_size = 0, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + int i, j, ret = 0; + + if (plane->modifiers) + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + + formats_size = sizeof(*plane->format_types) * plane->format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * format_modifier_count; + + blob_size = sizeof(struct drm_format_modifier_blob); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = plane->format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = format_modifier_count; + + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), plane->format_types, formats_size); + + /* If we can't determine support, just bail */ + if (!plane->funcs->format_mod_supported) + goto done; + + mod = modifiers_ptr(blob_data); + for (i = 0; i < format_modifier_count; i++) { + for (j = 0; j < plane->format_count; j++) { + if (plane->funcs->format_mod_supported(plane, + plane->format_types[j], + plane->modifiers[i])) { + + mod->formats |= 1 << j; + } + } + + mod->modifier = plane->modifiers[i]; + mod->offset = 0; + mod->pad = 0; + mod++; + } + +done: + drm_object_at
[PATCH v5 3/3] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 131 +-- drivers/gpu/drm/i915/intel_sprite.c | 76 +++- 2 files changed, 201 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9dd67d51e7c9..3519c10abcc3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,6 +93,14 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -13381,6 +13395,103 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + return true; + default: + return false; + } + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + /* All i915 modifiers are fine */ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return true; + default: + return false; + } + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + if (INTEL_GEN(dev_priv) >= 9) + return skl_mod_supported(format, modifier); + else if (INTEL_GEN(dev_priv) >= 4) + return i965_mod_supported(format, modifier); + else + return i8xx_mod_supported(format, modifier); + + return false; +} + +static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane, +
Re: [Intel-gfx] [PATCH 2/3] drm: Create a format/modifier blob
On 17-05-03 17:08:27, Daniel Vetter wrote: On Tue, May 02, 2017 at 10:14:27PM -0700, Ben Widawsky wrote: Updated blob layout (Rob, Daniel, Kristian, xerpi) Cc: Rob Clark <robdcl...@gmail.com> Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/drm_mode_config.c | 7 +++ drivers/gpu/drm/drm_plane.c | 119 ++ include/drm/drm_mode_config.h | 6 ++ include/uapi/drm/drm_mode.h | 26 + 4 files changed, 158 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..6bfbc3839df5 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 286e183891e5..2e89e0e73435 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,117 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +struct drm_format_modifier_blob { +#define FORMAT_BLOB_CURRENT 1 + /* Version of this blob format */ + u32 version; + + /* Flags */ + u32 flags; + + /* Number of fourcc formats supported */ + u32 count_formats; + + /* Where in this blob the formats exist (in bytes) */ + u32 formats_offset; + + /* Number of drm_format_modifiers */ + u32 count_modifiers; + + /* Where in this blob the modifiers exist (in bytes) */ + u32 modifiers_offset; + + /* u32 formats[] */ + /* struct drm_format_modifier modifiers[] */ +} __packed; The struct should be in the uapi header. Otherwise it won't show up in libdrm headers when following the proper process. -Daniel I don't agree that blobs are ever really part of the API, but it doesn't hurt to move it... in other words, done. + +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane, +const struct drm_plane_funcs *funcs, +const uint32_t *formats, unsigned int format_count, +const uint64_t *format_modifiers) +{ + const struct drm_mode_config *config = >mode_config; + const uint64_t *temp_modifiers = format_modifiers; + unsigned int format_modifier_count = 0; + struct drm_property_blob *blob = NULL; + struct drm_format_modifier *mod; + size_t blob_size = 0, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + int i, j, ret = 0; + + if (format_modifiers) + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + + formats_size = sizeof(__u32) * format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * format_modifier_count; + + blob_size = ALIGN(sizeof(struct drm_format_modifier_blob), 8); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = format_modifier_count; + + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), formats, formats_size); + + /* If we can't determine support, just bail */ + if (!funcs->format_mod_supported) + goto done; + + mod = m
Re: [PATCH 2/3] drm: Create a format/modifier blob
On 17-05-03 14:15:15, Liviu Dudau wrote: On Tue, May 02, 2017 at 10:14:27PM -0700, Ben Widawsky wrote: Updated blob layout (Rob, Daniel, Kristian, xerpi) Cc: Rob Clark <robdcl...@gmail.com> Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/drm_mode_config.c | 7 +++ drivers/gpu/drm/drm_plane.c | 119 ++ include/drm/drm_mode_config.h | 6 ++ include/uapi/drm/drm_mode.h | 26 + 4 files changed, 158 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..6bfbc3839df5 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 286e183891e5..2e89e0e73435 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,117 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +struct drm_format_modifier_blob { +#define FORMAT_BLOB_CURRENT 1 + /* Version of this blob format */ + u32 version; + + /* Flags */ + u32 flags; + + /* Number of fourcc formats supported */ + u32 count_formats; + + /* Where in this blob the formats exist (in bytes) */ + u32 formats_offset; + + /* Number of drm_format_modifiers */ + u32 count_modifiers; + + /* Where in this blob the modifiers exist (in bytes) */ + u32 modifiers_offset; + + /* u32 formats[] */ + /* struct drm_format_modifier modifiers[] */ +} __packed; + +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane, +const struct drm_plane_funcs *funcs, +const uint32_t *formats, unsigned int format_count, +const uint64_t *format_modifiers) Why do you have to pass the format_modifiers again when you have plane->modifiers? Or the reverse question: why do you need plane->modifiers when you are passing the modifiers as parameters all the time? I've dropped most of the parameters here and just used plane->* +{ + const struct drm_mode_config *config = >mode_config; + const uint64_t *temp_modifiers = format_modifiers; + unsigned int format_modifier_count = 0; + struct drm_property_blob *blob = NULL; + struct drm_format_modifier *mod; + size_t blob_size = 0, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + int i, j, ret = 0; + + if (format_modifiers) + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + + formats_size = sizeof(__u32) * format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * format_modifier_count; + + blob_size = ALIGN(sizeof(struct drm_format_modifier_blob), 8); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = format_modifier_count; + + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), formats, formats_size); + + /* If we can't determine support, just bail */ + if (!funcs->format_mod_supported) +
Re: [Intel-gfx] [PATCH 1/3] drm: Plumb modifiers through plane init
On 17-05-10 18:24:52, Liviu Dudau wrote: On Wed, May 10, 2017 at 09:34:40AM -0700, Ben Widawsky wrote: On 17-05-03 18:30:07, Liviu Dudau wrote: > On Wed, May 03, 2017 at 06:45:05PM +0200, Daniel Vetter wrote: > > On Wed, May 03, 2017 at 03:52:23PM +0100, Liviu Dudau wrote: > > > On Wed, May 03, 2017 at 03:14:56PM +0100, Daniel Stone wrote: > > > > On 3 May 2017 at 15:07, Liviu Dudau <liviu.du...@arm.com> wrote: > > > > > On Wed, May 03, 2017 at 02:45:26PM +0100, Daniel Stone wrote: > > > > >> It does deserve a much better commit message than what it has, but as > > > > >> he is on holiday for the rest of the week, I can answer. Currently, we > > > > >> advertise which formats each plane is capable of displaying. In order > > > > >> for userspace to be able to allocate tiled/compressed buffers for > > > > >> scanout, we want userspace to be able to discover which modifiers each > > > > >> plane supports as well. > > > > > > > > > > I get the overall goal. We need/want something similar for Mali DP and AFBC buffers. > > > > > What I don't understand is the current aproach (but I've found from Brian that somehow > > > > > I've missed the long discussion(s) around the subject). I was hoping to learn > > > > > from the commit message why he thinks the introduction of this code is the right > > > > > way of doing it. And the IRC logs seem to imply that he is mostly doing something > > > > > that others have agreed upon and he doesn't really care about the approach as long > > > > > as it ticks the "supported by intel driver" box. > > > > > > > > Or, with another interpretation, he thinks the various approaches of > > > > doing it are all equally good. He took guidance from a couple of > > > > userspace developers (Weston, ChromeOS), a Freedreno developer and > > > > also I believe an AFBC developer, to end up where he is now, which he > > > > still thinks is fine. In doing so, he's been through several > > > > iterations, always modifying the driver to suit. I think that's a > > > > pretty good way to do development of new uABI, if you ask me. (And > > > > again, I have trouble reading your last sentence as anything other > > > > than hostile.) > > > > > > I am getting the message. You think I am too strong here, so I'm going to back off. > > > Also look forward to see the next version where he takes into account the technical > > > comments that I have sent. > > > > Just to make it really clear: Google has an implementation for AFBC using > > exactly this scheme for cros. The only reasons it's not floating around > > here in upstream is that one of the critical pieces is missing (*hint*, > > *hint* you really want an open mail driver ...). > > > Don't know about open _mail_ drivers but there are plenty of open mail apps that one can use > > > Joke aside, the Mali GPU *kernel* driver *is* open source. Just not in the mainline and > not enough for what you want. But I'm not the right person to fix all that. > > And GPU is not the only IP capable of producing AFBC data, so there might be another driver > in the making that will be open source. > > Best regards, > Liviu > > > But besides that, it works > > perfectly fine for arm render compression format too. > > -Daniel > > -- > > Daniel Vetter > > Software Engineer, Intel Corporation > > http://blog.ffwll.ch > > -- So are we good with patch 1, sorry if I missed any real valid changes I need to make, but can we please capture that here. Sure, Thanks. Reordered your comments a bit... - documentation needs to use the actual macro name: DRM_FORMAT_MOD_INVALID Okay. It originally wasn't this way because it forces the sentence to be two lines, but I've changed it. - some extraneous empty lines could be trimmed I think I got them all.. - drm_universal_plane_init comment about first driver with > 64 formats could do with some verbose explanation on why ("because we encode each format as a bit in the format_modifiers field and we have only reserved 64 bits for that") - most (all?) drivers are passing NULL as the format_modifier pointer to drm_universal_plane_init() which makes me wonder if it is not better to have a different function for drivers that want to pass a non-NULL format_modifier. I can wrap this, that might be the best way and then I wouldn't need to touch the other drivers. Here is the relevant part of the diff: I'm fine with that if other people
Re: [Intel-gfx] [PATCH 1/3] drm: Plumb modifiers through plane init
On 17-05-03 18:30:07, Liviu Dudau wrote: On Wed, May 03, 2017 at 06:45:05PM +0200, Daniel Vetter wrote: On Wed, May 03, 2017 at 03:52:23PM +0100, Liviu Dudau wrote: > On Wed, May 03, 2017 at 03:14:56PM +0100, Daniel Stone wrote: > > On 3 May 2017 at 15:07, Liviu Dudau <liviu.du...@arm.com> wrote: > > > On Wed, May 03, 2017 at 02:45:26PM +0100, Daniel Stone wrote: > > >> It does deserve a much better commit message than what it has, but as > > >> he is on holiday for the rest of the week, I can answer. Currently, we > > >> advertise which formats each plane is capable of displaying. In order > > >> for userspace to be able to allocate tiled/compressed buffers for > > >> scanout, we want userspace to be able to discover which modifiers each > > >> plane supports as well. > > > > > > I get the overall goal. We need/want something similar for Mali DP and AFBC buffers. > > > What I don't understand is the current aproach (but I've found from Brian that somehow > > > I've missed the long discussion(s) around the subject). I was hoping to learn > > > from the commit message why he thinks the introduction of this code is the right > > > way of doing it. And the IRC logs seem to imply that he is mostly doing something > > > that others have agreed upon and he doesn't really care about the approach as long > > > as it ticks the "supported by intel driver" box. > > > > Or, with another interpretation, he thinks the various approaches of > > doing it are all equally good. He took guidance from a couple of > > userspace developers (Weston, ChromeOS), a Freedreno developer and > > also I believe an AFBC developer, to end up where he is now, which he > > still thinks is fine. In doing so, he's been through several > > iterations, always modifying the driver to suit. I think that's a > > pretty good way to do development of new uABI, if you ask me. (And > > again, I have trouble reading your last sentence as anything other > > than hostile.) > > I am getting the message. You think I am too strong here, so I'm going to back off. > Also look forward to see the next version where he takes into account the technical > comments that I have sent. Just to make it really clear: Google has an implementation for AFBC using exactly this scheme for cros. The only reasons it's not floating around here in upstream is that one of the critical pieces is missing (*hint*, *hint* you really want an open mail driver ...). Don't know about open _mail_ drivers but there are plenty of open mail apps that one can use Joke aside, the Mali GPU *kernel* driver *is* open source. Just not in the mainline and not enough for what you want. But I'm not the right person to fix all that. And GPU is not the only IP capable of producing AFBC data, so there might be another driver in the making that will be open source. Best regards, Liviu But besides that, it works perfectly fine for arm render compression format too. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch -- So are we good with patch 1, sorry if I missed any real valid changes I need to make, but can we please capture that here. -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH 1/3] drm: Plumb modifiers through plane init
On 17-05-03 14:45:26, Daniel Stone wrote: Hi Liviu, On 3 May 2017 at 11:34, Liviu Dudau <liviu.du...@arm.com> wrote: On Tue, May 02, 2017 at 10:14:26PM -0700, Ben Widawsky wrote: v2: A minor addition from Daniel You are *really* pushing your luck by not Cc-ing *any* of the maintainers of the drivers you touch. You do want reviews, don't you? Ouch. I'm very sure Ben does want reviews, but he mainly works in Mesa where you can rely on the list rather than having to CC everyone individually. It was a mistake, so please be more gentle with him; your whole mail comes across as quite hostile to me. It was not a mistake. The whole point of a mailing list is so that people can participate without needing to Cc every individual. dri-devel has been the location, and while many hardware vendors have set up their own list, dri-devel is still the mailing list for patches like this. There are a ridiculous number of DRM driver maintainers. There isn't even an easy way to script extracting all the relevant people from MAINTAINERS (happy to be corrected on that) I don't believe anybody Cc's them all, ever - but normally there isn't such a globally invasive patch. I'm sorry Liviu you obviously felt slighted. I did Cc the Intel mailing list because my implementation for this was on Intel. Finally, the questions I should've started with: why the change? What are you trying to achieve? It is not very clear from the commit message at all. It does deserve a much better commit message than what it has, but as he is on holiday for the rest of the week, I can answer. Currently, we advertise which formats each plane is capable of displaying. In order for userspace to be able to allocate tiled/compressed buffers for scanout, we want userspace to be able to discover which modifiers each plane supports as well. @@ -105,6 +108,28 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, return -ENOMEM; } + /* First driver to need more than 64 formats needs to fix this */ + if (WARN_ON(format_count > 64)) + return -EINVAL; What is the link between format_count and format modifiers? Why are you introducing this artificial restriction on the format_count? Also, there doesn't seem to be any check if format_modifier_count == format_count. What happens when they don't match? Inside the blob, each modifier carries a bitmask of formats (specified by index) that the modifier applies to, i.e. with: .formats = { ARGB, XRGB, RGB565 }, a modifier which applied only to the 32-bit formats would specify a bitmask of 0x3. The uABI supports this just fine, but the internal plumbing does not yet, because no-one supports more than 64 formats. + + if (format_modifiers) { + const uint64_t *temp_modifiers = format_modifiers; + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + } + + plane->modifier_count = format_modifier_count; Why do you need to remember this? It is not used anywhere else! It is used to populate the blob in a later patch! Cheers, Daniel I'm back now. Thanks Daniel for summing it up for me. -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/3] drm: Create a format/modifier blob
Updated blob layout (Rob, Daniel, Kristian, xerpi) Cc: Rob Clark <robdcl...@gmail.com> Cc: Daniel Stone <dani...@collabora.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/drm_mode_config.c | 7 +++ drivers/gpu/drm/drm_plane.c | 119 ++ include/drm/drm_mode_config.h | 6 ++ include/uapi/drm/drm_mode.h | 26 + 4 files changed, 158 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index d9862259a2a7..6bfbc3839df5 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, + "IN_FORMATS", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.modifiers = prop; + return 0; } diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 286e183891e5..2e89e0e73435 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -62,6 +62,117 @@ static unsigned int drm_num_planes(struct drm_device *dev) return num; } +struct drm_format_modifier_blob { +#define FORMAT_BLOB_CURRENT 1 + /* Version of this blob format */ + u32 version; + + /* Flags */ + u32 flags; + + /* Number of fourcc formats supported */ + u32 count_formats; + + /* Where in this blob the formats exist (in bytes) */ + u32 formats_offset; + + /* Number of drm_format_modifiers */ + u32 count_modifiers; + + /* Where in this blob the modifiers exist (in bytes) */ + u32 modifiers_offset; + + /* u32 formats[] */ + /* struct drm_format_modifier modifiers[] */ +} __packed; + +static inline u32 * +formats_ptr(struct drm_format_modifier_blob *blob) +{ + return (u32 *)(((char *)blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +modifiers_ptr(struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset); +} + +static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane, +const struct drm_plane_funcs *funcs, +const uint32_t *formats, unsigned int format_count, +const uint64_t *format_modifiers) +{ + const struct drm_mode_config *config = >mode_config; + const uint64_t *temp_modifiers = format_modifiers; + unsigned int format_modifier_count = 0; + struct drm_property_blob *blob = NULL; + struct drm_format_modifier *mod; + size_t blob_size = 0, formats_size, modifiers_size; + struct drm_format_modifier_blob *blob_data; + int i, j, ret = 0; + + if (format_modifiers) + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + + formats_size = sizeof(__u32) * format_count; + if (WARN_ON(!formats_size)) { + /* 0 formats are never expected */ + return 0; + } + + modifiers_size = + sizeof(struct drm_format_modifier) * format_modifier_count; + + blob_size = ALIGN(sizeof(struct drm_format_modifier_blob), 8); + blob_size += ALIGN(formats_size, 8); + blob_size += modifiers_size; + + blob = drm_property_create_blob(dev, blob_size, NULL); + if (IS_ERR(blob)) + return -1; + + blob_data = (struct drm_format_modifier_blob *)blob->data; + blob_data->version = FORMAT_BLOB_CURRENT; + blob_data->count_formats = format_count; + blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); + blob_data->count_modifiers = format_modifier_count; + + /* Modifiers offset is a pointer to a struct with a 64 bit field so it +* should be naturally aligned to 8B. +*/ + blob_data->modifiers_offset = + ALIGN(blob_data->formats_offset + formats_size, 8); + + memcpy(formats_ptr(blob_data), formats, formats_size); + + /* If we can't determine support, just bail */ + if (!funcs->format_mod_supported) + goto done; + + mod = modifiers_ptr(blob_data); + for (i = 0; i < format_modifier_count; i++) { + for (j = 0; j < format_count; j++) { + if (funcs->format_mod_supported(plane, formats[j], + format_modifiers[i])) { + mod->formats |
[PATCH 1/3] drm: Plumb modifiers through plane init
v2: A minor addition from Daniel Cc: Daniel Stone <dani...@collabora.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 +++- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 32 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 7 +- drivers/gpu/drm/i915/intel_sprite.c | 4 ++-- drivers/gpu/drm/imx/ipuv3-plane.c | 4 ++-- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 ++-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 ++-- drivers/gpu/drm/omapdrm/omap_plane.c| 3 ++- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 ++-- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 ++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++-- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 +- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c| 4 ++-- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 21 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm_fourcc.h | 11 + 41 files changed, 126 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a95916f1f..cd8a24c7c67d 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 798a3cc480a2..0caa03ae8708 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -303,6 +303,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { devm_kfree(drm->dev, plane); diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 814fda23cead..b156610c68a5 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -400,7 +400,7 @@ int malidp_de_planes_init(struct drm_device *drm) DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(drm, >base, crtcs, _de_plane_funcs, formats, - n, plane_type, NULL); + n, NULL, plane_type, NULL); if (ret < 0) goto cleanup; diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 4fe19fde84f9..ea48ef88f0e4 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -1269,6 +1269,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, _primary_plane_funcs, armada_primary_formats,
[PATCH 3/3] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 131 +-- drivers/gpu/drm/i915/intel_sprite.c | 76 +++- 2 files changed, 201 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d52bd05a017d..18aac538d978 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,6 +93,14 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -13381,6 +13395,103 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + return true; + default: + return false; + } + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + /* All i915 modifiers are fine */ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return true; + default: + return false; + } + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + if (INTEL_GEN(dev_priv) >= 9) + return skl_mod_supported(format, modifier); + else if (INTEL_GEN(dev_priv) >= 4) + return i965_mod_supported(format, modifier); + else + return i8xx_mod_supported(format, modifier); + + return false; +} + +static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane, +
Re: [PATCH 1/2] drm: Add new DRM_IOCTL_MODE_GETPLANE2
On 17-04-28 14:11:56, Lucas Stach wrote: Hi Ben, Am Dienstag, den 04.04.2017, 12:41 -0700 schrieb Ben Widawsky: On 17-04-04 11:07:26, Daniel Stone wrote: >Hi, > >On 1 April 2017 at 19:47, Rob Clark <robdcl...@gmail.com> wrote: >> On Tue, Dec 20, 2016 at 7:12 PM, Kristian H. Kristensen >> <hoegsb...@gmail.com> wrote: >>> This new ioctl exctends DRM_IOCTL_MODE_GETPLANE, by returning >>> information about the modifiers that will work with each format. >> >> So, just to toss out a completely different idea.. >> >> What if instead of a new ioctl, we had a read-only blob property >> (which encoded the info basically the same way, plus the fourcc's)? >> >> If we do writeback via some sort of OUT_FB_ID property on plane/crtc, >> we will need the same sort of format information so userspace knows >> what output formats (and modifiers) are supported. So re-using the >> same blob property layout (and userspace parsing) seems useful. > >I'd definitely be cool with this. It doesn't make our lives any easier >or more difficult in terms of parsing, and it also avoids a dep on new >libdrm API/ABI, which is always nice. If anyone types this up, I'll >happily port the Weston WIP. > >Cheers, >Daniel Okay. Sounds like we have consensus. I'm working on it now. I think like Rob said on IRC, a good amount of it will be reusable from GET_PLANE2. I'm a bit new to the binary blob props, so if anyone has a strong opinion on how it should look, please speak now. Otherwise, I'll just wire up something. Can you tell me the status of this? I'm looking at adding tiled scanout to imx-drm and just want to know if it's worth to hold my breath for the reworked patch to arrive. Regards, Lucas The agreement was to use a blob property instead of GET_PLANE2. I wrote the patches: https://cgit.freedesktop.org/~bwidawsk/drm-intel/log/?h=blobifier However, my test vehicle, kmscube has broken on i915, so I haven't yet been able to test and therefore I didn't send them yet. Daniel said he'd try to wire it up to weston next week. I can go back and try to make it work with legacy kmscube as well, unless someone wants to fix kmscube/i915/i965 first? -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/2] drm: Add new DRM_IOCTL_MODE_GETPLANE2
On 17-04-04 11:07:26, Daniel Stone wrote: Hi, On 1 April 2017 at 19:47, Rob Clark <robdcl...@gmail.com> wrote: On Tue, Dec 20, 2016 at 7:12 PM, Kristian H. Kristensen <hoegsb...@gmail.com> wrote: This new ioctl exctends DRM_IOCTL_MODE_GETPLANE, by returning information about the modifiers that will work with each format. So, just to toss out a completely different idea.. What if instead of a new ioctl, we had a read-only blob property (which encoded the info basically the same way, plus the fourcc's)? If we do writeback via some sort of OUT_FB_ID property on plane/crtc, we will need the same sort of format information so userspace knows what output formats (and modifiers) are supported. So re-using the same blob property layout (and userspace parsing) seems useful. I'd definitely be cool with this. It doesn't make our lives any easier or more difficult in terms of parsing, and it also avoids a dep on new libdrm API/ABI, which is always nice. If anyone types this up, I'll happily port the Weston WIP. Cheers, Daniel Okay. Sounds like we have consensus. I'm working on it now. I think like Rob said on IRC, a good amount of it will be reusable from GET_PLANE2. I'm a bit new to the binary blob props, so if anyone has a strong opinion on how it should look, please speak now. Otherwise, I'll just wire up something. -- Ben Widawsky, Intel Open Source Technology Center ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/3] [v5] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) v4: - List each modifier explicitly in supported modifiers (Ville) - Handle the CURSOR plane (Ville) v5: - Split out cursor and sprite handling (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 132 +-- drivers/gpu/drm/i915/intel_sprite.c | 76 +++- 2 files changed, 202 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 802a8449c5d3..67de3c267290 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,6 +93,14 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -13453,6 +13467,103 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + return true; + default: + return false; + } + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + /* All i915 modifiers are fine */ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return true; + default: + return false; + } + default: + return false; + } +} + +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + if (INTEL_GEN(dev_priv) >= 9) + return skl_mod_supported(format, modifier); + else if (INTEL_GEN(dev_priv) >= 4) + return i965_mod_supported(format, modifier); + else + return i8xx_mod_supported(format, modifier); + + return false; +} + +static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane, +
[PATCH] squash! drm/i915: Add format modifiers for Intel
make sprite and cursor have separate functions --- Ville, I think this addresses most of your comments. I'm guessing you're going to ask for separate gen sprite plane functions, but I think this looks pretty decent as is. --- drivers/gpu/drm/i915/intel_display.c | 26 -- drivers/gpu/drm/i915/intel_sprite.c | 51 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a5edcc910f4a..3f7ce8c39bc8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13535,18 +13535,16 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) } } -static bool intel_plane_format_mod_supported(struct drm_plane *plane, -uint32_t format, -uint64_t modifier) +static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) { struct drm_i915_private *dev_priv = to_i915(plane->dev); if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) return false; - if (plane->base.type == DRM_PLANE_TYPE_PRIMARY) - return modifier == DRM_FORMAT_MOD_LINEAR && - format == DRM_FORMAT_ARGB; + BUG_ON(plane->base.type != DRM_PLANE_TYPE_PRIMARY); if (INTEL_GEN(dev_priv) >= 9) return skl_mod_supported(format, modifier); @@ -13558,6 +13556,18 @@ static bool intel_plane_format_mod_supported(struct drm_plane *plane, return false; } +static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane, + uint32_t format, + uint64_t modifier) +{ + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + BUG_ON(plane->base.type != DRM_PLANE_TYPE_CURSOR); + + return modifier == DRM_FORMAT_MOD_LINEAR && format == DRM_FORMAT_ARGB; +} + const struct drm_plane_funcs intel_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -13567,7 +13577,7 @@ const struct drm_plane_funcs intel_plane_funcs = { .atomic_set_property = intel_plane_atomic_set_property, .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, - .format_mod_supported = intel_plane_format_mod_supported, + .format_mod_supported = intel_primary_plane_format_mod_supported, }; static int @@ -13704,7 +13714,7 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = { .atomic_set_property = intel_plane_atomic_set_property, .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, - .format_mod_supported = intel_plane_format_mod_supported, + .format_mod_supported = intel_cursor_plane_format_mod_supported, }; static struct intel_plane * diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index bf18d9edc66f..dae8e8a943b9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -30,6 +30,7 @@ * support. */ #include +#include #include #include #include @@ -1102,6 +1103,56 @@ static const uint64_t skl_plane_format_modifiers[] = { DRM_FORMAT_MOD_INVALID }; +static bool intel_sprite_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ +struct drm_i915_private *dev_priv = to_i915(plane->dev); + +if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) +return false; + +BUG_ON(plane->base.type != DRM_PLANE_TYPE_OVERLAY); + + switch (format) { + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + return true; + break; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_ARGB: + if (INTEL_GEN(dev_priv) >= 9 || IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + return true; + break; + case DRM_FORMAT_XBGR: + if (INTEL_GEN(dev_priv) >= 6) + return true; + break; + case DRM_FORMAT_XRGB: + case DRM_FORMAT_YUYV: + case
Re: [PATCH 3/3] drm/i915: Add format modifiers for Intel
On 17-03-29 23:17:13, Ville Syrjälä wrote: On Fri, Mar 24, 2017 at 02:29:50PM -0700, Ben Widawsky wrote: This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 112 +-- drivers/gpu/drm/i915/intel_sprite.c | 25 +++- 2 files changed, 131 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 802a8449c5d3..bb559a116fda 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,6 +93,14 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -13453,6 +13467,83 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + return modifier == DRM_FORMAT_MOD_LINEAR || + (modifier >= I915_FORMAT_MOD_X_TILED && +modifier < I915_FORMAT_MOD_Yf_TILED); The >= stuff makes this harder to parse than it should be IMO. I'd just list each modifier explicitly. + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + (modifier >= I915_FORMAT_MOD_X_TILED && + modifier <= I915_FORMAT_MOD_Yf_TILED); ditto. At first I couldn't even spot the difference between this and the C8 case. Okay, got those both. I think for now it's just: switch (format) { case DRM_FORMAT_C8: switch (modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: return true; default: return false; } case DRM_FORMAT_RGB565: case DRM_FORMAT_XRGB: case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: case DRM_FORMAT_UYVY: case DRM_FORMAT_VYUY: /* All i915 modifiers are fine */ switch (modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Yf_TILED: return true; default: return false; } default: return false;
[PATCH 1/3] drm/i915: Use LINEAR modifier instead of NONE
They're the same, so use the one which makes more sense. Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9a28a8917dc1..696d106461f8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1997,7 +1997,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane) unsigned int cpp = fb->format->cpp[plane]; switch (fb->modifier) { - case DRM_FORMAT_MOD_NONE: + case DRM_FORMAT_MOD_LINEAR: return cpp; case I915_FORMAT_MOD_X_TILED: if (IS_GEN2(dev_priv)) @@ -2033,7 +2033,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane) static unsigned int intel_tile_height(const struct drm_framebuffer *fb, int plane) { - if (fb->modifier == DRM_FORMAT_MOD_NONE) + if (fb->modifier == DRM_FORMAT_MOD_LINEAR) return 1; else return intel_tile_size(to_i915(fb->dev)) / @@ -2107,7 +2107,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, return 4096; switch (fb->modifier) { - case DRM_FORMAT_MOD_NONE: + case DRM_FORMAT_MOD_LINEAR: return intel_linear_alignment(dev_priv); case I915_FORMAT_MOD_X_TILED: if (INTEL_GEN(dev_priv) >= 9) @@ -2290,7 +2290,7 @@ static u32 intel_adjust_tile_offset(int *x, int *y, WARN_ON(new_offset > old_offset); - if (fb->modifier != DRM_FORMAT_MOD_NONE) { + if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { unsigned int tile_size, tile_width, tile_height; unsigned int pitch_tiles; @@ -2345,7 +2345,7 @@ static u32 _intel_compute_tile_offset(const struct drm_i915_private *dev_priv, if (alignment) alignment--; - if (fb_modifier != DRM_FORMAT_MOD_NONE) { + if (fb_modifier != DRM_FORMAT_MOD_LINEAR) { unsigned int tile_size, tile_width, tile_height; unsigned int tile_rows, tiles, pitch_tiles; @@ -2471,7 +2471,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv, DRM_ROTATE_0, tile_size); offset /= tile_size; - if (fb->modifier != DRM_FORMAT_MOD_NONE) { + if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { unsigned int tile_width, tile_height; unsigned int pitch_tiles; struct drm_rect r; @@ -2803,7 +2803,7 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane, int cpp = fb->format->cpp[plane]; switch (fb->modifier) { - case DRM_FORMAT_MOD_NONE: + case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: switch (cpp) { case 8: @@ -3199,7 +3199,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, static u32 intel_fb_stride_alignment(const struct drm_framebuffer *fb, int plane) { - if (fb->modifier == DRM_FORMAT_MOD_NONE) + if (fb->modifier == DRM_FORMAT_MOD_LINEAR) return 64; else return intel_tile_width_bytes(fb, plane); @@ -3298,7 +3298,7 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format) static u32 skl_plane_ctl_tiling(uint64_t fb_modifier) { switch (fb_modifier) { - case DRM_FORMAT_MOD_NONE: + case DRM_FORMAT_MOD_LINEAR: break; case I915_FORMAT_MOD_X_TILED: return PLANE_CTL_TILED_X; @@ -8426,7 +8426,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, tiling = val & PLANE_CTL_TILED_MASK; switch (tiling) { case PLANE_CTL_TILED_LINEAR: - fb->modifier = DRM_FORMAT_MOD_NONE; + fb->modifier = DRM_FORMAT_MOD_LINEAR; break; case PLANE_CTL_TILED_X: plane_config->tiling = I915_TILING_X; @@ -10399,7 +10399,7 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, ctl = I915_READ(PLANE_CTL(pipe, 0)); ctl &= ~PLANE_CTL_TILED_MASK; switch (fb->modifier) { - case DRM_FORMAT_MOD_NONE: + case DRM_FORMAT_MOD_LINEAR: break; case I915_FORMAT_MOD_X_TILED: ctl |= PLANE_CTL_TILED_X; @@ -13756,7 +13756,7 @@ intel_check_cursor_plane(struct drm_plane *plane, return -ENOMEM; } - if (fb->modifier != DRM_FORMAT_MOD_NONE) { + if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { DRM_DEBUG_KMS("cursor cannot be tiled\n"); return -EINVAL;
[PATCH 3/3] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. v2: - Add LINEAR and Yf modifiers to list (Ville) - Combine i8xx and i965 into one list of formats (Ville) - Allow 1010102 formats for Y/Yf tiled (Ville) v3: - Handle cursor formats (Ville) - Put handling for LINEAR in the mod_support functions (Ville) Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 112 +-- drivers/gpu/drm/i915/intel_sprite.c | 25 +++- 2 files changed, 131 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 802a8449c5d3..bb559a116fda 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -72,6 +72,12 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i9xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -87,6 +93,14 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED, + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -13453,6 +13467,83 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + return modifier == DRM_FORMAT_MOD_LINEAR || + (modifier >= I915_FORMAT_MOD_X_TILED && +modifier < I915_FORMAT_MOD_Yf_TILED); + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == DRM_FORMAT_MOD_LINEAR || + (modifier >= I915_FORMAT_MOD_X_TILED && + modifier <= I915_FORMAT_MOD_Yf_TILED); + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + return modifier == DRM_FORMAT_MOD_LINEAR; + default: + return false; + } + +} + +static bool intel_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + if (INTEL_GEN(dev_priv) >= 9) + return skl_mod_supported(format, modifier); + else if (INTEL_GEN(dev_priv) >= 4) + return i965_mod_supported(format, modifier); + else + return i8xx_mod_supported(format, modifier); + + return false; +} + const struct drm_plane_funcs intel_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -13462,6 +13553,7 @@ const struct drm_plane_funcs intel_plane_funcs = { .atomic_set_property = intel_plane_atomic_set_property, .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, + .format_mod_supported = intel_plane_format_mod_supported, }; static int @@ -13598,6 +13690,7 @@ static
[PATCH 2/3] drm: Add new DRM_IOCTL_MODE_GETPLANE2
Originally based off of a patch by Kristian. This new ioctl extends DRM_IOCTL_MODE_GETPLANE, by returning information about the modifiers that will work with each format. It's modified from Kristian's patch in that the modifiers and formats are setup by the driver, and then a callback is used to create the format list. The LOC was enough difference that I don't think it made sense to leave his authorship, but the new UABI was primarily his idea. Additionally, I hit a couple of drivers which Kristian missed updating. It also contains a change requested by Daniel to make the modifiers array a sentinel based structure instead of a sized one. Upon discussion on IRC, it was determined that having an invalid modifier might make sense in general as well. v2: - Make formats uint32_t, and use an offset, see the comment in the patch. Add a WARN_ON and early bail for when there are more than 32 formats. (Rob) - Remove DRM_DEBUG_KMS (Ville) - make flags come before count in struct (Ville) v3: - Make formats 64b again to defer the pain, and add a pad - Make init fail if > 64 instead of at get_plane. This could be made more optimal by doing it in get_plane because 0 masked modifiers don't need to be reported back to userspace. As a result, the first driver to go back 64 formats has to deal with this. - Fix the comment to be more clear. v4: - Add drivers/gpu/drm/qxl/ Cc: Rob Clark <robdcl...@gmail.com> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Daniel Stone <dan...@fooishbar.org> Cc: "Kristian H. Kristensen" <hoegsb...@gmail.com> References: https://patchwork.kernel.org/patch/9482393/ Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 +- drivers/gpu/drm/drm_ioctl.c | 2 +- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 67 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 7 ++- drivers/gpu/drm/i915/intel_sprite.c | 4 +- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 4 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 3 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 2 +- drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 2 +- drivers/gpu/drm/tegra/dc.c | 12 ++--- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 21 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm.h | 1 + include/uapi/drm/drm_fourcc.h | 11 include/uapi/drm/drm_mode.h | 44 41 files changed, 200 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a95916f1f..cd8a24c7c67d 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 798a3cc480a2..0caa03ae8708 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -303,6 +303,7 @
Re: [PATCH 2/5] drm: Remove fb hsub/vsub alignment requirement
On 17-03-21 20:12:15, Ville Syrjälä wrote: From: Ville Syrjälä <ville.syrj...@linux.intel.com> Allow framebuffers dimesions to be misaligned w.r.t. the subsampling factors. No real reason the core should have to enforce this, and it definitely starts to cause us issues with the i915 CCS support. So let's just lift the restriction. Let's start to round up when computing the color plane dimesions so that we'll not end up with too low an estimate for the memory requirements and whatnot. Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> Both 1 and 2 are: Reviewed-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/drm_framebuffer.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 1138f90a7d5d..69e4c1487420 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -132,7 +132,7 @@ static int fb_plane_width(int width, if (plane == 0) return width; - return width / format->hsub; + return DIV_ROUND_UP(width, format->hsub); } static int fb_plane_height(int height, @@ -141,7 +141,7 @@ static int fb_plane_height(int height, if (plane == 0) return height; - return height / format->vsub; + return DIV_ROUND_UP(height, format->vsub); } static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) @@ -158,12 +158,12 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) return -EINVAL; } - if (r->width == 0 || r->width % info->hsub) { + if (r->width == 0) { DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); return -EINVAL; } - if (r->height == 0 || r->height % info->vsub) { + if (r->height == 0) { DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); return -EINVAL; } -- 2.10.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 9/9] drm/i915: Add render decompression support
On 17-03-01 12:51:17, Ville Syrjälä wrote: On Tue, Feb 28, 2017 at 03:20:38PM -0800, Ben Widawsky wrote: On 17-02-28 12:18:39, Jason Ekstrand wrote: >I've said it before but reading through Ben's patches again make me want to >be peskier about it. I would really like the UABI to treat the CCS as if >it's Y-tiled with a tile size of 128B x 32 rows. Why? Because this is >what all the docs say it is. From the display docs for "Color Control >Surface": > >"The Color Control Surface (CCS) contains the compression status of the >cache-line pairs. The >compression state of the cache-line pair is specified by 2 bits in the CCS. >Each CCS cache-line represents >an area on the main surface of 16 x16 sets of 128 byte Y-tiled >cache-line-pairs. CCS is always Y tiled." > >This contains 95% of the information needed to know the relation between >the CCS and the main surface. The other 5% (which is badly documented) is >that cache line pairs are horizontally adjacent. This gives a relationship >of one cache line in the CCS maps to 32x64 cache lines in the main surface. > >But it's not actually Y-tiled? Of course not. I've worked out the exact >tiling and it looks something like Y but isn't quite the same. However, >this isn't unique to CCS. Stencil (W-tiled), HiZ, and gen7-8 >single-sampled MCS also each have their own tiling (Haswell MCS is >especially exotic) but the docs call all of them Y-tiled and I think the >hardware internally treats them as Y-tiled with the cache lines shuffled >around a bit. > >Given the fact that they seem to like to change the MCS/CCS tiling around >on every hardware generation, I'm reluctant to base UABI on the fact that >the CCS appears to have 64x64 "pixels" per tile with each "pixel" >corresponding to 16x8 pixels in the color surface. That's not what we had >on any previous gen and may change on gen10 for no aparent reason. I'd >much rather base it on Y-tiling and a relationship between cache lines >which, even if they change the exact swizzle on gen10, will probably remain >the same. (For the gen7-8 analogue of CCS, they changed the tiling every >generation but the relationship of one MCS cache line maps to 32x128 color >cache lines remained the same). > >Ok, I've said my peice. If we have to divide by 2 in userspace, we won't >die, but I'd like to get the UABI right before we chissel it in stone. > >--Jason > > I vote we make the stride in units of tiles when we have the CCS modifier. That won't fly with the KMS API. I suppose I could make the tile 128 bytes wide by swapping the "1 byte == 16x8 pixels" notion with a "1 byte == 8x16 pixels" notion. Doesn't match the actual truth anymore, but I guess no one really cares. KMS API goes right out the window with modifiers. Isn't that really the whole point of modifiers? >> + /* fall through */ >> case I915_FORMAT_MOD_Yf_TILED: >> /* >> * Bspec seems to suggest that the Yf tile width would >> @@ -2156,7 +2164,7 @@ static unsigned int intel_surf_alignment(const >> struct drm_framebuffer *fb, >> struct drm_i915_private *dev_priv = to_i915(fb->dev); >> >> /* AUX_DIST needs only 4K alignment */ >> - if (fb->format->format == DRM_FORMAT_NV12 && plane == 1) >> + if (plane == 1) >> return 4096; >> >> switch (fb->modifier) { >> @@ -2166,6 +2174,8 @@ static unsigned int intel_surf_alignment(const >> struct drm_framebuffer *fb, >> if (INTEL_GEN(dev_priv) >= 9) >> return 256 * 1024; >> return 0; >> + case I915_FORMAT_MOD_Y_TILED_CCS: >> + case I915_FORMAT_MOD_Yf_TILED_CCS: >> case I915_FORMAT_MOD_Y_TILED: >> case I915_FORMAT_MOD_Yf_TILED: >> return 1 * 1024 * 1024; >> @@ -2472,6 +2482,7 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t >> fb_modifier) >> case I915_FORMAT_MOD_X_TILED: >> return I915_TILING_X; >> case I915_FORMAT_MOD_Y_TILED: >> + case I915_FORMAT_MOD_Y_TILED_CCS: >> return I915_TILING_Y; >> default: >> return I915_TILING_NONE; >> @@ -2536,6 +2547,35 @@ intel_fill_fb_info(struct drm_i915_private >> *dev_priv, >> >> intel_fb_offset_to_xy(, , fb, i); >> >> + if ((fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS || >> +fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) && i == >> 1) { >> +
Re: [PATCH v2 9/9] drm/i915: Add render decompression support
On 17-02-28 12:18:39, Jason Ekstrand wrote: On Thu, Jan 5, 2017 at 7:14 AM, <ville.syrj...@linux.intel.com> wrote: From: Ville Syrjälä <ville.syrj...@linux.intel.com> SKL+ display engine can scan out certain kinds of compressed surfaces produced by the render engine. This involved telling the display engine the location of the color control surfae (CCS) which describes which parts of the main surface are compressed and which are not. The location of CCS is provided by userspace as just another plane with its own offset. Add the required stuff to validate the user provided AUX plane metadata and convert the user provided linear offset into something the hardware can consume. Due to hardware limitations we require that the main surface and the AUX surface (CCS) be part of the same bo. The hardware also makes life hard by not allowing you to provide separate x/y offsets for the main and AUX surfaces (excpet with NV12), so finding suitable offsets for both requires a bit of work. Assuming we still want keep playing tricks with the offsets. I've just gone with a dumb "search backward for suitable offsets" approach, which is far from optimal, but it works. Also not all planes will be capable of scanning out compressed surfaces, and eg. 90/270 degree rotation is not supported in combination with decompression either. This patch may contain work from at least the following people: * Vandana Kannan <vandana.kan...@intel.com> * Daniel Vetter <dan...@ffwll.ch> * Ben Widawsky <b...@bwidawsk.net> v2: Deal with display workarounds 0390, 0531, 1125 (Paulo) Cc: Paulo Zanoni <paulo.r.zan...@intel.com> Cc: Vandana Kannan <vandana.kan...@intel.com> Cc: Daniel Vetter <dan...@ffwll.ch> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> --- drivers/gpu/drm/i915/i915_reg.h | 23 drivers/gpu/drm/i915/intel_display.c | 234 ++ ++--- drivers/gpu/drm/i915/intel_pm.c | 29 - drivers/gpu/drm/i915/intel_sprite.c | 5 + 4 files changed, 274 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_ reg.h index 00970aa77afa..6849ba93f1d9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6209,6 +6209,28 @@ enum { _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \ _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)) +#define PLANE_AUX_DIST_1_A 0x701c0 +#define PLANE_AUX_DIST_2_A 0x702c0 +#define PLANE_AUX_DIST_1_B 0x711c0 +#define PLANE_AUX_DIST_2_B 0x712c0 +#define _PLANE_AUX_DIST_1(pipe) \ + _PIPE(pipe, PLANE_AUX_DIST_1_A, PLANE_AUX_DIST_1_B) +#define _PLANE_AUX_DIST_2(pipe) \ + _PIPE(pipe, PLANE_AUX_DIST_2_A, PLANE_AUX_DIST_2_B) +#define PLANE_AUX_DIST(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe)) + +#define PLANE_AUX_OFFSET_1_A 0x701c4 +#define PLANE_AUX_OFFSET_2_A 0x702c4 +#define PLANE_AUX_OFFSET_1_B 0x711c4 +#define PLANE_AUX_OFFSET_2_B 0x712c4 +#define _PLANE_AUX_OFFSET_1(pipe) \ + _PIPE(pipe, PLANE_AUX_OFFSET_1_A, PLANE_AUX_OFFSET_1_B) +#define _PLANE_AUX_OFFSET_2(pipe) \ + _PIPE(pipe, PLANE_AUX_OFFSET_2_A, PLANE_AUX_OFFSET_2_B) +#define PLANE_AUX_OFFSET(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe)) + /* legacy palette */ #define _LGC_PALETTE_A 0x4a000 #define _LGC_PALETTE_B 0x4a800 @@ -6433,6 +6455,7 @@ enum { # define CHICKEN3_DGMG_DONE_FIX_DISABLE(1 << 2) #define CHICKEN_PAR1_1 _MMIO(0x42080) +#define SKL_RC_HASH_OUTSIDE (1 << 15) #define DPA_MASK_VBLANK_SRD (1 << 15) #define FORCE_ARB_IDLE_PLANES (1 << 14) #define SKL_EDP_PSR_FIX_RDWRAP(1 << 3) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 38de9df0ec60..2236abebd8bc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2064,11 +2064,19 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane) return 128; else return 512; + case I915_FORMAT_MOD_Y_TILED_CCS: + if (plane == 1) + return 64; + /* fall through */ case I915_FORMAT_MOD_Y_TILED: if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv)) return 128; else return 512; + case I915_FORMAT_MOD_Yf_TILED_CCS: + if (plane == 1) + return 64; I've said it before but readi
Re: [PATCH v2 9/9] drm/i915: Add render decompression support
On 17-02-28 12:18:39, Jason Ekstrand wrote: On Thu, Jan 5, 2017 at 7:14 AM, <ville.syrj...@linux.intel.com> wrote: From: Ville Syrjälä <ville.syrj...@linux.intel.com> SKL+ display engine can scan out certain kinds of compressed surfaces produced by the render engine. This involved telling the display engine the location of the color control surfae (CCS) which describes which parts of the main surface are compressed and which are not. The location of CCS is provided by userspace as just another plane with its own offset. Add the required stuff to validate the user provided AUX plane metadata and convert the user provided linear offset into something the hardware can consume. Due to hardware limitations we require that the main surface and the AUX surface (CCS) be part of the same bo. The hardware also makes life hard by not allowing you to provide separate x/y offsets for the main and AUX surfaces (excpet with NV12), so finding suitable offsets for both requires a bit of work. Assuming we still want keep playing tricks with the offsets. I've just gone with a dumb "search backward for suitable offsets" approach, which is far from optimal, but it works. Also not all planes will be capable of scanning out compressed surfaces, and eg. 90/270 degree rotation is not supported in combination with decompression either. This patch may contain work from at least the following people: * Vandana Kannan <vandana.kan...@intel.com> * Daniel Vetter <dan...@ffwll.ch> * Ben Widawsky <b...@bwidawsk.net> v2: Deal with display workarounds 0390, 0531, 1125 (Paulo) Cc: Paulo Zanoni <paulo.r.zan...@intel.com> Cc: Vandana Kannan <vandana.kan...@intel.com> Cc: Daniel Vetter <dan...@ffwll.ch> Cc: Ben Widawsky <b...@bwidawsk.net> Cc: Jason Ekstrand <ja...@jlekstrand.net> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> --- drivers/gpu/drm/i915/i915_reg.h | 23 drivers/gpu/drm/i915/intel_display.c | 234 ++ ++--- drivers/gpu/drm/i915/intel_pm.c | 29 - drivers/gpu/drm/i915/intel_sprite.c | 5 + 4 files changed, 274 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_ reg.h index 00970aa77afa..6849ba93f1d9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6209,6 +6209,28 @@ enum { _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \ _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)) +#define PLANE_AUX_DIST_1_A 0x701c0 +#define PLANE_AUX_DIST_2_A 0x702c0 +#define PLANE_AUX_DIST_1_B 0x711c0 +#define PLANE_AUX_DIST_2_B 0x712c0 +#define _PLANE_AUX_DIST_1(pipe) \ + _PIPE(pipe, PLANE_AUX_DIST_1_A, PLANE_AUX_DIST_1_B) +#define _PLANE_AUX_DIST_2(pipe) \ + _PIPE(pipe, PLANE_AUX_DIST_2_A, PLANE_AUX_DIST_2_B) +#define PLANE_AUX_DIST(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe)) + +#define PLANE_AUX_OFFSET_1_A 0x701c4 +#define PLANE_AUX_OFFSET_2_A 0x702c4 +#define PLANE_AUX_OFFSET_1_B 0x711c4 +#define PLANE_AUX_OFFSET_2_B 0x712c4 +#define _PLANE_AUX_OFFSET_1(pipe) \ + _PIPE(pipe, PLANE_AUX_OFFSET_1_A, PLANE_AUX_OFFSET_1_B) +#define _PLANE_AUX_OFFSET_2(pipe) \ + _PIPE(pipe, PLANE_AUX_OFFSET_2_A, PLANE_AUX_OFFSET_2_B) +#define PLANE_AUX_OFFSET(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe)) + /* legacy palette */ #define _LGC_PALETTE_A 0x4a000 #define _LGC_PALETTE_B 0x4a800 @@ -6433,6 +6455,7 @@ enum { # define CHICKEN3_DGMG_DONE_FIX_DISABLE(1 << 2) #define CHICKEN_PAR1_1 _MMIO(0x42080) +#define SKL_RC_HASH_OUTSIDE (1 << 15) #define DPA_MASK_VBLANK_SRD (1 << 15) #define FORCE_ARB_IDLE_PLANES (1 << 14) #define SKL_EDP_PSR_FIX_RDWRAP(1 << 3) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 38de9df0ec60..2236abebd8bc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2064,11 +2064,19 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane) return 128; else return 512; + case I915_FORMAT_MOD_Y_TILED_CCS: + if (plane == 1) + return 64; + /* fall through */ case I915_FORMAT_MOD_Y_TILED: if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv)) return 128; else return 512; + case I915_FORMAT_MOD_Yf_TILED_CCS: + if (plane == 1) + return 64; I've said it before but readi
Re: [Intel-gfx] [PATCH 8/9] drm/i915: Implement .get_format_info() hook for CCS
On 17-02-27 17:13:41, Ville Syrjälä wrote: On Sun, Feb 26, 2017 at 02:41:50PM -0800, Chad Versace wrote: On Wed 04 Jan 2017, ville.syrj...@linux.intel.com wrote: > From: Ville Syrjälä <ville.syrj...@linux.intel.com> > > SKL+ display engine can scan out certain kinds of compressed surfaces > produced by the render engine. This involved telling the display engine > the location of the color control surfae (CCS) which describes which > parts of the main surface are compressed and which are not. The location > of CCS is provided by userspace as just another plane with its own offset. > > By providing our own format information for the CCS formats, we should > be able to make framebuffer_check() do the right thing for the CCS > surface as well. > > Note that we'll return the same format info for both Y and Yf tiled > format as that's what happens with the non-CCS Y vs. Yf as well. If > desired, we could potentially return a unique pointer for each > pixel_format+tiling+ccs combination, in which case we immediately be > able to tell if any of that stuff changed by just comparing the > pointers. But that does sound a bit wasteful space wise. > > v2: Drop the 'dev' argument from the hook > v3: Include the description of the CCS surface layout > > Cc: Vandana Kannan <vandana.kan...@intel.com> > Cc: Daniel Vetter <dan...@ffwll.ch> > Cc: Ben Widawsky <b...@bwidawsk.net> > Cc: Jason Ekstrand <ja...@jlekstrand.net> > Reviewed-by: Ben Widawsky <b...@bwidawsk.net> > Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> > --- > drivers/gpu/drm/i915/intel_display.c | 36 ++ > include/uapi/drm/drm_fourcc.h| 49 > 2 files changed, 85 insertions(+) > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h > index 9e1bb7fabcde..4581e3d41e5c 100644 > --- a/include/uapi/drm/drm_fourcc.h > +++ b/include/uapi/drm/drm_fourcc.h > @@ -230,6 +230,55 @@ extern "C" { > #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) > > /* > + * Intel color control surface (CCS) for render compression > + * > + * The framebuffer format must be one of the 8:8:8:8 RGB formats, > + * the main surface will be plane index 0 and will be Y/Yf-tiled, > + * the CCS will be plane index 1. > + * The paragraph below is... > + * Each byte of CCS contains 4 pairs of bits, with each pair of bits > + * matching an area of 8x4 pixels of the main surface. Which would seem > + * to match 2 cachelines containing 4x4 pixels each. The pairs bits within > + * the byte form a 2x2 grid, which thus matches a 16x8 pixel area of the > + * main surface. This is the 2x2 pattern the bits form (0=lsb, 7=msb): > + * --- > + * | 01 | 23 | > + * -- > + * | 45 | 67 | > + * --- ...almost correct. The hw docs state that each bit-pair of the CCS maps cacheline-pair, horizontally adjacent in the Y tile, of the primary surface. As a consequence, the remainder of the above paragraph is correct for 32-bit formats, but not others. Which is why the comment says at the very top that the fb needs to use a 8:8:8:8 format. IIRC that's the only thing the hardware supports. It is, and it is for the foreseeable future too. Chad, granted you say this isn't a nitpick below, but it is because Ville's patch is for the KMS case, it's not entirely relevant here. This is not a nitpick, because Vulkan and EGL users may want to share dma_bufs with a fat format like R32G32B32A32_UNORM, and want to have CCS enabled when possible. As long as the users use the dma_buf only the 3D engine, and don't submit it to KMS, it's all safe. For those users, we should document the bit-pair/cacheline-pair relationship correctly. And then preface the following detailed explanation and nice ascii diagrams by saying "this applies only to the 32-bit formats". Here's the relevant PRM quote: The Color Control Surface (CCS) contains the compression status of the cache-line pairs. The compression state of the cache-line pair is specified by 2 bits in the CCS. Each CCS cache-line represents an area on the main surface of 16x16 sets of 128 byte Y-tiled cache-line-pairs. CCS is always Y tiled. See this Mesa comment for more details: https://cgit.freedesktop.org/mesa/mesa/tree/src/intel/isl/isl.c?h=17.0#n211 > + * Actually only the lower bit of the pair seems to have any effect. > + * No idea why. 0 in the lower bit would seem to mean not compressed, > + * and 1 is compressed. The interpreation of the main surface data > + * when the block is marked compressed is unknown as of now. If I recall correctly (it's been several months since I inspected the bits), the high bit is actually significant. Bit pattern 11 means that t
[PATCH 1/3] [v3] drm: Add new DRM_IOCTL_MODE_GETPLANE2
Originally based off of a patch by Kristian. This new ioctl extends DRM_IOCTL_MODE_GETPLANE, by returning information about the modifiers that will work with each format. It's modified from Kristian's patch in that the modifiers and formats are setup by the driver, and then a callback is used to create the format list. The LOC was enough difference that I don't think it made sense to leave his authorship, but the new UABI was primarily his idea. Additionally, I hit a couple of drivers which Kristian missed updating. It also contains a change requested by Daniel to make the modifiers array a sentinel based structure instead of a sized one. Upon discussion on IRC, it was determined that having an invalid modifier might make sense in general as well. v2: - Make formats uint32_t, and use an offset, see the comment in the patch. Add a WARN_ON and early bail for when there are more than 32 formats. (Rob) - Remove DRM_DEBUG_KMS (Ville) - make flags come before count in struct (Ville) v3: - Make formats 64b again to defer the pain, and add a pad - Make init fail if > 64 instead of at get_plane. This could be made more optimal by doing it in get_plane because 0 masked modifiers don't need to be reported back to userspace. As a result, the first driver to go back 64 formats has to deal with this. - Fix the comment to be more clear. Cc: Rob Clark <robdcl...@gmail.com> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Daniel Stone <dan...@fooishbar.org> Cc: "Kristian H. Kristensen" <hoegsb...@gmail.com> References: https://patchwork.kernel.org/patch/9482393/ Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 +- drivers/gpu/drm/drm_ioctl.c | 2 +- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 67 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 7 ++- drivers/gpu/drm/i915/intel_sprite.c | 4 +- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 2 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 5 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 1 + drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 1 + drivers/gpu/drm/tegra/dc.c | 12 ++--- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 21 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm.h | 1 + include/uapi/drm/drm_fourcc.h | 11 include/uapi/drm/drm_mode.h | 44 40 files changed, 199 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a95916f1f..cd8a24c7c67d 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 20ebfb4fbdfa..89fded880807 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -283,6 +283,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universa
[PATCH 1/3] [v2] drm: Add new DRM_IOCTL_MODE_GETPLANE2
Originally based off of a patch by Kristian. This new ioctl extends DRM_IOCTL_MODE_GETPLANE, by returning information about the modifiers that will work with each format. It's modified from Kristian's patch in that the modifiers and formats are setup by the driver, and then a callback is used to create the format list. The LOC was enough difference that I don't think it made sense to leave his authorship, but the new UABI was primarily his idea. Additionally, I hit a couple of drivers which Kristian missed updating. It also contains a change requested by Daniel to make the modifiers array a sentinel based structure instead of a sized one. Upon discussion on IRC, it was determined that having an invalid modifier might make sense in general as well. v2: - Make formats uint32_t, and use an offset, see the comment in the patch. Add a WARN_ON and early bail for when there are more than 32 formats. (Rob) - Name format_modifiers annotation properly (Ville) - Remove DRM_DEBUG_KMS (Ville) - make flags come before count in struct (Ville) Cc: Rob Clark <robdcl...@gmail.com> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Daniel Stone <dan...@fooishbar.org> Cc: "Kristian H. Kristensen" <hoegsb...@gmail.com> References: https://patchwork.kernel.org/patch/9482393/ Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 +- drivers/gpu/drm/drm_ioctl.c | 2 +- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 65 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 7 ++- drivers/gpu/drm/i915/intel_sprite.c | 4 +- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 2 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 5 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 1 + drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 1 + drivers/gpu/drm/tegra/dc.c | 12 ++--- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 21 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm.h | 1 + include/uapi/drm/drm_fourcc.h | 11 + include/uapi/drm/drm_mode.h | 36 ++ 40 files changed, 189 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a95916f1f..cd8a24c7c67d 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 20ebfb4fbdfa..89fded880807 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -283,6 +283,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { devm_kfree(drm->dev, plane); diff --git a/drivers
Re: [PATCH 2/3] drm/i915: Add format modifiers for Intel
On 17-01-12 20:32:07, Ville Syrjälä wrote: On Thu, Jan 12, 2017 at 10:00:55AM -0800, Ben Widawsky wrote: On 17-01-12 12:51:20, Ville Syrjälä wrote: >On Wed, Jan 11, 2017 at 04:51:17PM -0800, Ben Widawsky wrote: >> This was based on a patch originally by Kristian. It has been modified >> pretty heavily to use the new callbacks from the previous patch. >> >> Cc: Kristian H. Kristensen <hoegsb...@gmail.com> >> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> >> --- >> drivers/gpu/drm/i915/intel_display.c | 109 ++- >> drivers/gpu/drm/i915/intel_sprite.c | 33 ++- >> 2 files changed, 137 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c >> index 8715b1083d1d..26f3a911b999 100644 >> --- a/drivers/gpu/drm/i915/intel_display.c >> +++ b/drivers/gpu/drm/i915/intel_display.c >> @@ -61,6 +61,11 @@ static const uint32_t i8xx_primary_formats[] = { >>DRM_FORMAT_XRGB, >> }; >> >> +static const uint64_t i8xx_format_modifiers[] = { >> + I915_FORMAT_MOD_X_TILED, > >Did we want to list the linear modifier in these as well? > Yeah. My initial response was no, but yes. We should. I was using DRM_FORMAT_MOD_NONE in its place, it should be linear, and it should be defined in the array. >> + DRM_FORMAT_MOD_INVALID >> +}; >> + >> /* Primary plane formats for gen >= 4 */ >> static const uint32_t i965_primary_formats[] = { >>DRM_FORMAT_C8, >> @@ -71,6 +76,11 @@ static const uint32_t i965_primary_formats[] = { >>DRM_FORMAT_XBGR2101010, >> }; >> >> +static const uint64_t i965_format_modifiers[] = { >> + I915_FORMAT_MOD_X_TILED, >> + DRM_FORMAT_MOD_INVALID >> +}; > >We could just share the i8xx array. The name of the array should perhaps >be i9xx_format_modifiers[] in that case. That's sort of the naming >convention we've been left with for things that apply to more or less >all the platforms. > Got it thanks. This is a relic from Kristian's original patch which tied the modifiers to the formats in place. It made more sense there to have a separate i8xx >> + >> static const uint32_t skl_primary_formats[] = { >>DRM_FORMAT_C8, >>DRM_FORMAT_RGB565, >> @@ -86,6 +96,12 @@ static const uint32_t skl_primary_formats[] = { >>DRM_FORMAT_VYUY, >> }; >> >> +static const uint64_t skl_format_modifiers[] = { >> + I915_FORMAT_MOD_Y_TILED, > >Yf missing? and linear > Yes, thanks. I'm kind of scared to add Yf to be honest :P >> + I915_FORMAT_MOD_X_TILED, >> + DRM_FORMAT_MOD_INVALID >> +}; >> + >> /* Cursor formats */ >> static const uint32_t intel_cursor_formats[] = { >>DRM_FORMAT_ARGB, >> @@ -15173,6 +15189,87 @@ void intel_plane_destroy(struct drm_plane *plane) >>kfree(to_intel_plane(plane)); >> } >> >> +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) >> +{ >> + if (modifier == DRM_FORMAT_MOD_NONE) >> + return true; >> + >> + switch (format) { >> + case DRM_FORMAT_C8: >> + case DRM_FORMAT_RGB565: >> + case DRM_FORMAT_XRGB1555: >> + case DRM_FORMAT_XRGB: >> + return modifier == I915_FORMAT_MOD_X_TILED; >> + default: >> + return false; >> + } >> +} >> + >> +static bool i965_mod_supported(uint32_t format, uint64_t modifier) >> +{ >> + switch (format) { >> + case DRM_FORMAT_C8: >> + case DRM_FORMAT_RGB565: >> + case DRM_FORMAT_XRGB: >> + case DRM_FORMAT_XBGR: >> + case DRM_FORMAT_XRGB2101010: >> + case DRM_FORMAT_XBGR2101010: >> + return modifier == I915_FORMAT_MOD_X_TILED; >> + default: >> + return false; >> + } >> +} > >Hmm. There should be no format vs. tiling restrictions on these >platforms, so presumably a simple "return true" should cover it all. >That does perhaps remove the usefulness of these functions for >verifying that the format or modifier is supported at all One of the reasons for changing to this current format-modifier lookup at all was Kristian's approach was considered fragile. If for whatever reason formats are added, or removed, we'll catch it here. Also, it maybe let's us do something on cursor plane at some point (I don't actually know). So yeah, we can return true, but I like that it's spelled out explicitly. Makes it easy to com
Re: [PATCH 2/3] drm/i915: Add format modifiers for Intel
On 17-01-12 12:51:20, Ville Syrjälä wrote: On Wed, Jan 11, 2017 at 04:51:17PM -0800, Ben Widawsky wrote: This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 109 ++- drivers/gpu/drm/i915/intel_sprite.c | 33 ++- 2 files changed, 137 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8715b1083d1d..26f3a911b999 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -61,6 +61,11 @@ static const uint32_t i8xx_primary_formats[] = { DRM_FORMAT_XRGB, }; +static const uint64_t i8xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, Did we want to list the linear modifier in these as well? Yeah. My initial response was no, but yes. We should. I was using DRM_FORMAT_MOD_NONE in its place, it should be linear, and it should be defined in the array. + DRM_FORMAT_MOD_INVALID +}; + /* Primary plane formats for gen >= 4 */ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_C8, @@ -71,6 +76,11 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i965_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_INVALID +}; We could just share the i8xx array. The name of the array should perhaps be i9xx_format_modifiers[] in that case. That's sort of the naming convention we've been left with for things that apply to more or less all the platforms. Got it thanks. This is a relic from Kristian's original patch which tied the modifiers to the formats in place. It made more sense there to have a separate i8xx + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -86,6 +96,12 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Y_TILED, Yf missing? and linear Yes, thanks. I'm kind of scared to add Yf to be honest :P + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -15173,6 +15189,87 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + if (modifier == DRM_FORMAT_MOD_NONE) + return true; + + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} Hmm. There should be no format vs. tiling restrictions on these platforms, so presumably a simple "return true" should cover it all. That does perhaps remove the usefulness of these functions for verifying that the format or modifier is supported at all One of the reasons for changing to this current format-modifier lookup at all was Kristian's approach was considered fragile. If for whatever reason formats are added, or removed, we'll catch it here. Also, it maybe let's us do something on cursor plane at some point (I don't actually know). So yeah, we can return true, but I like that it's spelled out explicitly. Makes it easy to compare it to the docs as well to make sure our code is correct. The benefit is of course I can combine i965_mod_supported() with i8xx_mod_supported() I'm honestly fine with changing it as well, I just don't see a huge reason to change it since I've already typed it up. I'll leave it to you. [ ] Yes, change it. [ ] No, leave it. but I've been thinking that addfb should perhaps just iterate through the format and modifier lists for every plane. Would avoid having to effectively maintain the same lists in multiple places. I don't quite follow this. Can you elaborate? + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: +
[PATCH 3/3] drm/i915: Add support for GET_PLANE2 CCS modifiers
Cc: Kristian Høgsberg <k...@bitplanet.net> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 10 -- drivers/gpu/drm/i915/intel_sprite.c | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 26f3a911b999..cf1b19447af1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -97,6 +97,8 @@ static const uint32_t skl_primary_formats[] = { }; static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_INVALID @@ -15225,15 +15227,19 @@ static bool skl_mod_supported(uint32_t format, uint64_t modifier) switch (format) { case DRM_FORMAT_C8: case DRM_FORMAT_RGB565: + return modifier == I915_FORMAT_MOD_Y_TILED || + modifier == I915_FORMAT_MOD_X_TILED; case DRM_FORMAT_XRGB: case DRM_FORMAT_XBGR: case DRM_FORMAT_ARGB: case DRM_FORMAT_ABGR: - return modifier == I915_FORMAT_MOD_Y_TILED || + return modifier == I915_FORMAT_MOD_Yf_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED_CCS || + modifier == I915_FORMAT_MOD_Y_TILED || modifier == I915_FORMAT_MOD_X_TILED; case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XBGR2101010: - return modifier == I915_FORMAT_MOD_X_TILED; + return modifier == I915_FORMAT_MOD_X_TILED; case DRM_FORMAT_YUYV: case DRM_FORMAT_YVYU: case DRM_FORMAT_UYVY: diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 152ec8196d41..eed7195212b7 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1045,6 +1045,8 @@ static uint32_t skl_plane_formats[] = { }; static const uint64_t skl_plane_format_modifiers[] = { + I915_FORMAT_MOD_Yf_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_INVALID -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/3] drm: Add new DRM_IOCTL_MODE_GETPLANE2
Originally based off of a patch by Kristian. This new ioctl extends DRM_IOCTL_MODE_GETPLANE, by returning information about the modifiers that will work with each format. It's modified from Kristian's patch in that the modifiers and formats are setup by the driver, and then a callback is used to create the format list. The LOC was enough difference that I don't think it made sense to leave his authorship, but the new UABI was primarily his idea. Additionally, I hit a couple of drivers which Kristian missed updating. It also contains a change requested by Daniel to make the modifiers array a sentinel based structure instead of a sized one. Upon discussion on IRC, it was determined that having an invalid modifier might make sense in general as well. References: https://patchwork.kernel.org/patch/9482393/ Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 +- drivers/gpu/drm/drm_ioctl.c | 2 +- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 67 - drivers/gpu/drm/drm_simple_kms_helper.c | 3 ++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 7 ++- drivers/gpu/drm/i915/intel_sprite.c | 4 +- drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 2 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 5 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 1 + drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 1 + drivers/gpu/drm/tegra/dc.c | 12 ++--- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 21 +++- include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm.h | 1 + include/uapi/drm/drm_fourcc.h | 11 include/uapi/drm/drm_mode.h | 27 ++ 40 files changed, 182 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a95916f1f..cd8a24c7c67d 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 20ebfb4fbdfa..89fded880807 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -283,6 +283,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, _plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { devm_kfree(drm->dev, plane); diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index eff2fe47e26a..94dbcbc9ad8f 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -283,7 +283,7 @@ int malidp_de_planes_init(struct drm_device *drm) DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(drm, >base, crtcs, _de_plane_funcs, formats, - n
[PATCH 2/3] drm/i915: Add format modifiers for Intel
This was based on a patch originally by Kristian. It has been modified pretty heavily to use the new callbacks from the previous patch. Cc: Kristian H. Kristensen <hoegsb...@gmail.com> Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/intel_display.c | 109 ++- drivers/gpu/drm/i915/intel_sprite.c | 33 ++- 2 files changed, 137 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8715b1083d1d..26f3a911b999 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -61,6 +61,11 @@ static const uint32_t i8xx_primary_formats[] = { DRM_FORMAT_XRGB, }; +static const uint64_t i8xx_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_INVALID +}; + /* Primary plane formats for gen >= 4 */ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_C8, @@ -71,6 +76,11 @@ static const uint32_t i965_primary_formats[] = { DRM_FORMAT_XBGR2101010, }; +static const uint64_t i965_format_modifiers[] = { + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_INVALID +}; + static const uint32_t skl_primary_formats[] = { DRM_FORMAT_C8, DRM_FORMAT_RGB565, @@ -86,6 +96,12 @@ static const uint32_t skl_primary_formats[] = { DRM_FORMAT_VYUY, }; +static const uint64_t skl_format_modifiers[] = { + I915_FORMAT_MOD_Y_TILED, + I915_FORMAT_MOD_X_TILED, + DRM_FORMAT_MOD_INVALID +}; + /* Cursor formats */ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB, @@ -15173,6 +15189,87 @@ void intel_plane_destroy(struct drm_plane *plane) kfree(to_intel_plane(plane)); } +static bool i8xx_mod_supported(uint32_t format, uint64_t modifier) +{ + if (modifier == DRM_FORMAT_MOD_NONE) + return true; + + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XRGB: + return modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool i965_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == I915_FORMAT_MOD_X_TILED; + default: + return false; + } +} + +static bool skl_mod_supported(uint32_t format, uint64_t modifier) +{ + switch (format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XRGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_ABGR: + return modifier == I915_FORMAT_MOD_Y_TILED || + modifier == I915_FORMAT_MOD_X_TILED; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return modifier == I915_FORMAT_MOD_X_TILED; + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + default: + return false; + } + +} + +static bool intel_plane_format_mod_supported(struct drm_plane *plane, +uint32_t format, +uint64_t modifier) +{ + struct drm_i915_private *dev_priv = to_i915(plane->dev); + + if (modifier == DRM_FORMAT_MOD_NONE) + return true; + + if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID)) + return false; + + if (WARN_ON(plane->type != DRM_PLANE_TYPE_PRIMARY && + plane->type != DRM_PLANE_TYPE_OVERLAY)) + return false; + + if (INTEL_GEN(dev_priv) >= 9) + return skl_mod_supported(format, modifier); + else if (INTEL_GEN(dev_priv) >= 4) + return i965_mod_supported(format, modifier); + else + return i8xx_mod_supported(format, modifier); + + return false; +} + const struct drm_plane_funcs intel_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -15182,6 +15279,7 @@ const struct drm_plane_funcs intel_plane_funcs = { .atomic_set_property = intel_plane_atomic_set_property, .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, + .format_mod_supported = intel_plane_format_mod_supported, }; static int @@ -15324,6 +15422,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) const uint32_t *intel_primary_formats; unsigned int supported_rotations; u
[PATCH 0/3] GET_PLANE2 w/ i915 implementation
This patch series implements GET_PLANE2 support for Intel platforms and defines the new kernel UAPI. The idea was originally introduced by Kristian. Ultimately, the purpose of the new API is to provide the ability to query per-plane modifiers in KMS. These modifiers, which are just fb modifiers, will be used by the client to enable optimal modifications for framebuffers. A reference implementation in kmscube is referenced (in that code is a comment for an optimal algorithm not implemented). This work has been discussed on the mailing list and IRC over the last few weeks and this is a result of the agreed changes. There is still some debate about the UAPI, I believe, but I can firmly say that this seems entirely sufficient for Intel platforms in the foreseeable future. Cc: Kristian Høgsberg <k...@bitplanet.net> Cc: Rob Clark <robdcl...@gmail.com> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com> Cc: Daniel Vetter <daniel.vet...@ffwll.ch> References: (ccs modifier) https://lists.freedesktop.org/archives/intel-gfx/2017-January/116022.html References: (GBM modifiers) https://lists.freedesktop.org/archives/mesa-dev/2017-January/139284.html References: (kmscube) https://github.com/bwidawsk/kmscube/commit/55519640f5a1a21983e267fb39e4cf48f6312ef9 References: (libdrm) https://lists.freedesktop.org/archives/dri-devel/2016-December/127942.html Ben Widawsky (3): drm: Add new DRM_IOCTL_MODE_GETPLANE2 drm/i915: Add format modifiers for Intel drm/i915: Add support for GET_PLANE2 CCS modifiers drivers/gpu/drm/arc/arcpgu_crtc.c | 1 + drivers/gpu/drm/arm/hdlcd_crtc.c| 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c| 1 + drivers/gpu/drm/armada/armada_overlay.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 4 +- drivers/gpu/drm/drm_ioctl.c | 2 +- drivers/gpu/drm/drm_modeset_helper.c| 1 + drivers/gpu/drm/drm_plane.c | 67 +- drivers/gpu/drm/drm_simple_kms_helper.c | 3 + drivers/gpu/drm/exynos/exynos_drm_plane.c | 2 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 1 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 2 +- drivers/gpu/drm/i915/intel_display.c| 116 +++- drivers/gpu/drm/i915/intel_sprite.c | 31 +++ drivers/gpu/drm/imx/ipuv3-plane.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c| 2 +- drivers/gpu/drm/meson/meson_plane.c | 1 + drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 2 +- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 5 +- drivers/gpu/drm/omapdrm/omap_plane.c| 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 5 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/sti/sti_cursor.c| 1 + drivers/gpu/drm/sti/sti_gdp.c | 2 +- drivers/gpu/drm/sti/sti_hqvdp.c | 2 +- drivers/gpu/drm/sun4i/sun4i_layer.c | 1 + drivers/gpu/drm/tegra/dc.c | 12 +-- drivers/gpu/drm/vc4/vc4_plane.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +- drivers/gpu/drm/zte/zx_plane.c | 2 +- include/drm/drm_plane.h | 21 - include/drm/drm_simple_kms_helper.h | 1 + include/uapi/drm/drm.h | 1 + include/uapi/drm/drm_fourcc.h | 11 +++ include/uapi/drm/drm_mode.h | 27 ++ 40 files changed, 320 insertions(+), 36 deletions(-) -- 2.11.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6] drm: add fourcc codes for 16bit R and RG
On 17-01-11 17:05:04, Ville Syrjälä wrote: On Thu, Jan 05, 2017 at 02:45:37PM +0100, Christian König wrote: Am 05.01.2017 um 12:37 schrieb Ville Syrjälä: > On Wed, Jan 04, 2017 at 07:38:55PM +0100, Rainer Hochecker wrote: >> From: Rainer Hochecker>> >> This adds fourcc codes for 16bit planes required for DRM buffer >> export to mesa. >> >> Signed-off-by: Rainer Hochecker > Reviewed-by: Ville Syrjälä Good to see some work landing on that part, patch is Acked-by: Christian König . Has the userspace side of this been reviewed already? /me wonders if it's safe to push this... I acked the mesa side, and Rainer sent a version 2 which also looked fine to me. Let me bump that thread... > >> --- >> include/uapi/drm/drm_fourcc.h | 7 +++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h >> index a5890bf..d230e58 100644 >> --- a/include/uapi/drm/drm_fourcc.h >> +++ b/include/uapi/drm/drm_fourcc.h >> @@ -41,10 +41,17 @@ extern "C" { >> /* 8 bpp Red */ >> #define DRM_FORMAT_R8fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ >> >> +/* 16 bpp Red */ >> +#define DRM_FORMAT_R16fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */ >> + >> /* 16 bpp RG */ >> #define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */ >> #define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ >> >> +/* 32 bpp RG */ >> +#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */ >> +#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */ >> + >> /* 8 bpp RGB */ >> #define DRM_FORMAT_RGB332fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ >> #define DRM_FORMAT_BGR233fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ >> -- >> 2.9.3 -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/9] drm/i915: SKL+ render decompression support
On 17-01-04 20:42:23, Ville Syrjälä wrote: >From: Ville Syrjälä > >This series enables the SKL+ display engine render decompression >support. Some bits and pieces of the i915 code are based on work >from various people, but I just put my name on it since it >would be hard to figure out which parts came from where. > >Entire series available here: >git://github.com/vsyrjala/linux.git fb_format_dedup_4_ccs > >Cc: Vandana Kannan >Cc: Daniel Vetter >Cc: Ben Widawsky >Cc: Jason Ekstrand >Cc: Laurent Pinchart > In addition to review comments I've left, this series (patch 8 and 9 in particular) is: Tested-by: Ben Widawsky [snip] -- Ben Widawsky, Intel Open Source Technology Center
[Intel-gfx] [PATCH 8/9] drm/i915: Implement .get_format_info() hook for CCS
On 17-01-05 16:24:56, Tvrtko Ursulin wrote: > >On 04/01/2017 18:42, ville.syrjala at linux.intel.com wrote: >>From: Ville Syrjälä >> >>SKL+ display engine can scan out certain kinds of compressed surfaces >>produced by the render engine. This involved telling the display engine >>the location of the color control surfae (CCS) which describes which >>parts of the main surface are compressed and which are not. The location >>of CCS is provided by userspace as just another plane with its own offset. >> >>By providing our own format information for the CCS formats, we should >>be able to make framebuffer_check() do the right thing for the CCS >>surface as well. >> >>Note that we'll return the same format info for both Y and Yf tiled >>format as that's what happens with the non-CCS Y vs. Yf as well. If >>desired, we could potentially return a unique pointer for each >>pixel_format+tiling+ccs combination, in which case we immediately be >>able to tell if any of that stuff changed by just comparing the >>pointers. But that does sound a bit wasteful space wise. >> >>v2: Drop the 'dev' argument from the hook >>v3: Include the description of the CCS surface layout >> >>Cc: Vandana Kannan >>Cc: Daniel Vetter >>Cc: Ben Widawsky >>Cc: Jason Ekstrand >>Reviewed-by: Ben Widawsky >>Signed-off-by: Ville Syrjälä >>--- >> drivers/gpu/drm/i915/intel_display.c | 36 ++ >> include/uapi/drm/drm_fourcc.h| 49 >> >> 2 files changed, 85 insertions(+) >> >>diff --git a/drivers/gpu/drm/i915/intel_display.c >>b/drivers/gpu/drm/i915/intel_display.c >>index c4662b2e9613..38de9df0ec60 100644 >>--- a/drivers/gpu/drm/i915/intel_display.c >>+++ b/drivers/gpu/drm/i915/intel_display.c >>@@ -2478,6 +2478,41 @@ static unsigned int >>intel_fb_modifier_to_tiling(uint64_t fb_modifier) >> } >> } >> >>+static const struct drm_format_info ccs_formats[] = { >>+ { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2, .cpp = { >>4, 1, }, .hsub = 16, .vsub = 8, }, >>+ { .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2, .cpp = { >>4, 1, }, .hsub = 16, .vsub = 8, }, >>+ { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2, .cpp = { >>4, 1, }, .hsub = 16, .vsub = 8, }, >>+ { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2, .cpp = { >>4, 1, }, .hsub = 16, .vsub = 8, }, >>+}; >>+ >>+static const struct drm_format_info * >>+lookup_format_info(const struct drm_format_info formats[], >>+int num_formats, u32 format) >>+{ >>+ int i; >>+ >>+ for (i = 0; i < num_formats; i++) { >>+ if (formats[i].format == format) >>+ return [i]; >>+ } >>+ >>+ return NULL; >>+} >>+ >>+static const struct drm_format_info * >>+intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd) >>+{ >>+ switch (cmd->modifier[0]) { >>+ case I915_FORMAT_MOD_Y_TILED_CCS: >>+ case I915_FORMAT_MOD_Yf_TILED_CCS: >>+ return lookup_format_info(ccs_formats, >>+ ARRAY_SIZE(ccs_formats), >>+ cmd->pixel_format); >>+ default: >>+ return NULL; >>+ } >>+} >>+ >> static int >> intel_fill_fb_info(struct drm_i915_private *dev_priv, >> struct drm_framebuffer *fb) >>@@ -16083,6 +16118,7 @@ static void intel_atomic_state_free(struct >>drm_atomic_state *state) >> >> static const struct drm_mode_config_funcs intel_mode_funcs = { >> .fb_create = intel_user_framebuffer_create, >>+ .get_format_info = intel_get_format_info, >> .output_poll_changed = intel_fbdev_output_poll_changed, >> .atomic_check = intel_atomic_check, >> .atomic_commit = intel_atomic_commit, >>diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h >>index 9e1bb7fabcde..4581e3d41e5c 100644 >>--- a/include/uapi/drm/drm_fourcc.h >>+++ b/include/uapi/drm/drm_fourcc.h >>@@ -230,6 +230,55 @@ extern "C" { >> #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) >> >> /* >>+ * Intel color control surface (CCS) for render compression >>+ * >>+ * The framebuffer format must be one of the 8:8:8:8 RGB formats, >>+ * the main surface will be plane index 0 and will be Y/Yf-tiled, >>+ * the CCS will be plane ind
[PATCH 9/9] drm/i915: Add render decompression support
On 17-01-04 20:42:32, Ville Syrjälä wrote: >From: Ville Syrjälä > >SKL+ display engine can scan out certain kinds of compressed surfaces >produced by the render engine. This involved telling the display engine >the location of the color control surfae (CCS) which describes >which parts of the main surface are compressed and which are not. The >location of CCS is provided by userspace as just another plane with its >own offset. > >Add the required stuff to validate the user provided AUX plane metadata >and convert the user provided linear offset into something the hardware >can consume. > >Due to hardware limitations we require that the main surface and >the AUX surface (CCS) be part of the same bo. The hardware also >makes life hard by not allowing you to provide separate x/y offsets >for the main and AUX surfaces (excpet with NV12), so finding suitable >offsets for both requires a bit of work. Assuming we still want keep >playing tricks with the offsets. I've just gone with a dumb "search >backward for suitable offsets" approach, which is far from optimal, >but it works. > >Also not all planes will be capable of scanning out compressed surfaces, >and eg. 90/270 degree rotation is not supported in combination with >decompression either. > >This patch may contain work from at least the following people: >* Vandana Kannan >* Daniel Vetter >* Ben Widawsky > >Cc: Vandana Kannan >Cc: Daniel Vetter >Cc: Ben Widawsky >Cc: Jason Ekstrand >Signed-off-by: Ville Syrjälä >--- > drivers/gpu/drm/i915/i915_reg.h | 22 > drivers/gpu/drm/i915/intel_display.c | 219 +-- > drivers/gpu/drm/i915/intel_pm.c | 8 +- > drivers/gpu/drm/i915/intel_sprite.c | 5 + > 4 files changed, 240 insertions(+), 14 deletions(-) > >diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h >index 00970aa77afa..05e18e742776 100644 >--- a/drivers/gpu/drm/i915/i915_reg.h >+++ b/drivers/gpu/drm/i915/i915_reg.h >@@ -6209,6 +6209,28 @@ enum { > _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \ > _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)) > >+#define PLANE_AUX_DIST_1_A0x701c0 >+#define PLANE_AUX_DIST_2_A0x702c0 >+#define PLANE_AUX_DIST_1_B0x711c0 >+#define PLANE_AUX_DIST_2_B0x712c0 >+#define _PLANE_AUX_DIST_1(pipe) \ >+ _PIPE(pipe, PLANE_AUX_DIST_1_A, PLANE_AUX_DIST_1_B) >+#define _PLANE_AUX_DIST_2(pipe) \ >+ _PIPE(pipe, PLANE_AUX_DIST_2_A, PLANE_AUX_DIST_2_B) >+#define PLANE_AUX_DIST(pipe, plane) \ >+ _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe)) >+ >+#define PLANE_AUX_OFFSET_1_A 0x701c4 >+#define PLANE_AUX_OFFSET_2_A 0x702c4 >+#define PLANE_AUX_OFFSET_1_B 0x711c4 >+#define PLANE_AUX_OFFSET_2_B 0x712c4 >+#define _PLANE_AUX_OFFSET_1(pipe) \ >+ _PIPE(pipe, PLANE_AUX_OFFSET_1_A, PLANE_AUX_OFFSET_1_B) >+#define _PLANE_AUX_OFFSET_2(pipe) \ >+ _PIPE(pipe, PLANE_AUX_OFFSET_2_A, PLANE_AUX_OFFSET_2_B) >+#define PLANE_AUX_OFFSET(pipe, plane) \ >+ _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe)) >+ > /* legacy palette */ > #define _LGC_PALETTE_A 0x4a000 > #define _LGC_PALETTE_B 0x4a800 >diff --git a/drivers/gpu/drm/i915/intel_display.c >b/drivers/gpu/drm/i915/intel_display.c >index 38de9df0ec60..b547332eeda1 100644 >--- a/drivers/gpu/drm/i915/intel_display.c >+++ b/drivers/gpu/drm/i915/intel_display.c >@@ -2064,11 +2064,19 @@ intel_tile_width_bytes(const struct drm_framebuffer >*fb, int plane) > return 128; > else > return 512; >+ case I915_FORMAT_MOD_Y_TILED_CCS: >+ if (plane == 1) >+ return 64; >+ /* fall through */ > case I915_FORMAT_MOD_Y_TILED: > if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv)) > return 128; > else > return 512; >+ case I915_FORMAT_MOD_Yf_TILED_CCS: >+ if (plane == 1) >+ return 64; >+ /* fall through */ > case I915_FORMAT_MOD_Yf_TILED: > /* >* Bspec seems to suggest that the Yf tile width would >@@ -2156,7 +2164,7 @@ static unsigned int intel_surf_alignment(const struct >drm_framebuffer *fb, > struct drm_i915_private *dev_priv = to_i915(fb->dev); > > /* AUX_DIST needs only 4K alignment */ >- if (fb->format->forma
[PATCH 1/9] drm: Add mode_config .get_format_info() hook
On 17-01-04 20:42:24, Ville Syrjälä wrote: >From: Ville Syrjälä > >Allow drivers to return a custom drm_format_info structure for special >fb layouts. We'll use this for the compression control surface in i915. > >v2: Fix drm_get_format_info() kernel doc (Laurent) >Don't pass 'dev' to the new hook (Laurent) > >Cc: Laurent Pinchart >Cc: Ben Widawsky >Signed-off-by: Ville Syrjälä >--- > drivers/gpu/drm/drm_fb_cma_helper.c | 2 +- > drivers/gpu/drm/drm_fourcc.c | 25 + > drivers/gpu/drm/drm_framebuffer.c| 9 +++-- > drivers/gpu/drm/drm_modeset_helper.c | 2 +- > include/drm/drm_fourcc.h | 6 ++ > include/drm/drm_mode_config.h| 14 ++ > 6 files changed, 54 insertions(+), 4 deletions(-) > >diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c >b/drivers/gpu/drm/drm_fb_cma_helper.c >index 20a4011f790d..de3c9fe116fc 100644 >--- a/drivers/gpu/drm/drm_fb_cma_helper.c >+++ b/drivers/gpu/drm/drm_fb_cma_helper.c >@@ -177,7 +177,7 @@ struct drm_framebuffer >*drm_fb_cma_create_with_funcs(struct drm_device *dev, > int ret; > int i; > >- info = drm_format_info(mode_cmd->pixel_format); >+ info = drm_get_format_info(dev, mode_cmd); > if (!info) > return ERR_PTR(-EINVAL); > >diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c >index 90d2cc8da8eb..f9b6445e846a 100644 >--- a/drivers/gpu/drm/drm_fourcc.c >+++ b/drivers/gpu/drm/drm_fourcc.c >@@ -199,6 +199,31 @@ const struct drm_format_info *drm_format_info(u32 format) > EXPORT_SYMBOL(drm_format_info); > > /** >+ * drm_get_format_info - query information for a given framebuffer >configuration >+ * @dev: DRM device >+ * @mode_cmd: metadata from the userspace fb creation request >+ * >+ * Returns: >+ * The instance of struct drm_format_info that describes the pixel format, or >+ * NULL if the format is unsupported. >+ */ >+const struct drm_format_info * >+drm_get_format_info(struct drm_device *dev, >+ const struct drm_mode_fb_cmd2 *mode_cmd) >+{ >+ const struct drm_format_info *info = NULL; >+ >+ if (dev->mode_config.funcs->get_format_info) >+ info = dev->mode_config.funcs->get_format_info(mode_cmd); >+ >+ if (!info) >+ info = drm_format_info(mode_cmd->pixel_format); >+ >+ return info; >+} >+EXPORT_SYMBOL(drm_get_format_info); >+ >+/** > * drm_format_num_planes - get the number of planes for format > * @format: pixel format (DRM_FORMAT_*) > * >diff --git a/drivers/gpu/drm/drm_framebuffer.c >b/drivers/gpu/drm/drm_framebuffer.c >index 588ccc3a2218..e276fcdc3a62 100644 >--- a/drivers/gpu/drm/drm_framebuffer.c >+++ b/drivers/gpu/drm/drm_framebuffer.c >@@ -126,11 +126,13 @@ int drm_mode_addfb(struct drm_device *dev, > return 0; > } > >-static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) >+static int framebuffer_check(struct drm_device *dev, >+ const struct drm_mode_fb_cmd2 *r) > { > const struct drm_format_info *info; > int i; > >+ /* check if the format is supported at all */ > info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); > if (!info) { > struct drm_format_name_buf format_name; >@@ -140,6 +142,9 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 >*r) > return -EINVAL; > } > >+ /* now let the driver pick its own format info */ >+ info = drm_get_format_info(dev, r); >+ > if (r->width == 0 || r->width % info->hsub) { > DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); > return -EINVAL; >@@ -263,7 +268,7 @@ drm_internal_framebuffer_create(struct drm_device *dev, > return ERR_PTR(-EINVAL); > } > >- ret = framebuffer_check(r); >+ ret = framebuffer_check(dev, r); > if (ret) > return ERR_PTR(ret); > >diff --git a/drivers/gpu/drm/drm_modeset_helper.c >b/drivers/gpu/drm/drm_modeset_helper.c >index cc44a9a4b004..2b33825f2f93 100644 >--- a/drivers/gpu/drm/drm_modeset_helper.c >+++ b/drivers/gpu/drm/drm_modeset_helper.c >@@ -78,7 +78,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev, > int i; > > fb->dev = dev; >- fb->format = drm_format_info(mode_cmd->pixel_format); >+ fb->format = drm_get_format_info(dev, mode_cmd); > fb->width = mode_cmd->width; > fb->height = mode_cmd->height; > for (i = 0; i < 4; i++) { >diff --git a/include/drm/drm_fourcc.h b
[PATCH 2/2] modetest: Teach modetest about format info
On 16-12-20 16:13:33, Kristian H. Kristensen wrote: >From: "Kristian H. Kristensen" > >BUG=chrome-os-partner:56407 >TEST=modetest on a KMS driver that exposes modifiers should print those > >Change-Id: I91b2a408b1c8f112d7ba5d0998119b3c800b199c >--- > tests/modetest/modetest.c | 40 > 1 file changed, 36 insertions(+), 4 deletions(-) > >diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c >index dedd286..091bcba 100644 >--- a/tests/modetest/modetest.c >+++ b/tests/modetest/modetest.c >@@ -417,9 +417,30 @@ static void dump_framebuffers(struct device *dev) > printf("\n"); > } > >+static const char * >+mod_to_string(uint64_t mod, char *buf, int len) >+{ >+ switch (mod) { >+ case DRM_FORMAT_MOD_NONE: >+ return "LINEAR"; Just being pedantic here but a lack of modifier doesn't only mean that it's linear, it means that there is no compression, and whatever else the future holds. I'd just maybe return something like "unmodified". >+ case I915_FORMAT_MOD_X_TILED: >+ return "X_TILED"; >+ case I915_FORMAT_MOD_Y_TILED: >+ return "Y_TILED"; >+ case I915_FORMAT_MOD_Yf_TILED: >+ return "Yf_TILED"; >+ case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE: >+ return "SAMSUNG_64_32_TILE"; >+ default: >+ snprintf(buf, len, "%016x", mod); >+ return buf; >+ } >+} >+ > static void dump_planes(struct device *dev) > { >- unsigned int i, j; >+ unsigned int i, j, k; >+ char buf[17]; > > printf("Planes:\n"); > printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\tpossible crtcs\n"); >@@ -442,8 +463,19 @@ static void dump_planes(struct device *dev) > continue; > > printf(" formats:"); >- for (j = 0; j < ovr->count_formats; j++) >- printf(" %4.4s", (char *)>formats[j]); >+ for (j = 0; j < ovr->count_formats; j++) { >+ if (ovr->count_format_modifiers == 0) { >+ printf(" %4.4s", (char *)>formats[j]); >+ continue; >+ } >+ struct drm_format_modifier *fm; >+ for (k = 0; k < ovr->count_format_modifiers; k++) { >+ fm = >format_modifiers[k]; >+ if (fm->formats & (1 << j)) >+ printf(" %4.4s:%s", (char >*)>formats[j], >+ mod_to_string(fm->modifier, buf, >sizeof(buf))); >+ } >+ } Wasn't the plan to have only 1 modifier per plane? Did that change? The GBM interface only allows 1 modifier per plane. > printf("\n"); > > if (plane->props) { >@@ -609,7 +641,7 @@ static struct resources *get_resources(struct device *dev) > if (!res->planes) > goto error; > >- get_resource(res, plane_res, plane, Plane); >+ get_resource(res, plane_res, plane, Plane2); > get_properties(res, plane_res, plane, PLANE); > > return res; >-- >2.9.3 >
[PATCH 1/2] Add DRM_IOCTL_MODE_GETPLANE2 ioctl wrapper
r->format_modifiers = >+ drmAllocCpy(U642VOID(ovr.format_modifier_ptr), >+ ovr.count_format_modifiers, >+ sizeof(struct drm_format_modifier)); >+ if (ovr.count_format_modifiers && !r->format_modifiers) { >+ drmFree(r->formats); >+ drmFree(r); >+ r = 0; > } > > err_allocs: > drmFree(U642VOID(ovr.format_type_ptr)); >+ drmFree(U642VOID(ovr.format_modifier_ptr)); > > return r; > } > >+drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id) >+{ >+ drmModePlanePtr r = get_plane(DRM_IOCTL_MODE_GETPLANE2, fd, plane_id); >+ >+ if (r || errno != EINVAL) >+ return r; >+ >+ return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id); >+} >+ IMO, it should be up to the client to fallback to drmModeGetPlane if DRM_IOCTL_MODE_GETPLANE2 doesn't exist. However, as long as the modifiers are returned as 0, it should work fine. Reviewed-by: Ben Widawsky >+drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) >+{ >+ return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id); >+} >+ > void drmModeFreePlane(drmModePlanePtr ptr) > { > if (!ptr) > return; > > drmFree(ptr->formats); >+ drmFree(ptr->format_modifiers); > drmFree(ptr); > } > >diff --git a/xf86drmMode.h b/xf86drmMode.h >index b684967..044f38e 100644 >--- a/xf86drmMode.h >+++ b/xf86drmMode.h >@@ -328,6 +328,9 @@ typedef struct _drmModePlane { > > uint32_t possible_crtcs; > uint32_t gamma_size; >+ >+ uint32_t count_format_modifiers; >+ struct drm_format_modifier *format_modifiers; > } drmModePlane, *drmModePlanePtr; > > typedef struct _drmModePlaneRes { >@@ -479,6 +482,7 @@ extern int drmModePageFlipTarget(int fd, uint32_t crtc_id, >uint32_t fb_id, > > extern drmModePlaneResPtr drmModeGetPlaneResources(int fd); > extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id); >+extern drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id); > extern int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, > uint32_t fb_id, uint32_t flags, > int32_t crtc_x, int32_t crtc_y, >-- >2.9.3 >
[PATCH 37/37] drm/i915: Implement .get_format_info() hook for CCS
On 16-11-18 21:53:13, Ville Syrjälä wrote: >From: Ville Syrjälä > >By providing our own format information for the CCS formats, we should >be able to make framebuffer_check() do the right thing for the CCS >surface as well. > I was hoping to see that patch as well :-). If you're adding the new fb modifiers, I think it'd make sense to make it part of this series. Alternatively, I can take 36, and 37 and make it part of my series, then integrate that last bit. It's up to you. >Note that we'll return the same format info for both Y and Yf tiled >format as that's what happens with the non-CCS Y vs. Yf as well. If >desired, we could potentially return a unique pointer for each >pixel_format+tiling+ccs combination, in which case we immediately be >able to tell if any of that stuff changed by just comparing the >pointers. But that does sound a bit wasteful space wise. > >Cc: Ben Widawsky >Cc: intel-gfx at lists.freedesktop.org >Signed-off-by: Ville Syrjälä I have a comment below however, you can consider it: Reviewed-by: Ben Widawsky >--- > drivers/gpu/drm/i915/intel_display.c | 37 > include/uapi/drm/drm_fourcc.h| 3 +++ > 2 files changed, 40 insertions(+) > >diff --git a/drivers/gpu/drm/i915/intel_display.c >b/drivers/gpu/drm/i915/intel_display.c >index 7b7135be3b9e..de6909770c68 100644 >--- a/drivers/gpu/drm/i915/intel_display.c >+++ b/drivers/gpu/drm/i915/intel_display.c >@@ -2488,6 +2488,42 @@ static unsigned int >intel_fb_modifier_to_tiling(uint64_t fb_modifier) > } > } > >+static const struct drm_format_info ccs_formats[] = { >+ { .format = DRM_FORMAT_XRGB, .depth = 24, .num_planes = 2, .cpp = { >4, 1, }, .hsub = 16, .vsub = 8, }, >+ { .format = DRM_FORMAT_XBGR, .depth = 24, .num_planes = 2, .cpp = { >4, 1, }, .hsub = 16, .vsub = 8, }, >+ { .format = DRM_FORMAT_ARGB, .depth = 32, .num_planes = 2, .cpp = { >4, 1, }, .hsub = 16, .vsub = 8, }, >+ { .format = DRM_FORMAT_ABGR, .depth = 32, .num_planes = 2, .cpp = { >4, 1, }, .hsub = 16, .vsub = 8, }, >+}; >+ >+static const struct drm_format_info * >+lookup_format_info(const struct drm_format_info formats[], >+ int num_formats, u32 format) >+{ >+ int i; >+ >+ for (i = 0; i < num_formats; i++) { >+ if (formats[i].format == format) >+ return [i]; >+ } >+ >+ return NULL; >+} >+ >+static const struct drm_format_info * >+intel_get_format_info(struct drm_device *dev, >+const struct drm_mode_fb_cmd2 *cmd) >+{ >+ switch (cmd->modifier[0]) { >+ case I915_FORMAT_MOD_Y_TILED_CCS: >+ case I915_FORMAT_MOD_Yf_TILED_CCS: >+ return lookup_format_info(ccs_formats, >+ARRAY_SIZE(ccs_formats), >+cmd->pixel_format); >+ default: >+ return NULL; >+ } >+} >+ It sort of seems like somewhat of a waste to provide this if implementations are allowed to return NULL. It's like saying, "DRM core will check stuff for you if you provide the info, but you don't have to do it if you don't want to." If that's the case you may as well provide a driver hook to just do the check, ie. s/mod_funcs->get_format_info/mode_functs->check_format/ > static int > intel_fill_fb_info(struct drm_i915_private *dev_priv, > struct drm_framebuffer *fb) >@@ -15922,6 +15958,7 @@ intel_user_framebuffer_create(struct drm_device *dev, > > static const struct drm_mode_config_funcs intel_mode_funcs = { > .fb_create = intel_user_framebuffer_create, >+ .get_format_info = intel_get_format_info, > .output_poll_changed = intel_fbdev_output_poll_changed, > .atomic_check = intel_atomic_check, > .atomic_commit = intel_atomic_commit, >diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h >index a5890bf44c0a..2926d916f199 100644 >--- a/include/uapi/drm/drm_fourcc.h >+++ b/include/uapi/drm/drm_fourcc.h >@@ -218,6 +218,9 @@ extern "C" { > */ > #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) > >+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4) >+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5) >+ > /* > * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks > * -- Ben Widawsky, Intel Open Source Technology Center
[RFC][PATCH] drm: Nuke modifier[1-3]
Acked-by: Ben Widawsky On 16-11-16 13:33:16, Ville Syrjälä wrote: >From: Ville Syrjälä > >It has been suggested that having per-plane modifiers is making life >more difficult for userspace, so let's just retire modifier[1-3] and >use modifier[0] to apply to the entire framebuffer. > >Obviosuly this means that if individual planes need different tiling >layouts and whatnot we will need a new modifier for each combination >of planes with different tiling layouts. > >For a bit of extra backwards compatilbilty the kernel will allow >non-zero modifier[1+] but it require that they will match modifier[0]. >This in case there's existing userspace out there that sets >modifier[1+] to something non-zero with planar formats. > >Mostly a cocci job, with a bit of manual stuff mixed in. > >@@ >struct drm_framebuffer *fb; >expression E; >@@ >- fb->modifier[E] >+ fb->modifier > >@@ >struct drm_framebuffer fb; >expression E; >@@ >- fb.modifier[E] >+ fb.modifier > >Cc: Kristian Høgsberg >Cc: Ben Widawsky >Cc: Rob Clark >Cc: Daniel Vetter >Cc: Tomeu Vizoso >Cc: dczaplejewicz at collabora.co.uk >Suggested-by: Kristian Høgsberg >Signed-off-by: Ville Syrjälä >--- > drivers/gpu/drm/drm_atomic.c | 2 +- > drivers/gpu/drm/drm_framebuffer.c | 7 +++ > drivers/gpu/drm/drm_modeset_helper.c | 2 +- > drivers/gpu/drm/i915/i915_debugfs.c | 4 +- > drivers/gpu/drm/i915/intel_atomic_plane.c | 4 +- > drivers/gpu/drm/i915/intel_display.c | 72 +++ > drivers/gpu/drm/i915/intel_fbdev.c| 2 +- > drivers/gpu/drm/i915/intel_pm.c | 22 +- > drivers/gpu/drm/i915/intel_sprite.c | 14 +++--- > drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +- > include/drm/drm_framebuffer.h | 4 +- > include/uapi/drm/drm_mode.h | 13 +++--- > 12 files changed, 79 insertions(+), 69 deletions(-) > >diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c >index 57e0a6e96f6d..bfaa6e4a9989 100644 >--- a/drivers/gpu/drm/drm_atomic.c >+++ b/drivers/gpu/drm/drm_atomic.c >@@ -922,12 +922,12 @@ static void drm_atomic_plane_print_state(struct >drm_printer *p, > > drm_printf(p, "\t\tformat=%s\n", > drm_get_format_name(fb->pixel_format, > _name)); >+ drm_printf(p, "\t\t\tmodifier=0x%llx\n", fb->modifier); > drm_printf(p, "\t\tsize=%dx%d\n", fb->width, fb->height); > drm_printf(p, "\t\tlayers:\n"); > for (i = 0; i < n; i++) { > drm_printf(p, "\t\t\tpitch[%d]=%u\n", i, > fb->pitches[i]); > drm_printf(p, "\t\t\toffset[%d]=%u\n", i, > fb->offsets[i]); >- drm_printf(p, "\t\t\tmodifier[%d]=0x%llx\n", i, >fb->modifier[i]); > } > } > drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG()); >diff --git a/drivers/gpu/drm/drm_framebuffer.c >b/drivers/gpu/drm/drm_framebuffer.c >index 06ad3d1350c4..cbf0c893f426 100644 >--- a/drivers/gpu/drm/drm_framebuffer.c >+++ b/drivers/gpu/drm/drm_framebuffer.c >@@ -177,6 +177,13 @@ static int framebuffer_check(const struct >drm_mode_fb_cmd2 *r) > return -EINVAL; > } > >+ if (r->flags & DRM_MODE_FB_MODIFIERS && >+ r->modifier[i] != r->modifier[0]) { >+ DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n", >+r->modifier[i], i); >+ return -EINVAL; >+ } >+ > /* modifier specific checks: */ > switch (r->modifier[i]) { > case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE: >diff --git a/drivers/gpu/drm/drm_modeset_helper.c >b/drivers/gpu/drm/drm_modeset_helper.c >index 2f452b3dd40e..633355e02398 100644 >--- a/drivers/gpu/drm/drm_modeset_helper.c >+++ b/drivers/gpu/drm/drm_modeset_helper.c >@@ -93,8 +93,8 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer >*fb, > for (i = 0; i < 4; i++) { > fb->pitches[i] = mode_cmd->pitches[i]; > fb->offsets[i] = mode_cmd->offsets[i]; >- fb->modifier[i] = mode_cmd->modifier[i]; > } >+ fb->modifier = mode_cmd->modifier[0]; > fb->pixel_format = mode_cmd->pixel_format; > fb->flags = mode_cmd->flags; > } >diff --git a/drivers/gpu/drm/i915/
[PATCH] intel: Add Geminilake PCI IDs
From: Ben Widawsky <b...@bwidawsk.net> Signed-off-by: Ben Widawsky --- intel/intel_chipset.h | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h index 514f659..41fc0da 100644 --- a/intel/intel_chipset.h +++ b/intel/intel_chipset.h @@ -218,6 +218,9 @@ #define PCI_CHIP_BROXTON_3 0x1A85 #define PCI_CHIP_BROXTON_4 0x5A85 +#define PCI_CHIP_GLK 0x3184 +#define PCI_CHIP_GLK_2X6 0x3185 + #define IS_MOBILE(devid) ((devid) == PCI_CHIP_I855_GM || \ (devid) == PCI_CHIP_I915_GM || \ (devid) == PCI_CHIP_I945_GM || \ @@ -446,9 +449,13 @@ (devid) == PCI_CHIP_BROXTON_3 || \ (devid) == PCI_CHIP_BROXTON_4) -#define IS_GEN9(devid) (IS_SKYLAKE(devid) || \ -IS_BROXTON(devid) || \ -IS_KABYLAKE(devid)) +#define IS_GEMINILAKE(devid) ((devid) == PCI_CHIP_GLK || \ +(devid) == PCI_CHIP_GLK_2X6) + +#define IS_GEN9(devid) (IS_SKYLAKE(devid) || \ +IS_BROXTON(devid) || \ +IS_KABYLAKE(devid) || \ +IS_GEMINILAKE(devid)) #define IS_9XX(dev)(IS_GEN3(dev) || \ IS_GEN4(dev) || \ -- 2.10.2
[Mesa-dev] [PATCH] [v2] intel: Add missing SKL device IDs
On Tue, Feb 16, 2016 at 03:42:45PM -0800, Ben Widawsky wrote: > A new list yielded new devices that apparently have shipped, or will ship. > > v2: I can't read. 0x192d is GT3 > > Signed-off-by: Ben Widawsky > --- > intel/intel_chipset.h | 11 --- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h > index 35148e5..9c24701 100644 > --- a/intel/intel_chipset.h > +++ b/intel/intel_chipset.h > @@ -168,6 +168,7 @@ > #define PCI_CHIP_SKYLAKE_DT_GT1 0x1902 > #define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906 > #define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A /* Reserved */ > +#define PCI_CHIP_SKYLAKE_H_GT1 0x190B > #define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E /* Reserved */ > #define PCI_CHIP_SKYLAKE_DT_GT2 0x1912 > #define PCI_CHIP_SKYLAKE_FUSED0_GT2 0x1913 /* Reserved */ > @@ -182,6 +183,7 @@ > #define PCI_CHIP_SKYLAKE_GT3 0x1926 > #define PCI_CHIP_SKYLAKE_HALO_GT30x192B /* Reserved */ > #define PCI_CHIP_SKYLAKE_SRV_GT4 0x192A > +#define PCI_CHIP_SKYLAKE_MEDIA_SRV_GT3 0x192D > #define PCI_CHIP_SKYLAKE_DT_GT4 0x1932 > #define PCI_CHIP_SKYLAKE_SRV_GT4X0x193A > #define PCI_CHIP_SKYLAKE_H_GT4 0x193B > @@ -376,7 +378,8 @@ > #define IS_SKL_GT1(devid)((devid) == PCI_CHIP_SKYLAKE_ULT_GT1|| \ >(devid) == PCI_CHIP_SKYLAKE_ULX_GT1|| \ >(devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \ > - (devid) == PCI_CHIP_SKYLAKE_SRV_GT1) > + (devid) == PCI_CHIP_SKYLAKE_SRV_GT1|| \ > + (devid) == PCI_CHIP_SKYLAKE_H_GT1) > > #define IS_SKL_GT2(devid)((devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \ >(devid) == PCI_CHIP_SKYLAKE_FUSED0_GT2 || \ > @@ -390,13 +393,15 @@ >(devid) == PCI_CHIP_SKYLAKE_MOBILE_GT2) > > #define IS_SKL_GT3(devid)((devid) == PCI_CHIP_SKYLAKE_GT3|| \ > - (devid) == PCI_CHIP_SKYLAKE_HALO_GT3) > + (devid) == PCI_CHIP_SKYLAKE_HALO_GT3 || \ > + (devid) == PCI_CHIP_SKYLAKE_MEDIA_SRV_GT3) > + > > #define IS_SKL_GT4(devid)((devid) == PCI_CHIP_SKYLAKE_SRV_GT4|| \ >(devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \ >(devid) == PCI_CHIP_SKYLAKE_SRV_GT4X || \ >(devid) == PCI_CHIP_SKYLAKE_H_GT4 || \ > - (devid) == PCI_CHIP_SKYLAKE_WKS_GT4) > + (devid) == PCI_CHIP_SKYLAKE_WKS_GT4|| \ Really sloppy on my part... This hunk is gone from my local patch. I'm not even sure really how I sent this out... > > #define IS_KBL_GT1(devid)((devid) == PCI_CHIP_KABYLAKE_ULT_GT1_5 || \ >(devid) == PCI_CHIP_KABYLAKE_ULX_GT1_5 || \ > -- > 2.7.1 > > ___ > mesa-dev mailing list > mesa-dev at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[PATCH] [v2] intel: Add missing SKL device IDs
A new list yielded new devices that apparently have shipped, or will ship. v2: I can't read. 0x192d is GT3 Signed-off-by: Ben Widawsky --- intel/intel_chipset.h | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h index 35148e5..9c24701 100644 --- a/intel/intel_chipset.h +++ b/intel/intel_chipset.h @@ -168,6 +168,7 @@ #define PCI_CHIP_SKYLAKE_DT_GT10x1902 #define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906 #define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A /* Reserved */ +#define PCI_CHIP_SKYLAKE_H_GT1 0x190B #define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E /* Reserved */ #define PCI_CHIP_SKYLAKE_DT_GT20x1912 #define PCI_CHIP_SKYLAKE_FUSED0_GT20x1913 /* Reserved */ @@ -182,6 +183,7 @@ #define PCI_CHIP_SKYLAKE_GT3 0x1926 #define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B /* Reserved */ #define PCI_CHIP_SKYLAKE_SRV_GT4 0x192A +#define PCI_CHIP_SKYLAKE_MEDIA_SRV_GT3 0x192D #define PCI_CHIP_SKYLAKE_DT_GT40x1932 #define PCI_CHIP_SKYLAKE_SRV_GT4X 0x193A #define PCI_CHIP_SKYLAKE_H_GT4 0x193B @@ -376,7 +378,8 @@ #define IS_SKL_GT1(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT1|| \ (devid) == PCI_CHIP_SKYLAKE_ULX_GT1|| \ (devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \ -(devid) == PCI_CHIP_SKYLAKE_SRV_GT1) +(devid) == PCI_CHIP_SKYLAKE_SRV_GT1|| \ +(devid) == PCI_CHIP_SKYLAKE_H_GT1) #define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \ (devid) == PCI_CHIP_SKYLAKE_FUSED0_GT2 || \ @@ -390,13 +393,15 @@ (devid) == PCI_CHIP_SKYLAKE_MOBILE_GT2) #define IS_SKL_GT3(devid) ((devid) == PCI_CHIP_SKYLAKE_GT3|| \ -(devid) == PCI_CHIP_SKYLAKE_HALO_GT3) +(devid) == PCI_CHIP_SKYLAKE_HALO_GT3 || \ +(devid) == PCI_CHIP_SKYLAKE_MEDIA_SRV_GT3) + #define IS_SKL_GT4(devid) ((devid) == PCI_CHIP_SKYLAKE_SRV_GT4|| \ (devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \ (devid) == PCI_CHIP_SKYLAKE_SRV_GT4X || \ (devid) == PCI_CHIP_SKYLAKE_H_GT4 || \ -(devid) == PCI_CHIP_SKYLAKE_WKS_GT4) +(devid) == PCI_CHIP_SKYLAKE_WKS_GT4|| \ #define IS_KBL_GT1(devid) ((devid) == PCI_CHIP_KABYLAKE_ULT_GT1_5 || \ (devid) == PCI_CHIP_KABYLAKE_ULX_GT1_5 || \ -- 2.7.1
[PATCH] intel: Add missing SKL device IDs
A new list yielded new devices that apparently have shipped, or will ship. Signed-off-by: Ben Widawsky --- intel/intel_chipset.h | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h index 35148e5..392f7ba 100644 --- a/intel/intel_chipset.h +++ b/intel/intel_chipset.h @@ -168,6 +168,7 @@ #define PCI_CHIP_SKYLAKE_DT_GT10x1902 #define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906 #define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A /* Reserved */ +#define PCI_CHIP_SKYLAKE_H_GT1 0x190B #define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E /* Reserved */ #define PCI_CHIP_SKYLAKE_DT_GT20x1912 #define PCI_CHIP_SKYLAKE_FUSED0_GT20x1913 /* Reserved */ @@ -182,6 +183,7 @@ #define PCI_CHIP_SKYLAKE_GT3 0x1926 #define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B /* Reserved */ #define PCI_CHIP_SKYLAKE_SRV_GT4 0x192A +#define PCI_CHIP_SKYLAKE_MEDIA_SRV_GT4 0x192D #define PCI_CHIP_SKYLAKE_DT_GT40x1932 #define PCI_CHIP_SKYLAKE_SRV_GT4X 0x193A #define PCI_CHIP_SKYLAKE_H_GT4 0x193B @@ -376,7 +378,8 @@ #define IS_SKL_GT1(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT1|| \ (devid) == PCI_CHIP_SKYLAKE_ULX_GT1|| \ (devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \ -(devid) == PCI_CHIP_SKYLAKE_SRV_GT1) +(devid) == PCI_CHIP_SKYLAKE_SRV_GT1|| \ +(devid) == PCI_CHIP_SKYLAKE_H_GT1) #define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \ (devid) == PCI_CHIP_SKYLAKE_FUSED0_GT2 || \ @@ -396,7 +399,8 @@ (devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \ (devid) == PCI_CHIP_SKYLAKE_SRV_GT4X || \ (devid) == PCI_CHIP_SKYLAKE_H_GT4 || \ -(devid) == PCI_CHIP_SKYLAKE_WKS_GT4) +(devid) == PCI_CHIP_SKYLAKE_WKS_GT4|| \ +(devid) == PCI_CHIP_SKYLAKE_MEDIA_SRV_GT4) #define IS_KBL_GT1(devid) ((devid) == PCI_CHIP_KABYLAKE_ULT_GT1_5 || \ (devid) == PCI_CHIP_KABYLAKE_ULX_GT1_5 || \ -- 2.7.1
[PATCH 2/2] intel: Cleanup SKL PCI ID definitions.
This removes ones which aren't used 0x190b, 192a), and adds some new ones. I kept the original names where possible. Cc: Kristian Høgsberg Cc: Damien Lespiau Signed-off-by: Ben Widawsky --- intel/intel_chipset.h | 46 ++ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h index 6c8dc73..a0f17c6 100644 --- a/intel/intel_chipset.h +++ b/intel/intel_chipset.h @@ -165,21 +165,24 @@ #define PCI_CHIP_CHERRYVIEW_2 0x22b2 #define PCI_CHIP_CHERRYVIEW_3 0x22b3 -#define PCI_CHIP_SKYLAKE_ULT_GT2 0x1916 +#define PCI_CHIP_SKYLAKE_DT_GT10x1902 #define PCI_CHIP_SKYLAKE_ULT_GT1 0x1906 -#define PCI_CHIP_SKYLAKE_ULT_GT3 0x1926 -#define PCI_CHIP_SKYLAKE_ULT_GT2F 0x1921 -#define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E -#define PCI_CHIP_SKYLAKE_ULX_GT2 0x191E +#define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A /* Reserved */ +#define PCI_CHIP_SKYLAKE_ULX_GT1 0x190E /* Reserved */ #define PCI_CHIP_SKYLAKE_DT_GT20x1912 -#define PCI_CHIP_SKYLAKE_DT_GT10x1902 +#define PCI_CHIP_SKYLAKE_FUSED0_GT20x1913 /* Reserved */ +#define PCI_CHIP_SKYLAKE_FUSED1_GT20x1915 /* Reserved */ +#define PCI_CHIP_SKYLAKE_ULT_GT2 0x1916 +#define PCI_CHIP_SKYLAKE_FUSED2_GT20x1917 /* Reserved */ +#define PCI_CHIP_SKYLAKE_SRV_GT2 0x191A /* Reserved */ #define PCI_CHIP_SKYLAKE_HALO_GT2 0x191B -#define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B -#define PCI_CHIP_SKYLAKE_HALO_GT1 0x190B -#define PCI_CHIP_SKYLAKE_SRV_GT2 0x191A -#define PCI_CHIP_SKYLAKE_SRV_GT3 0x192A -#define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A #define PCI_CHIP_SKYLAKE_WKS_GT2 0x191D +#define PCI_CHIP_SKYLAKE_ULX_GT2 0x191E +#define PCI_CHIP_SKYLAKE_MOBILE_GT20x1921 /* Reserved */ +#define PCI_CHIP_SKYLAKE_GT3E_540 0x1923 +#define PCI_CHIP_SKYLAKE_GT3 0x1926 +#define PCI_CHIP_SKYLAKE_GT3E_550 0x1927 +#define PCI_CHIP_SKYLAKE_HALO_GT3 0x192B /* Reserved */ #define PCI_CHIP_SKYLAKE_DT_GT40x1932 #define PCI_CHIP_SKYLAKE_SRV_GT4 0x193A #define PCI_CHIP_SKYLAKE_H_GT4 0x193B @@ -351,20 +354,23 @@ #define IS_SKL_GT1(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT1|| \ (devid) == PCI_CHIP_SKYLAKE_ULX_GT1|| \ (devid) == PCI_CHIP_SKYLAKE_DT_GT1 || \ -(devid) == PCI_CHIP_SKYLAKE_HALO_GT1 || \ (devid) == PCI_CHIP_SKYLAKE_SRV_GT1) -#define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT2|| \ -(devid) == PCI_CHIP_SKYLAKE_ULT_GT2F || \ -(devid) == PCI_CHIP_SKYLAKE_ULX_GT2|| \ -(devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \ -(devid) == PCI_CHIP_SKYLAKE_HALO_GT2 || \ +#define IS_SKL_GT2(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT2 || \ +(devid) == PCI_CHIP_SKYLAKE_FUSED0_GT2 || \ +(devid) == PCI_CHIP_SKYLAKE_FUSED1_GT2 || \ +(devid) == PCI_CHIP_SKYLAKE_ULT_GT2|| \ +(devid) == PCI_CHIP_SKYLAKE_FUSED2_GT2 || \ (devid) == PCI_CHIP_SKYLAKE_SRV_GT2|| \ -(devid) == PCI_CHIP_SKYLAKE_WKS_GT2) +(devid) == PCI_CHIP_SKYLAKE_HALO_GT2 || \ +(devid) == PCI_CHIP_SKYLAKE_WKS_GT2|| \ +(devid) == PCI_CHIP_SKYLAKE_ULX_GT2|| \ +(devid) == PCI_CHIP_SKYLAKE_MOBILE_GT2) -#define IS_SKL_GT3(devid) ((devid) == PCI_CHIP_SKYLAKE_ULT_GT3|| \ +#define IS_SKL_GT3(devid) ((devid) == PCI_CHIP_SKYLAKE_GT3|| \ (devid) == PCI_CHIP_SKYLAKE_HALO_GT3 || \ -(devid) == PCI_CHIP_SKYLAKE_SRV_GT3) +(devid) == PCI_CHIP_SKYLAKE_GT3E_540 || \ +(devid) == PCI_CHIP_SKYLAKE_GT3E_550) #define IS_SKL_GT4(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \ (devid) == PCI_CHIP_SKYLAKE_SRV_GT4|| \ -- 2.6.1
[PATCH 1/2] intel: Add SKL GT4 PCI IDs
Cc: Kristian Høgsberg Cc: Damien Lespiau Signed-off-by: Ben Widawsky --- intel/intel_chipset.h | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h index 253ea71..6c8dc73 100644 --- a/intel/intel_chipset.h +++ b/intel/intel_chipset.h @@ -180,6 +180,10 @@ #define PCI_CHIP_SKYLAKE_SRV_GT3 0x192A #define PCI_CHIP_SKYLAKE_SRV_GT1 0x190A #define PCI_CHIP_SKYLAKE_WKS_GT2 0x191D +#define PCI_CHIP_SKYLAKE_DT_GT40x1932 +#define PCI_CHIP_SKYLAKE_SRV_GT4 0x193A +#define PCI_CHIP_SKYLAKE_H_GT4 0x193B +#define PCI_CHIP_SKYLAKE_WKS_GT4 0x193D #define PCI_CHIP_BROXTON_0 0x0A84 #define PCI_CHIP_BROXTON_1 0x1A84 @@ -362,9 +366,15 @@ (devid) == PCI_CHIP_SKYLAKE_HALO_GT3 || \ (devid) == PCI_CHIP_SKYLAKE_SRV_GT3) +#define IS_SKL_GT4(devid) ((devid) == PCI_CHIP_SKYLAKE_DT_GT4 || \ +(devid) == PCI_CHIP_SKYLAKE_SRV_GT4|| \ +(devid) == PCI_CHIP_SKYLAKE_H_GT4 || \ +(devid) == PCI_CHIP_SKYLAKE_WKS_GT4) + #define IS_SKYLAKE(devid) (IS_SKL_GT1(devid) || \ IS_SKL_GT2(devid) || \ -IS_SKL_GT3(devid)) +IS_SKL_GT3(devid) || \ +IS_SKL_GT4(devid)) #define IS_BROXTON(devid) ((devid) == PCI_CHIP_BROXTON_0 || \ (devid) == PCI_CHIP_BROXTON_1 || \ -- 2.6.1
[PATCH v2] drm/vgem: implement virtual GEM
On Sat, Jan 31, 2015 at 11:02:05AM -0500, Rob Clark wrote: > On Fri, Jan 30, 2015 at 1:05 PM, Zach Reizner wrote: > > This patch implements the virtual GEM driver with PRIME sharing which > > allows vgem to import a gem object from other drivers for the purpose > > of mmap-ing them to userspace. The mmap is done using the mmap > > operation exported by other drivers. > > > > v2: remove platform_device and do not attach to dma bufs > > > > Reviewed-by: Stéphane Marchesin > > Signed-off-by: Adam Jackson > > Signed-off-by: Ben Widawsky > > Signed-off-by: Zach Reizner > > couple small suggestions/comments below, but with those addressed, > > Reviewed-by: Rob Clark > > > --- > > drivers/gpu/drm/Kconfig | 9 + > > drivers/gpu/drm/Makefile| 1 + > > drivers/gpu/drm/vgem/Makefile | 4 + > > drivers/gpu/drm/vgem/vgem_dma_buf.c | 96 + > > drivers/gpu/drm/vgem/vgem_drv.c | 390 > > > > drivers/gpu/drm/vgem/vgem_drv.h | 57 ++ > > 6 files changed, 557 insertions(+) > > create mode 100644 drivers/gpu/drm/vgem/Makefile > > create mode 100644 drivers/gpu/drm/vgem/vgem_dma_buf.c > > create mode 100644 drivers/gpu/drm/vgem/vgem_drv.c > > create mode 100644 drivers/gpu/drm/vgem/vgem_drv.h > > > > [snip] > > > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c > > b/drivers/gpu/drm/vgem/vgem_drv.c > > new file mode 100644 > > index 000..e20f4a4 > > --- /dev/null > > +++ b/drivers/gpu/drm/vgem/vgem_drv.c > > @@ -0,0 +1,390 @@ > > +/* > > + * Copyright 2011 Red Hat, Inc. > > + * Copyright © 2014 The Chromium OS Authors > > + * > > + * 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 > > + * on the rights to use, copy, modify, merge, publish, distribute, sub > > + * license, and/or sell copies of the Software, and to permit persons to > > whom > > + * them Software is furnished to do so, subject to the following > > conditions: > > + * > > + * The above copyright notice and this permission notice (including the > > next > > + * paragraph) shall be included in all copies or substantial portions of > > the > > + * Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > > OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT > > SHALL > > + * THE AUTHORS 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: > > + * Adam Jackson > > + * Ben Widawsky > > + */ > > + > > +/** > > + * This is vgem, a (non-hardware-backed) GEM service. This is used by > > Mesa's > > + * software renderer and the X server for efficient buffer sharing. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include "vgem_drv.h" > > + > > +#define DRIVER_NAME"vgem" > > +#define DRIVER_DESC"Virtual GEM provider" > > +#define DRIVER_DATE"20120112" > > +#define DRIVER_MAJOR 1 > > +#define DRIVER_MINOR 0 > > + > > +void vgem_gem_put_pages(struct drm_vgem_gem_object *obj) > > +{ > > + int num_pages = obj->base.size / PAGE_SIZE; > > + int i; > > + > > + for (i = 0; i < num_pages; i++) { > > + if (obj->pages[i] == NULL) > > + break; > > seems like other than this break statement, you could use > drm_gem_put_pages().. not entirely sure why you'd encounter a null > page, but if there is a legit reason for that, then just add the check > in drm_gem_put_pages() (plus maybe a comment) and use that.. > First, this code predated drm_gem_put_pages, so it was probably just an oversight that a consolidated function existed. As for the NULL, it's because the cleanup of failed vgem get_pages() just calls vgem put_pages() (you can't have sparsely populated entries, but the last n pointers can be NULL). If the helpers
[PATCH v2] drm/vgem: implement virtual GEM
On Fri, Jan 30, 2015 at 10:05:45AM -0800, Zach Reizner wrote: > This patch implements the virtual GEM driver with PRIME sharing which > allows vgem to import a gem object from other drivers for the purpose > of mmap-ing them to userspace. The mmap is done using the mmap > operation exported by other drivers. > > v2: remove platform_device and do not attach to dma bufs > > Reviewed-by: Stéphane Marchesin > Signed-off-by: Adam Jackson > Signed-off-by: Ben Widawsky > Signed-off-by: Zach Reizner Looks good to me. [snip]
[Intel-gfx] [PATCH 4/4] drm/i915: Opportunistically reduce flushing at execbuf
On Tue, Dec 16, 2014 at 07:57:39AM +, Chris Wilson wrote: > On Mon, Dec 15, 2014 at 01:06:40PM -0800, Ben Widawsky wrote: > > On Mon, Dec 15, 2014 at 08:39:35PM +, Chris Wilson wrote: > > > On Mon, Dec 15, 2014 at 11:56:05AM -0800, Ben Widawsky wrote: > > > > On Mon, Dec 15, 2014 at 08:20:50AM +, Chris Wilson wrote: > > > > > On Mon, Dec 15, 2014 at 08:55:32AM +0100, Daniel Vetter wrote: > > > > > > On Sun, Dec 14, 2014 at 03:37:36PM -0800, Ben Widawsky wrote: > > > > > > > It's not hard, and I think that's a good idea as well. One reason > > > > > > > I didn't put > > > > > > > such code in this series is that moves away from a global DRM > > > > > > > solution (and like > > > > > > > I said in the cover-letter, I am fine with that). Implementing > > > > > > > this, I think in > > > > > > > the i915 code we'd just iterate through the BOs until we got to a > > > > > > > certain > > > > > > > threshold, then just call wbinvd() from i915 and not even both > > > > > > > with drm_cache. > > > > > > > You could also maybe try to shorcut if there are more than X > > > > > > > buffers. > > > > > > > > > > > > I don't mind an i915 specific solution (we have them already in many > > > > > > places). So will wait for the results of this experiments before > > > > > > merging > > > > > > more patches. > > > > > > > > > > I actually think an i915 specific solution is required, as the making > > > > > drm_clflush_pages autoselect is likely to cause regressions on unaware > > > > > drivers (e.g. anything that has a reservation loop in execbuf like > > > > > i915). > > > > > > > > Assuming the stall is gone as Jesse said in the other thread, I can't > > > > envision a > > > > scenario where wbinvd would do worse on large objects. > > > > > > It is the multiple wbinvd performed at each execbuffer that is worrisome. > > > > This patch attempts to avoid that by dropping all flushing after the first > > WBINVD. > > But you can't make the central change to drm_clflush_* without driver > specific workarounds like this patch... Good point. I'll do an i915 one when I find the time. I was still hoping to get some numbers from Eero on this series.
[PATCH 2/4] drm/cache: Try to be smarter about clflushing on x86
On Sat, Dec 13, 2014 at 08:15:22PM -0800, Matt Turner wrote: > On Sat, Dec 13, 2014 at 7:08 PM, Ben Widawsky > wrote: > > Any GEM driver which has very large objects and a slow CPU is subject to > > very > > long waits simply for clflushing incoherent objects. Generally, each > > individual > > object is not a problem, but if you have very large objects, or very many > > objects, the flushing begins to show up in profiles. Because on x86 we know > > the > > cache size, we can easily determine when an object will use all the cache, > > and > > forego iterating over each cacheline. > > > > We need to be careful when using wbinvd. wbinvd() is itself potentially slow > > because it requires synchronizing the flush across all CPUs so they have a > > coherent view of memory. This can result in either stalling work being done > > on > > other CPUs, or this call itself stalling while waiting for a CPU to accept > > the > > interrupt. Also, wbinvd() also has the downside of invalidating all > > cachelines, > > so we don't want to use it unless we're sure we already own most of the > > cachelines. > > > > The current algorithm is very naive. I think it can be tweaked more, and it > > would be good if someone else gave it some thought. I am pretty confident in > > i915, we can even skip the IPI in the execbuf path with minimal code change > > (or > > perhaps just some verifying of the existing code). It would be nice to hear > > what > > other developers who depend on this code think. > > > > Cc: Intel GFX > > Signed-off-by: Ben Widawsky > > --- > > drivers/gpu/drm/drm_cache.c | 20 +--- > > 1 file changed, 17 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c > > index d7797e8..6009c2d 100644 > > --- a/drivers/gpu/drm/drm_cache.c > > +++ b/drivers/gpu/drm/drm_cache.c > > @@ -64,6 +64,20 @@ static void drm_cache_flush_clflush(struct page *pages[], > > drm_clflush_page(*pages++); > > mb(); > > } > > + > > +static bool > > +drm_cache_should_clflush(unsigned long num_pages) > > +{ > > + const int cache_size = boot_cpu_data.x86_cache_size; > > + > > + /* For now the algorithm simply checks if the number of pages to be > > +* flushed is greater than the entire system cache. One could make > > the > > +* function more aware of the actual system (ie. if SMP, how large > > is > > +* the cache, CPU freq. etc. All those help to determine when to > > +* wbinvd() */ > > + WARN_ON_ONCE(!cache_size); > > + return !cache_size || num_pages < (cache_size >> 2); > > +} > > #endif > > > > void > > @@ -71,7 +85,7 @@ drm_clflush_pages(struct page *pages[], unsigned long > > num_pages) > > { > > > > #if defined(CONFIG_X86) > > - if (cpu_has_clflush) { > > + if (cpu_has_clflush && drm_cache_should_clflush(num_pages)) { > > drm_cache_flush_clflush(pages, num_pages); > > return; > > } > > @@ -104,7 +118,7 @@ void > > drm_clflush_sg(struct sg_table *st) > > { > > #if defined(CONFIG_X86) > > - if (cpu_has_clflush) { > > + if (cpu_has_clflush && drm_cache_should_clflush(st->nents)) { > > struct sg_page_iter sg_iter; > > > > mb(); > > @@ -128,7 +142,7 @@ void > > drm_clflush_virt_range(void *addr, unsigned long length) > > { > > #if defined(CONFIG_X86) > > - if (cpu_has_clflush) { > > + if (cpu_has_clflush && drm_cache_should_clflush(length / > > PAGE_SIZE)) { > > If length isn't a multiple of page size, isn't this ignoring the > remainder? Should it be rounding length up to the next multiple of > PAGE_SIZE, like ROUND_UP_TO? Yeah, we could round_up. In practice it probably won't matter. I actually think it would be better to pass a size to drm_cache_should_clflush(), and let that round it up. It sounds like people don't want this patch anyway, so I'll make the equivalent change in the i915 only patch. -- Ben Widawsky, Intel Open Source Technology Center
[Intel-gfx] [PATCH 4/4] drm/i915: Opportunistically reduce flushing at execbuf
On Mon, Dec 15, 2014 at 08:39:35PM +, Chris Wilson wrote: > On Mon, Dec 15, 2014 at 11:56:05AM -0800, Ben Widawsky wrote: > > On Mon, Dec 15, 2014 at 08:20:50AM +, Chris Wilson wrote: > > > On Mon, Dec 15, 2014 at 08:55:32AM +0100, Daniel Vetter wrote: > > > > On Sun, Dec 14, 2014 at 03:37:36PM -0800, Ben Widawsky wrote: > > > > > On Sun, Dec 14, 2014 at 03:12:21PM +0200, Ville Syrjälä wrote: > > > > > > On Sat, Dec 13, 2014 at 07:08:24PM -0800, Ben Widawsky wrote: > > > > > > > If we're moving a bunch of buffers from the CPU domain to the GPU > > > > > > > domain, and > > > > > > > we've already blown out the entire cache via a wbinvd, there is > > > > > > > nothing more to > > > > > > > do. > > > > > > > > > > > > > > With this and the previous patches, I am seeing a 3x FPS increase > > > > > > > on a certain > > > > > > > benchmark which uses a giant 2d array texture. Unless I missed > > > > > > > something in the > > > > > > > code, it should only effect non-LLC i915 platforms. > > > > > > > > > > > > > > I haven't yet run any numbers for other benchmarks, nor have I > > > > > > > attempted to > > > > > > > check if various conformance tests still pass. > > > > > > > > > > > > > > NOTE: As mentioned in the previous patch, if one can easily > > > > > > > obtain the largest > > > > > > > buffer and attempt to flush it first, the results would be even > > > > > > > more desirable. > > > > > > > > > > > > So even with that optimization if you only have tons of small > > > > > > buffers > > > > > > that need to be flushed you'd still take the clflush path for every > > > > > > single one. > > > > > > > > > > > > How difficult would it to calculate the total size to be flushed > > > > > > first, > > > > > > and then make the clflush vs. wbinvd decision base on that? > > > > > > > > > > > > > > > > I'll write the patch and send it to Eero for test. > > > > > > > > > > It's not hard, and I think that's a good idea as well. One reason I > > > > > didn't put > > > > > such code in this series is that moves away from a global DRM > > > > > solution (and like > > > > > I said in the cover-letter, I am fine with that). Implementing this, > > > > > I think in > > > > > the i915 code we'd just iterate through the BOs until we got to a > > > > > certain > > > > > threshold, then just call wbinvd() from i915 and not even both with > > > > > drm_cache. > > > > > You could also maybe try to shorcut if there are more than X buffers. > > > > > > > > I don't mind an i915 specific solution (we have them already in many > > > > places). So will wait for the results of this experiments before merging > > > > more patches. > > > > > > I actually think an i915 specific solution is required, as the making > > > drm_clflush_pages autoselect is likely to cause regressions on unaware > > > drivers (e.g. anything that has a reservation loop in execbuf like i915). > > > > Assuming the stall is gone as Jesse said in the other thread, I can't > > envision a > > scenario where wbinvd would do worse on large objects. > > It is the multiple wbinvd performed at each execbuffer that is worrisome. > -Chris > This patch attempts to avoid that by dropping all flushing after the first WBINVD. -- Ben Widawsky, Intel Open Source Technology Center
[PATCH] [v2] drm/cache: Use wbinvd helpers
From: Ben Widawsky <b...@bwidawsk.net> When the original drm code was written there were no centralized functions for doing a coordinated wbinvd across all CPUs. Now (since 2010) there are, so use them instead of rolling a new one. v2: On x86 UP systems the wbinvd_on_all_cpus() is defined as a static inline in smp.h. We must therefore include this file so we don't get compiler errors. This error was found by 0-DAY kernel test infrastructure. We only need this for x86. Cc: Intel GFX Signed-off-by: Ben Widawsky Reviewed-by: Chris Wilson (v1) --- drivers/gpu/drm/drm_cache.c | 13 - 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index a6b6906..9a62d7a 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -32,6 +32,7 @@ #include #if defined(CONFIG_X86) +#include /* * clflushopt is an unordered instruction which needs fencing with mfence or @@ -64,12 +65,6 @@ static void drm_cache_flush_clflush(struct page *pages[], drm_clflush_page(*pages++); mb(); } - -static void -drm_clflush_ipi_handler(void *null) -{ - wbinvd(); -} #endif void @@ -82,7 +77,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) return; } - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #elif defined(__powerpc__) @@ -121,7 +116,7 @@ drm_clflush_sg(struct sg_table *st) return; } - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); @@ -144,7 +139,7 @@ drm_clflush_virt_range(void *addr, unsigned long length) return; } - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); -- 2.1.3
[Intel-gfx] [PATCH 4/4] drm/i915: Opportunistically reduce flushing at execbuf
On Mon, Dec 15, 2014 at 08:20:50AM +, Chris Wilson wrote: > On Mon, Dec 15, 2014 at 08:55:32AM +0100, Daniel Vetter wrote: > > On Sun, Dec 14, 2014 at 03:37:36PM -0800, Ben Widawsky wrote: > > > On Sun, Dec 14, 2014 at 03:12:21PM +0200, Ville Syrjälä wrote: > > > > On Sat, Dec 13, 2014 at 07:08:24PM -0800, Ben Widawsky wrote: > > > > > If we're moving a bunch of buffers from the CPU domain to the GPU > > > > > domain, and > > > > > we've already blown out the entire cache via a wbinvd, there is > > > > > nothing more to > > > > > do. > > > > > > > > > > With this and the previous patches, I am seeing a 3x FPS increase on > > > > > a certain > > > > > benchmark which uses a giant 2d array texture. Unless I missed > > > > > something in the > > > > > code, it should only effect non-LLC i915 platforms. > > > > > > > > > > I haven't yet run any numbers for other benchmarks, nor have I > > > > > attempted to > > > > > check if various conformance tests still pass. > > > > > > > > > > NOTE: As mentioned in the previous patch, if one can easily obtain > > > > > the largest > > > > > buffer and attempt to flush it first, the results would be even more > > > > > desirable. > > > > > > > > So even with that optimization if you only have tons of small buffers > > > > that need to be flushed you'd still take the clflush path for every > > > > single one. > > > > > > > > How difficult would it to calculate the total size to be flushed first, > > > > and then make the clflush vs. wbinvd decision base on that? > > > > > > > > > > I'll write the patch and send it to Eero for test. > > > > > > It's not hard, and I think that's a good idea as well. One reason I > > > didn't put > > > such code in this series is that moves away from a global DRM solution > > > (and like > > > I said in the cover-letter, I am fine with that). Implementing this, I > > > think in > > > the i915 code we'd just iterate through the BOs until we got to a certain > > > threshold, then just call wbinvd() from i915 and not even both with > > > drm_cache. > > > You could also maybe try to shorcut if there are more than X buffers. > > > > I don't mind an i915 specific solution (we have them already in many > > places). So will wait for the results of this experiments before merging > > more patches. > > I actually think an i915 specific solution is required, as the making > drm_clflush_pages autoselect is likely to cause regressions on unaware > drivers (e.g. anything that has a reservation loop in execbuf like i915). Assuming the stall is gone as Jesse said in the other thread, I can't envision a scenario where wbinvd would do worse on large objects. > > I do think that execbuf regularly hitting clflush is something to be > concerned about in userspace (even a wbinvd every execbuf is not going > to be nice, even an mfence per execbuf shows up on profiles!), but we do > have to occassionally flush large objects like framebuffers which > probably would be faster using wbinvd. > -Chris > > -- > Chris Wilson, Intel Open Source Technology Centre
[Intel-gfx] [PATCH 2/4] drm/cache: Try to be smarter about clflushing on x86
On Sun, Dec 14, 2014 at 08:06:20PM -0800, Jesse Barnes wrote: > On 12/14/2014 4:59 AM, Chris Wilson wrote: > >One of the things wbinvd is considered evil for is that it blocks the > >CPU for an indeterminate amount of time - upsetting latency critcial > >aspects of the OS. For example, the x86/mm has similar code to use > >wbinvd for large clflushes that caused a bit of controversy with RT: > > > >http://linux-kernel.2935.n7.nabble.com/PATCH-x86-Use-clflush-instead-of-wbinvd-whenever-possible-when-changing-mapping-td493751.html > > > >and also the use of wbinvd in the nvidia driver has also been noted as > >evil by RT folks. > > > >However as the wbinvd still exists, it can't be all that bad... That patch looks eerily similar. I guess I am slightly better in that I take the cache size into account. > > Yeah there are definitely tradeoffs here. In this particular case, we're > trying to flush out a ~140M object on every frame, which just seems silly. > > There's definitely room for optimization in Mesa too; avoiding a mapping > that marks a large bo as dirty would be good, but if we improve the kernel > in this area, even sloppy apps and existing binaries will speed up. > > Maybe we could apply this only on !llc systems or something? I wonder how > much wbinvd performance varies across microarchitectures; maybe Thomas's > issue isn't really relevant anymore (at least one can hope). I am pretty sure from the mesa perspective we do not hit this path on non-llc systems because we end up with a linear buffer, and just CPU map the buffer. In addition to trying to manage the cache dirtiness ourselves, the current code which determines how it wants to manage subregions within large textures could probably use some eyes to make sure the order in which we decide the various fallbacks makes sense for all sizes, and all platforms. I /think/ we can do better, but when I was writing a patch, the code got messy fast. > > When digging into this, I found that an optimization to remove the IPI for > wbinvd was clobbered during a merge; maybe that should be resurrected too. > Surely a single, global wbinvd is sufficient; we don't need to do n_cpus^2 > wbinvd + the associated invalidation bus signals here... If this actually works, then there should be no CPU stall at all. > > Alternately, we could insert some delays into this path just to make it > extra clear to userspace that they really shouldn't be hitting this in the > common case (and provide some additional interfaces to let them avoid it by > allowing flushing and dirty management in userspace). I don't think such an extreme step is needed. If we really don't need the IPI, then I think this path can only be faster than CLFLUSH. > > Jesse
[Intel-gfx] [PATCH 4/4] drm/i915: Opportunistically reduce flushing at execbuf
On Sun, Dec 14, 2014 at 03:12:21PM +0200, Ville Syrjälä wrote: > On Sat, Dec 13, 2014 at 07:08:24PM -0800, Ben Widawsky wrote: > > If we're moving a bunch of buffers from the CPU domain to the GPU domain, > > and > > we've already blown out the entire cache via a wbinvd, there is nothing > > more to > > do. > > > > With this and the previous patches, I am seeing a 3x FPS increase on a > > certain > > benchmark which uses a giant 2d array texture. Unless I missed something in > > the > > code, it should only effect non-LLC i915 platforms. > > > > I haven't yet run any numbers for other benchmarks, nor have I attempted to > > check if various conformance tests still pass. > > > > NOTE: As mentioned in the previous patch, if one can easily obtain the > > largest > > buffer and attempt to flush it first, the results would be even more > > desirable. > > So even with that optimization if you only have tons of small buffers > that need to be flushed you'd still take the clflush path for every > single one. > > How difficult would it to calculate the total size to be flushed first, > and then make the clflush vs. wbinvd decision base on that? > I'll write the patch and send it to Eero for test. It's not hard, and I think that's a good idea as well. One reason I didn't put such code in this series is that moves away from a global DRM solution (and like I said in the cover-letter, I am fine with that). Implementing this, I think in the i915 code we'd just iterate through the BOs until we got to a certain threshold, then just call wbinvd() from i915 and not even both with drm_cache. You could also maybe try to shorcut if there are more than X buffers. However, for what you describe, I think it might make more sense to let userspace specify an execbuf flag to do the wbinvd(). Userspace can trivially determine such info, it prevents having to iterate through the buffers an extra time in the kernel. I wonder if the clflushing many small objects is showing up on profiles? So far, this specific microbenchmark was the only profile I'd seen where the clflushes show up. Thanks. [snip]
[PATCH 4/4] drm/i915: Opportunistically reduce flushing at execbuf
If we're moving a bunch of buffers from the CPU domain to the GPU domain, and we've already blown out the entire cache via a wbinvd, there is nothing more to do. With this and the previous patches, I am seeing a 3x FPS increase on a certain benchmark which uses a giant 2d array texture. Unless I missed something in the code, it should only effect non-LLC i915 platforms. I haven't yet run any numbers for other benchmarks, nor have I attempted to check if various conformance tests still pass. NOTE: As mentioned in the previous patch, if one can easily obtain the largest buffer and attempt to flush it first, the results would be even more desirable. Cc: DRI Development Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_drv.h| 3 ++- drivers/gpu/drm/i915/i915_gem.c| 12 +--- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 8 +--- drivers/gpu/drm/i915/intel_lrc.c | 8 +--- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d68c75f..fdb92a3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2642,7 +2642,8 @@ static inline bool i915_stop_ring_allow_warn(struct drm_i915_private *dev_priv) } void i915_gem_reset(struct drm_device *dev); -bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); +enum drm_cache_flush +i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); int __must_check i915_gem_init(struct drm_device *dev); int i915_gem_init_rings(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index de241eb..3746738 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3608,7 +3608,7 @@ err_unpin: return vma; } -bool +enum drm_cache_flush i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force) { @@ -3617,14 +3617,14 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, * again at bind time. */ if (obj->pages == NULL) - return false; + return DRM_CACHE_FLUSH_NONE; /* * Stolen memory is always coherent with the GPU as it is explicitly * marked as wc by the system, or the system is cache-coherent. */ if (obj->stolen || obj->phys_handle) - return false; + return DRM_CACHE_FLUSH_NONE; /* If the GPU is snooping the contents of the CPU cache, * we do not need to manually clear the CPU cache lines. However, @@ -3635,12 +3635,10 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj, * tracking. */ if (!force && cpu_cache_is_coherent(obj->base.dev, obj->cache_level)) - return false; + return DRM_CACHE_FLUSH_NONE; trace_i915_gem_object_clflush(obj); - drm_clflush_sg(obj->pages); - - return true; + return drm_clflush_sg(obj->pages); } /** Flushes the GTT write domain for the object if it's dirty. */ diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 0c25f62..e8eb9e9 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -827,7 +827,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_engine_cs *ring, { struct i915_vma *vma; uint32_t flush_domains = 0; - bool flush_chipset = false; + enum drm_cache_flush flush_chipset = DRM_CACHE_FLUSH_NONE; int ret; list_for_each_entry(vma, vmas, exec_list) { @@ -836,8 +836,10 @@ i915_gem_execbuffer_move_to_gpu(struct intel_engine_cs *ring, if (ret) return ret; - if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) - flush_chipset |= i915_gem_clflush_object(obj, false); + if (obj->base.write_domain & I915_GEM_DOMAIN_CPU && + flush_chipset != DRM_CACHE_FLUSH_WBINVD) { + flush_chipset = i915_gem_clflush_object(obj, false); + } flush_domains |= obj->base.write_domain; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 89b5577..a6c6ebd 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -611,7 +611,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf, struct intel_engine_cs *ring = ringbuf->ring; struct i915_vma *vma; uint32_t flush_domains = 0; - bool flush_chipset = false; + enum drm_cache_flush flush_chipset = DRM_CACHE_FLUSH_NONE; int ret; list_for_each_entry(vma, vmas, exec_list) { @@ -621,8 +621,10 @@
[PATCH 3/4] drm/cache: Return what type of cache flush occurred
The caller of the cache flush APIs can sometimes do useful things with the information of how the cache was flushed. For instance, when giving buffers to the GPU to read, we need to make sure all of them have properly invalidated the caches (when not using LLC). If we can determine a wbinvd() occurred though, we can skip trying to clflush all remaining objects. There is a further optimization to be made here in the driver specific code where it can try to flush the largest object first in hopes of it needing a wbinvd(). I haven't implemented that yet. The enum parts of this were very minimally considered for the sake of getting the data for the profile. Cc: Intel GFX Signed-off-by: Ben Widawsky --- drivers/gpu/drm/drm_cache.c | 34 +- include/drm/drmP.h | 13 ++--- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 6009c2d..433b15d 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -80,21 +80,25 @@ drm_cache_should_clflush(unsigned long num_pages) } #endif -void +int drm_clflush_pages(struct page *pages[], unsigned long num_pages) { #if defined(CONFIG_X86) if (cpu_has_clflush && drm_cache_should_clflush(num_pages)) { drm_cache_flush_clflush(pages, num_pages); - return; + return DRM_CACHE_FLUSH_CL; } - if (wbinvd_on_all_cpus()) + if (wbinvd_on_all_cpus()) { printk(KERN_ERR "Timed out waiting for cache flush.\n"); + return DRM_CACHE_FLUSH_ERROR; + } else + return DRM_CACHE_FLUSH_WBINVD; #elif defined(__powerpc__) unsigned long i; + int ret = DRM_CACHE_FLUSH_NONE; for (i = 0; i < num_pages; i++) { struct page *page = pages[i]; void *page_virtual; @@ -106,15 +110,19 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) flush_dcache_range((unsigned long)page_virtual, (unsigned long)page_virtual + PAGE_SIZE); kunmap_atomic(page_virtual); + ret = DRM_CACHE_FLUSH_DCACHE; } + WARN_ON(ret == DRM_CACHE_FLUSH_NONE); + return ret; #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); WARN_ON_ONCE(1); + return DRM_CACHE_FLUSH_NONE; #endif } EXPORT_SYMBOL(drm_clflush_pages); -void +int drm_clflush_sg(struct sg_table *st) { #if defined(CONFIG_X86) @@ -126,19 +134,23 @@ drm_clflush_sg(struct sg_table *st) drm_clflush_page(sg_page_iter_page(_iter)); mb(); - return; + return DRM_CACHE_FLUSH_CL; } - if (wbinvd_on_all_cpus()) + if (wbinvd_on_all_cpus()) { printk(KERN_ERR "Timed out waiting for cache flush.\n"); + return DRM_CACHE_FLUSH_ERROR; + } else + return DRM_CACHE_FLUSH_WBINVD; #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); WARN_ON_ONCE(1); + return DRM_CACHE_FLUSH_NONE; #endif } EXPORT_SYMBOL(drm_clflush_sg); -void +int drm_clflush_virt_range(void *addr, unsigned long length) { #if defined(CONFIG_X86) @@ -149,14 +161,18 @@ drm_clflush_virt_range(void *addr, unsigned long length) clflushopt(addr); clflushopt(end - 1); mb(); - return; + return DRM_CACHE_FLUSH_CL; } - if (wbinvd_on_all_cpus()) + if (wbinvd_on_all_cpus()) { printk(KERN_ERR "Timed out waiting for cache flush.\n"); + return DRM_CACHE_FLUSH_ERROR; + } else + return DRM_CACHE_FLUSH_WBINVD; #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); WARN_ON_ONCE(1); + return DRM_CACHE_FLUSH_NONE; #endif } EXPORT_SYMBOL(drm_clflush_virt_range); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 8ba35c6..09ebe46 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -884,9 +884,16 @@ int drm_noop(struct drm_device *dev, void *data, struct drm_file *file_priv); /* Cache management (drm_cache.c) */ -void drm_clflush_pages(struct page *pages[], unsigned long num_pages); -void drm_clflush_sg(struct sg_table *st); -void drm_clflush_virt_range(void *addr, unsigned long length); +enum drm_cache_flush { + DRM_CACHE_FLUSH_NONE=0, + DRM_CACHE_FLUSH_ERROR, + DRM_CACHE_FLUSH_CL, + DRM_CACHE_FLUSH_WBINVD, + DRM_CACHE_FLUSH_DCACHE, +}; +int drm_clflush_pages(struct page *pages[], unsigned long num_pages); +int drm_clflush_sg(struct sg_table *st); +int drm_clflush_virt_range(void *addr, unsigned long length); /* * These are exported to drivers so that they can implement fencing using -- 2.1.3
[PATCH 2/4] drm/cache: Try to be smarter about clflushing on x86
Any GEM driver which has very large objects and a slow CPU is subject to very long waits simply for clflushing incoherent objects. Generally, each individual object is not a problem, but if you have very large objects, or very many objects, the flushing begins to show up in profiles. Because on x86 we know the cache size, we can easily determine when an object will use all the cache, and forego iterating over each cacheline. We need to be careful when using wbinvd. wbinvd() is itself potentially slow because it requires synchronizing the flush across all CPUs so they have a coherent view of memory. This can result in either stalling work being done on other CPUs, or this call itself stalling while waiting for a CPU to accept the interrupt. Also, wbinvd() also has the downside of invalidating all cachelines, so we don't want to use it unless we're sure we already own most of the cachelines. The current algorithm is very naive. I think it can be tweaked more, and it would be good if someone else gave it some thought. I am pretty confident in i915, we can even skip the IPI in the execbuf path with minimal code change (or perhaps just some verifying of the existing code). It would be nice to hear what other developers who depend on this code think. Cc: Intel GFX Signed-off-by: Ben Widawsky --- drivers/gpu/drm/drm_cache.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index d7797e8..6009c2d 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -64,6 +64,20 @@ static void drm_cache_flush_clflush(struct page *pages[], drm_clflush_page(*pages++); mb(); } + +static bool +drm_cache_should_clflush(unsigned long num_pages) +{ + const int cache_size = boot_cpu_data.x86_cache_size; + + /* For now the algorithm simply checks if the number of pages to be +* flushed is greater than the entire system cache. One could make the +* function more aware of the actual system (ie. if SMP, how large is +* the cache, CPU freq. etc. All those help to determine when to +* wbinvd() */ + WARN_ON_ONCE(!cache_size); + return !cache_size || num_pages < (cache_size >> 2); +} #endif void @@ -71,7 +85,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) { #if defined(CONFIG_X86) - if (cpu_has_clflush) { + if (cpu_has_clflush && drm_cache_should_clflush(num_pages)) { drm_cache_flush_clflush(pages, num_pages); return; } @@ -104,7 +118,7 @@ void drm_clflush_sg(struct sg_table *st) { #if defined(CONFIG_X86) - if (cpu_has_clflush) { + if (cpu_has_clflush && drm_cache_should_clflush(st->nents)) { struct sg_page_iter sg_iter; mb(); @@ -128,7 +142,7 @@ void drm_clflush_virt_range(void *addr, unsigned long length) { #if defined(CONFIG_X86) - if (cpu_has_clflush) { + if (cpu_has_clflush && drm_cache_should_clflush(length / PAGE_SIZE)) { void *end = addr + length; mb(); for (; addr < end; addr += boot_cpu_data.x86_clflush_size) -- 2.1.3
[PATCH 1/4] drm/cache: Use wbinvd helpers
When the original drm code was written there were no centralized functions for doing a coordinated wbinvd across all CPUs. Now (since 2010) there are, so use them instead of rolling a new one. Cc: Intel GFX Signed-off-by: Ben Widawsky --- drivers/gpu/drm/drm_cache.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index a6b6906..d7797e8 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -64,12 +64,6 @@ static void drm_cache_flush_clflush(struct page *pages[], drm_clflush_page(*pages++); mb(); } - -static void -drm_clflush_ipi_handler(void *null) -{ - wbinvd(); -} #endif void @@ -82,7 +76,7 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) return; } - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #elif defined(__powerpc__) @@ -121,7 +115,7 @@ drm_clflush_sg(struct sg_table *st) return; } - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); @@ -144,7 +138,7 @@ drm_clflush_virt_range(void *addr, unsigned long length) return; } - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) + if (wbinvd_on_all_cpus()) printk(KERN_ERR "Timed out waiting for cache flush.\n"); #else printk(KERN_ERR "Architecture has no drm_cache.c support\n"); -- 2.1.3
[PATCH 0/4] [RFC] Sometimes opt for wbinvd over clflush
While looking at a recent benchmark on a non-LLC platform, Kristian noticed that the amount of time simply spent cflushing buffers was not only measurable, but dominating the profile. It's possible I'm oversimplifying the problem, but it seems like for cases where we have a slow CPU, and when you know the set of BOs is using all or most of the cache, wbinvd is the optimal solution. The gains are about 3.5x FPS on the micro-benchmark with these patches. These patches attempt to make a generic solution which could potentially be used by other drivers. It can just as easily be implemented solely in i915, and if that's what people find more desirable and safe, I am happy to do that as well. I wouldn't say these patches are ready for inclusion as I haven't spent much time testing, or polishing them. I would like feedback on what people think of the general idea. Thoughts on figuring out when to switch over to wbinvd, and in particular [as mentioned in patch 3] if I even need to do the synchronized wbinvd. (For the time being, I have convinced myself we can avoid it on i915, but I am quite often wrong about such things; more details in the relevant patch.) PPC specific code is only compile tested. Thanks. Ben Widawsky (4): drm/cache: Use wbinvd helpers drm/cache: Try to be smarter about clflushing on x86 drm/cache: Return what type of cache flush occurred drm/i915: Opportunistically reduce flushing at execbuf drivers/gpu/drm/drm_cache.c| 54 +- drivers/gpu/drm/i915/i915_drv.h| 3 +- drivers/gpu/drm/i915/i915_gem.c| 12 +++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 8 +++-- drivers/gpu/drm/i915/intel_lrc.c | 8 +++-- include/drm/drmP.h | 13 +-- 6 files changed, 66 insertions(+), 32 deletions(-) -- 2.1.3
[Intel-gfx] [PATCH] drm/mm: Don't WARN if drm_mm_reserve_node
On Wed, Apr 09, 2014 at 07:25:37AM +0100, Chris Wilson wrote: > On Tue, Apr 08, 2014 at 10:21:44AM -0700, Ben Widawsky wrote: > > I am not convinced this is the correct solution. At least the way we > > used this interface, it isn't meant to ever fail. I also didn't look > > into exactly why we depend an ENOSPC return. That sounds fragile to me, > > especially for a public interface. > > Eh? This interface is explicitly used to check that the requested range > is available. > -Chris > What I mean is, the node is already initialized, and we always expect it to be available - at least with all the callers prior to the fastboot. I didn't look very closely at how we get the fb objects from the existing stolen memory, but my drive-by review would suggest it's much better to deal with the redundancy at that level (or make this an i915 private function). Removing the WARN is fine with me though, it's: Tested-by: Ben Widawsky My complaint was more with how we solved the problem initially, and not with this patch itself. -- Ben Widawsky, Intel Open Source Technology Center
[PATCH] drm/mm: Don't WARN if drm_mm_reserve_node
On Mon, Apr 07, 2014 at 10:13:13PM -0700, Jesse Barnes wrote: > On Mon, 7 Apr 2014 23:25:20 +0200 > Daniel Vetter wrote: > > > Jesse's BIOS fb reconstruction code actually relies on the -ENOSPC > > return value to detect overlapping framebuffers (which the bios uses > > always when lighting up more than one screen). All this fanciness > > happens in intel_alloc_plane_obj in intel_display.c. > > > > Since no one else uses this we can savely remove the WARN without > > repercursions. > > > > Reported-by: Ben Widawsky > > Cc: Ben Widawsky > > Cc: Jesse Barnes > > Cc: Dave Airlie > > Signed-off-by: Daniel Vetter > > --- > > drivers/gpu/drm/drm_mm.c | 2 -- > > 1 file changed, 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c > > index a2d45b748f86..e4dfd5c3b15e 100644 > > --- a/drivers/gpu/drm/drm_mm.c > > +++ b/drivers/gpu/drm/drm_mm.c > > @@ -192,8 +192,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct > > drm_mm_node *node) > > return 0; > > } > > > > - WARN(1, "no hole found for node 0x%lx + 0x%lx\n", > > -node->start, node->size); > > return -ENOSPC; > > } > > EXPORT_SYMBOL(drm_mm_reserve_node); > > Yeah thanks, pushing this has been on my list for weeks now... I am not convinced this is the correct solution. At least the way we used this interface, it isn't meant to ever fail. I also didn't look into exactly why we depend an ENOSPC return. That sounds fragile to me, especially for a public interface. Obviously it makes the WARN go away, and we have only one other user of the interface, so it's correct. So if both of you are happy, I won't stand in the way. -- Ben Widawsky, Intel Open Source Technology Center
[PATCH 20/34] drm/doc: Repleace LOCKING kerneldoc sections in drm_modes.c
On Thu, Mar 20, 2014 at 11:31:26AM +1000, Dave Airlie wrote: > On Tue, Mar 11, 2014 at 8:30 PM, Daniel Vetter > wrote: > > There's not really any value in stating that no locking is needed. And > > even if the comment is useful, a check for the right mutex at the > > beginning of the function is better since that can't be ingored as > > easily as a bit of documentation. > > > > Note that drm_mode_probed_add in drm_crtc.c is also changed, the next > > patch will move this into drm_modes.c > > > > v2: Don't add locking WARN_ONs where it is not strictly required (i.e. > > the two functions to validate/prune mode lists). > > This made radeon blow up hard, I kinda expect other drivers also, > > > >Mar 20 01:14:21 crydee kernel: [ cut here ] > Mar 20 01:14:21 crydee kernel: WARNING: CPU: 3 PID: 882 at > /home/airlied/kernel/linux-2.6/drivers/gpu/drm/drm_crtc.c:94 > drm_warn_on_modeset_not_all_locked+0x48/0x76 [drm]() > Mar 20 01:14:21 crydee kernel: Modules linked in: firewire_ohci > firewire_core crc_itu_t ehci_pci ohci_pci ehci_hcd ohci_hcd radeon(+) > hwmon i2c_algo_bit drm_kms_helper ttm drm i2c_core > Mar 20 01:14:21 crydee kernel: CPU: 3 PID: 882 Comm: systemd-udevd Not > tainted 3.14.0-rc7+ #67 > Mar 20 01:14:21 crydee kernel: Hardware name: Gigabyte Technology Co., > Ltd. GA-A75M-UD2H/GA-A75M-UD2H, BIOS F4 09/16/2011 > Mar 20 01:14:21 crydee kernel: 88022311f9c8 > 814b5b21 > Mar 20 01:14:21 crydee kernel: 88022311fa00 81039e11 > a001882f 880036b92000 > Mar 20 01:14:21 crydee kernel: 880224c85000 880224c85690 > 88022311fa10 > Mar 20 01:14:21 crydee kernel: Call Trace: > Mar 20 01:14:21 crydee kernel: [] dump_stack+0x4d/0x66 > Mar 20 01:14:21 crydee kernel: [] > warn_slowpath_common+0x7a/0x93 > Mar 20 01:14:21 crydee kernel: [] ? > drm_warn_on_modeset_not_all_locked+0x48/0x76 [drm] > Mar 20 01:14:21 crydee kernel: [] > warn_slowpath_null+0x15/0x17 > Mar 20 01:14:21 crydee kernel: [] > drm_warn_on_modeset_not_all_locked+0x48/0x76 [drm] > Mar 20 01:14:21 crydee kernel: [] > drm_helper_disable_unused_functions+0x11/0x103 [drm_kms_helper] > Mar 20 01:14:21 crydee kernel: [] > radeon_fbdev_init+0xb2/0xcf [radeon] > Mar 20 01:14:21 crydee kernel: [] > radeon_modeset_init+0x763/0x951 [radeon] > Mar 20 01:14:21 crydee kernel: [] > radeon_driver_load_kms+0xc5/0x171 [radeon] > Mar 20 01:14:21 crydee kernel: [] > drm_dev_register+0x7f/0xf8 [drm] > Mar 20 01:14:21 crydee kernel: [] > drm_get_pci_dev+0xfe/0x1c8 [drm] > Mar 20 01:14:21 crydee kernel: [] ? > trace_hardirqs_on+0xd/0xf > Mar 20 01:14:21 crydee kernel: [] > radeon_pci_probe+0xa8/0xaf [radeon] > Mar 20 01:14:21 crydee kernel: [] local_pci_probe+0x38/0x7d > Mar 20 01:14:21 crydee kernel: [] > pci_device_probe+0xc6/0xec > Mar 20 01:14:21 crydee kernel: [] > driver_probe_device+0x98/0x1b3 > Mar 20 01:14:21 crydee kernel: [] __driver_attach+0x5c/0x7e > Mar 20 01:14:21 crydee kernel: [] ? > __device_attach+0x38/0x38 > Mar 20 01:14:21 crydee kernel: [] > bus_for_each_dev+0x79/0x83 > Mar 20 01:14:21 crydee kernel: [] driver_attach+0x19/0x1b > Mar 20 01:14:21 crydee kernel: [] > bus_add_driver+0x109/0x1d3 > Mar 20 01:14:21 crydee kernel: [] driver_register+0x89/0xc5 > Mar 20 01:14:21 crydee kernel: [] > __pci_register_driver+0x5b/0x5e > Mar 20 01:14:21 crydee kernel: [] ? 0xa01c0fff > Mar 20 01:14:21 crydee kernel: [] > drm_pci_init+0x69/0xec [drm] > Mar 20 01:14:21 crydee kernel: [] ? 0xa01c0fff > Mar 20 01:14:21 crydee kernel: [] > radeon_init+0x97/0xb5 [radeon] > > Dave. i915 gets 3 distinct WARNs from this patch. -- Ben Widawsky, Intel Open Source Technology Center