<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 20, 2017 at 3:25 PM, Ben Widawsky <span dir="ltr"><<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 17-03-20 12:00:44, Jason Ekstrand wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Fri, Mar 17, 2017 at 5:34 PM, Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This patch begins introducing how we'll actually handle the potentially<br>
many modifiers coming in from the API, how we'll store them, and the<br>
structure in the code to support it.<br>
<br>
Prior to this patch, the Y-tiled modifier would be entirely ignored. It<br>
shouldn't actually be used until this point because we've not bumped the<br>
DRIimage extension version (which is a requirement to use modifiers).<br>
<br>
With X-tiling:<br>
Writes:          6,583.58 MiB<br>
Reads:           6,540.93 MiB<br>
<br>
With Y-tiling:<br>
Writes:          5,361.78 MiB<br>
Reads            6,052.45 MiB<br>
<br>
Savings per frame<br>
Writes:  2 MiB<br>
Reads:  .8 MiB<br>
<br>
Similar functionality was introduced and then reverted here:<br>
<br>
commit 6a0d036483caf87d43ebe2edd19058<wbr>73446c9589<br>
Author: Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>><br>
Date:   Thu Apr 21 20:14:58 2016 -0700<br>
<br>
    i965: Always use Y-tiled buffers on SKL+<br>
<br>
v2: Use last set bit instead of first set bit in modifiers to address<br>
bug found by Daniel Stone.<br>
<br>
Signed-off-by: Ben Widawsky <<a href="mailto:benjamin.widawsky@intel.com" target="_blank">benjamin.widawsky@intel.com</a>><br>
Reviewed-by: Eric Engestrom <<a href="mailto:eric.engestrom@imgtec.com" target="_blank">eric.engestrom@imgtec.com</a>><br>
Acked-by: Daniel Stone <<a href="mailto:daniels@collabora.com" target="_blank">daniels@collabora.com</a>><br>
---<br>
 src/mesa/drivers/dri/i965/int<wbr>el_screen.c | 55<br>
++++++++++++++++++++++++++++--<wbr>--<br>
 1 file changed, 49 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
b/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
index 22ab3a30b6..1954757d1e 100644<br>
--- a/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
+++ b/src/mesa/drivers/dri/i965/in<wbr>tel_screen.c<br>
@@ -23,6 +23,7 @@<br>
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.<br>
  */<br>
<br>
+#include <drm_fourcc.h><br>
 #include <errno.h><br>
 #include <time.h><br>
 #include <unistd.h><br>
