Message ID | 1501484693-13183-2-git-send-email-vidya.srinivas@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
The userspace mesa patches to produce Y_TILED_CCS surfaces have been reviewed for a couple of weeks now. So long as kmscube counts as userspace, I think this should be good to land. Acked-by: Jason Ekstrand <jason@jlekstrand.net> On Mon, Jul 31, 2017 at 12:04 AM, Vidya Srinivas <vidya.srinivas@intel.com> wrote: > From: Ville Syrjälä <ville.syrjala@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 <daniel@ffwll.ch> > Cc: Ben Widawsky <ben@bwidawsk.net> > Cc: Jason Ekstrand <jason@jlekstrand.net> > Reviewed-by: Ben Widawsky <ben@bwidawsk.net> (v3) > Signed-off-by: Ville Syrjä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/intel_display.c | 43 ++++++++++++++++++++++++++++++ > ++++++ > include/uapi/drm/drm_fourcc.h | 20 +++++++++++++++++ > 2 files changed, 63 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index 5a89db1..5c1a52d 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -2428,6 +2428,48 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t > fb_modifier) > } > } > > +/* > + * 1 byte of CCS actually corresponds to 16x8 pixels on the main > + * surface, and the memory layout for the CCS tile us 64x64 bytes. > + * But since we're pretending the CCS tile is 128 bytes wide we > + * adjust hsub/vsub here accordingly to 8x16 so that the > + * bytes<->x/y conversions come out correct. > + */ > +static const struct drm_format_info ccs_formats[] = { > + { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, > .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, > + { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, > .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, > + { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, > .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, > + { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, > .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, > +}; > + > +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 &formats[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) > @@ -13673,6 +13715,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 7586c46..238658f 100644 > --- a/include/uapi/drm/drm_fourcc.h > +++ b/include/uapi/drm/drm_fourcc.h > @@ -253,6 +253,26 @@ > #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 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. > + */ > +#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 > * > * Macroblocks are laid in a Z-shape, and each pixel data is following the > -- > 1.9.1 > >
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5a89db1..5c1a52d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2428,6 +2428,48 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier) } } +/* + * 1 byte of CCS actually corresponds to 16x8 pixels on the main + * surface, and the memory layout for the CCS tile us 64x64 bytes. + * But since we're pretending the CCS tile is 128 bytes wide we + * adjust hsub/vsub here accordingly to 8x16 so that the + * bytes<->x/y conversions come out correct. + */ +static const struct drm_format_info ccs_formats[] = { + { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, + { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, + { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, + { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, +}; + +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 &formats[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) @@ -13673,6 +13715,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 7586c46..238658f 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -253,6 +253,26 @@ #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 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. + */ +#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 * * Macroblocks are laid in a Z-shape, and each pixel data is following the