<div dir="ltr"><div>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.<br><br></div>Acked-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 31, 2017 at 12:04 AM, Vidya Srinivas <span dir="ltr"><<a href="mailto:vidya.srinivas@intel.com" target="_blank">vidya.srinivas@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Ville Syrjälä <<a href="mailto:ville.syrjala@linux.intel.com" target="_blank">ville.syrjala@linux.intel.com</a><wbr>><br>
<br>
SKL+ display engine can scan out certain kinds of compressed surfaces<br>
produced by the render engine. This involved telling the display engine<br>
the location of the color control surfae (CCS) which describes which<br>
parts of the main surface are compressed and which are not. The location<br>
of CCS is provided by userspace as just another plane with its own offset.<br>
<br>
By providing our own format information for the CCS formats, we should<br>
be able to make framebuffer_check() do the right thing for the CCS<br>
surface as well.<br>
<br>
Note that we'll return the same format info for both Y and Yf tiled<br>
format as that's what happens with the non-CCS Y vs. Yf as well. If<br>
desired, we could potentially return a unique pointer for each<br>
pixel_format+tiling+ccs combination, in which case we immediately be<br>
able to tell if any of that stuff changed by just comparing the<br>
pointers. But that does sound a bit wasteful space wise.<br>
<br>
v2: Drop the 'dev' argument from the hook<br>
        v3: Include the description of the CCS surface layout<br>
v4: Pretend CCS tiles are regular 128 byte wide Y tiles (Jason)<br>
<br>
Cc: Daniel Vetter <<a href="mailto:daniel@ffwll.ch" target="_blank">daniel@ffwll.ch</a>><br>
Cc: Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>><br>
Cc: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>><br>
Reviewed-by: Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>> (v3)<br>
Signed-off-by: Ville Syrjä <<a href="mailto:ville.syrjala@linux.intel.com" target="_blank">ville.syrjala@linux.intel.com</a><wbr>><br>
---<br>
 drivers/gpu/drm/i915/intel_di<wbr>splay.c | 43 ++++++++++++++++++++++++++++++<wbr>++++++<br>
 include/uapi/drm/drm_fourcc.<wbr>h        | 20 +++++++++++++++++<br>
 2 files changed, 63 insertions(+)<br>
<br>
diff --git a/drivers/gpu/drm/i915/intel_d<wbr>isplay.c b/drivers/gpu/drm/i915/intel_d<wbr>isplay.c<br>
index 5a89db1..5c1a52d 100644<br>
--- a/drivers/gpu/drm/i915/intel_d<wbr>isplay.c<br>
+++ b/drivers/gpu/drm/i915/intel_d<wbr>isplay.c<br>
@@ -2428,6 +2428,48 @@ static unsigned int intel_fb_modifier_to_tiling(ui<wbr>nt64_t fb_modifier)<br>
        }<br>
 }<br>
<br>
+/*<br>
+ * 1 byte of CCS actually corresponds to 16x8 pixels on the main<br>
+ * surface, and the memory layout for the CCS tile us 64x64 bytes.<br>
+ * But since we're pretending the CCS tile is 128 bytes wide we<br>
+ * adjust hsub/vsub here accordingly to 8x16 so that the<br>
+ * bytes<->x/y conversions come out correct.<br>
+ */<br>
+static const struct drm_format_info ccs_formats[] = {<br>
+       { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },<br>
+       { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },<br>
+       { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },<br>
+       { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },<br>
+};<br>
+<br>
+static const struct drm_format_info *<br>
+lookup_format_info(const struct drm_format_info formats[],<br>
+                  int num_formats, u32 format)<br>
+{<br>
+       int i;<br>
+<br>
+       for (i = 0; i < num_formats; i++) {<br>
+               if (formats[i].format == format)<br>
+                       return &formats[i];<br>
+       }<br>
+<br>
+       return NULL;<br>
+}<br>
+<br>
+static const struct drm_format_info *<br>
+intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd)<br>
+{<br>
+       switch (cmd->modifier[0]) {<br>
+       case I915_FORMAT_MOD_Y_TILED_CCS:<br>
+       case I915_FORMAT_MOD_Yf_TILED_CCS:<br>
+               return lookup_format_info(ccs_formats<wbr>,<br>
+                                         ARRAY_SIZE(ccs_formats),<br>
+                                         cmd->pixel_format);<br>
+       default:<br>
+               return NULL;<br>
+       }<br>
+}<br>
+<br>
 static int<br>
 intel_fill_fb_info(struct drm_i915_private *dev_priv,<br>
                   struct drm_framebuffer *fb)<br>
@@ -13673,6 +13715,7 @@ static void intel_atomic_state_free(struct drm_atomic_state *state)<br>
<br>
 static const struct drm_mode_config_funcs intel_mode_funcs = {<br>
        .fb_create = intel_user_framebuffer_create,<br>
+       .get_format_info = intel_get_format_info,<br>
        .output_poll_changed = intel_fbdev_output_poll_change<wbr>d,<br>
        .atomic_check = intel_atomic_check,<br>
        .atomic_commit = intel_atomic_commit,<br>
diff --git a/include/uapi/drm/drm_fourcc.<wbr>h b/include/uapi/drm/drm_fourcc.<wbr>h<br>
index 7586c46..238658f 100644<br>
--- a/include/uapi/drm/drm_fourcc.<wbr>h<br>
+++ b/include/uapi/drm/drm_fourcc.<wbr>h<br>
@@ -253,6 +253,26 @@<br>
 #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)<br>
<br>
 /*<br>
+ * Intel color control surface (CCS) for render compression<br>
+ *<br>
+ * The framebuffer format must be one of the 8:8:8:8 RGB formats.<br>
+ * The main surface will be plane index 0 and must be Y/Yf-tiled,<br>
+ * the CCS will be plane index 1.<br>
+ *<br>
+ * Each CCS tile matches a 1024x512 pixel area of the main surface.<br>
+ * To match certain aspects of the 3D hardware the CCS is<br>
+ * considered to be made up of normal 128Bx32 Y tiles, Thus<br>
+ * the CCS pitch must be specified in multiples of 128 bytes.<br>
+ *<br>
+ * In reality the CCS tile appears to be a 64Bx64 Y tile, composed<br>
+ * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks.<br>
+ * But that fact is not relevant unless the memory is accessed<br>
+ * directly.<br>
+ */<br>
+#define I915_FORMAT_MOD_Y_TILED_CCS    fourcc_mod_code(INTEL, 4)<br>
+#define I915_FORMAT_MOD_Yf_TILED_CCS   fourcc_mod_code(INTEL, 5)<br>
+<br>
+/*<br>
  * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks<br>
  *<br>
  * Macroblocks are laid in a Z-shape, and each pixel data is following the<br>
<span class="m_-2091063116742059762HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
</font></span></blockquote></div><br></div></div></div></div></div>