@@ -520,16 +521,35 @@ select_best_modifier(struct gen_device_info *devinfo,<br>
                      const uint64_t *modifiers,<br>
                      const unsigned count)<br>
 {<br>
-   uint64_t modifier = DRM_FORMAT_MOD_INVALID;<br>
+#define YTILE  (1 << 1)<br>
+#define LINEAR (1 << 0)<br>
+<br>
+   const uint64_t prio_modifiers[] = { I915_FORMAT_MOD_Y_TILED,<br>
DRM_FORMAT_MOD_LINEAR };<br>
+   uint32_t modifier_bitmask = 0; /* API only allows 32 */<br>
<br>
</blockquote>
<br>
The bitfield thing is still confusing to me.  Here's an idea on how we<br>
could maybe make it better.<br>
<br>
enum modifier_priority {<br>
  MODIFIER_PRIORITY_LINEAR,<br>
  MODIFIER_PRIORITY_X,<br>
  MODIFIER_PRIORITY_Y,<br>
  MODIFIER_PRIORITY_Y_CCS,<br>
};<br>
<br>
uint32_t priority_to_modifier[] = {<br>
  [MODIFIER_PRIORITY_LINEAR] = DRM_FORMAT_MOD_LINEAR,<br>
  [MODIFIER_PRIORITY_X] = I915_FORMAT_MOD_X_TILED,<br>
  [MODIFIER_PRIORITY_Y] = I915_FORMAT_MOD_Y_TILED,<br>
  [MODIFIER_PRIORITY_Y_CCS] = I915_FORMAT_MOD_Y_TILED_CCS,<br>
}<br>
<br>
enum modier_priority prio = 0;<br>
for (int i = 0; i < count; i++) {<br>
  switch (modifiers[i]) {<br>
  case DRM_FORMAT_MOD_LINEAR:<br>
     prio = MAX2(prio, MODIFIER_PRIORITY_LINEAR);<br>
     break;<br>
<br>
  case DRM_FORMAT_MOD_X_TILED:<br>
     prio = MAX2(prio, MODIFIER_PRIORITY_X);<br>
     break;<br>
<br>
  case DRM_FORMAT_MOD_Y_TILED:<br>
     prio = MAX2(prio, MODIFIER_PRIORITY_Y);<br>
     break;<br>
<br>
  case DRM_FORMAT_MOD_Y_TILIED_CCS:<br>
     prio = MAX2(prio, MODIFIER_PRIORITY_Y_CCS);<br>
     break;<br>
}<br>
<br>
return priority_to_modifier[prio];<br>
<br>
How does this strike your fancy?  I'm ok with the bit set approach if you<br>
really prefer it but I find it hard to reason about.<br>
<br>
</blockquote>
<br></div></div>
I don't really prefer. This looks pretty good. Seems no less complex to me, but<br>
I wrote the first one, so perhaps I'm partial.<br>
<br>
Originally, I had some code in the equivalent function (before select_best was<br>
separate) which would try fallbacks, ie. if Y tiled allocation failed, it'd go<br>
down to the next modifier just walking down the bits, but logic is now gone, so<br>
there isn't really a point in the bitmask.<br>
<br>
Will respin with this and the fixes meant below.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
    for (int i = 0; i < count; i++) {<br>
       switch (modifiers[i]) {<br>
       case DRM_FORMAT_MOD_LINEAR:<br>
-         return modifiers[i];<br>
+         modifier_bitmask |= LINEAR;<br>
+         break;<br>
+      case I915_FORMAT_MOD_Y_TILED:<br>
+         if (devinfo->gen < 9) {<br>
+            _mesa_warning(NULL, "Invalid Y-tiling parameter\n");<br>
+            continue;<br>
<br>
</blockquote>
<br>
This isn't invalid.  It's just invalid for scanout.  If you wanted to<br>
create an image to share between two GL implementations, Y-tiling works<br>
fine on everything.<br>
<br>
<br>
</blockquote>
<br></span>
As a general function to support modifiers, you are correct, however since this<br>
is only called for image creation, I believe the existing warning is correct.<br></blockquote><div><br></div><div>But what if I want to create an image to share between two userspace processes with no scanout involved?  While the GBM portion of the API is mostly intended for scanout, the EGL extension will be something that can and will be used for GL <-> GL.  I guess we can always flip it on when we add support for the EGL extension but I see no reason why it shouldn't work through GBM.<br><br></div><div>Part of the problem may be that I really don't understand why GBM exists.  It's like a linux-specific half-of-EGL thing. :-/<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+         }<br>
+<br>
+         modifier_bitmask |= YTILE;<br>
+         break;<br>
       }<br>
    }<br>
<br>
-   return modifier;<br>
+   if (modifier_bitmask)<br>
+      return prio_modifiers[util_last_bit64<wbr>(modifier_bitmask)-1];<br>
+<br>
+   return DRM_FORMAT_MOD_INVALID;<br>
+<br>
+#undef LINEAR<br>
+#undef YTILE<br>
 }<br>
<br>
 static __DRIimage *<br>
@@ -560,6 +580,9 @@ intel_create_image_common(__DR<wbr>Iscreen *dri_screen,<br>
    case DRM_FORMAT_MOD_LINEAR:<br>
       tiling = I915_TILING_NONE;<br>
       break;<br>
+   case I915_FORMAT_MOD_Y_TILED:<br>
+      tiling = I915_TILING_Y;<br>
+      break;<br>
    case DRM_FORMAT_MOD_INVALID:<br>
    default:<br>
          break;<br>
@@ -611,8 +634,26 @@ intel_create_image_with_modifi<wbr>ers(__DRIscreen<br>
*dri_screen,<br>
                                   const unsigned count,<br>
                                   void *loaderPrivate)<br>
 {<br>
-   return intel_create_image_common(dri_<wbr>screen, width, height, format,<br>
0, NULL,<br>
-                                    0, loaderPrivate);<br>
+   uint64_t local_mods[count];<br>
+   int local_count = 0;<br>
+<br>
+   /* This compacts the actual modifiers to the ones we know how to<br>
handle */<br>
+   for (int i = 0; i < count; i++) {<br>
+      switch (modifiers[i]) {<br>
+      case I915_FORMAT_MOD_Y_TILED:<br>
+      case DRM_FORMAT_MOD_LINEAR:<br>
+         local_mods[local_count++] = modifiers[i];<br>
+         break;<br>
+      case DRM_FORMAT_MOD_INVALID:<br>
+         unreachable("Invalid modifiers specified\n");<br>
<br>
</blockquote>
<br>
I'm not sure this is truely unreachable.  What prevents someone from<br>
calling create_image_with_modifiers with INVALID?  Do we have a check<br>
somewhere higher up that that prevents it?  If this is something that's<br>
actually triggerable from client code, then I think we probably want to<br>
just let it fall through.<br>
<br>
<br>
</blockquote>
<br></div></div>
Nothing. It was meant to be handled in the entry points, but I missed it<br>
apparently.</blockquote><div><br></div><div>If you want to add code to the entrypoints to handle it, and keep the unreachable, that's fine with me.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<div class="HOEnZb"><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      default:<br>
+         /* Modifiers from other vendors would land here. */<br>
+         break;<br>
+      }<br>
+   }<br>
+<br>
+   return intel_create_image_common(dri_<wbr>screen, width, height, format, 0,<br>
+                                    local_mods, local_count,<br>
loaderPrivate);<br>
 }<br>
<br>
 static GLboolean<br>
@@ -1867,7 +1908,9 @@ intelAllocateBuffer(__DRIscree<wbr>n *dri_screen,<br>
    if (intelBuffer == NULL)<br>
       return NULL;<br>
<br>
-   /* The front and back buffers are color buffers, which are X tiled. */<br>
+   /* The front and back buffers are color buffers, which are X tiled.<br>
GEN9+<br>
+    * supports Y tiled and compressed buffers, but there is no way to<br>
plumb that<br>
+    * through to here. */<br>
    uint32_t tiling = I915_TILING_X;<br>
    unsigned long pitch;<br>
    int cpp = format / 8;<br>
--<br>
2.12.0<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
<br>
</blockquote></blockquote>
</div></div></blockquote></div><br></div></div>