On 21 July 2012 17:36, Chad Versace <span dir="ltr"><<a href="mailto:chad.versace@linux.intel.com" target="_blank">chad.versace@linux.intel.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Immediately after obtaining, with DRI2GetBuffersWithFormat, the DRM buffer<br>
handle for a DRI2 buffer, we wrap that DRM buffer handle with a region and<br>
a miptre. This patch additionally allocates an accompanying multisample<br></blockquote><div><br>"miptree" <br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">


miptree if the DRI2 buffer is multisampled.<br>
<br>
Since we do not yet advertise multisample GL configs, the code for<br>
allocating the multisample miptree is currently inactive.<br>
<br>
CC: Eric Anholt <<a href="mailto:eric@anholt.net" target="_blank">eric@anholt.net</a>><br>
CC: Paul Berry <<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>><br>
Signed-off-by: Chad Versace <<a href="mailto:chad.versace@linux.intel.com" target="_blank">chad.versace@linux.intel.com</a>><br>
---<br>
 src/mesa/drivers/dri/intel/intel_context.c     | 26 +++++++++----<br>
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 52 ++++++++++++++++++++++++++<br>
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h |  6 +++<br>
 3 files changed, 76 insertions(+), 8 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c<br>
index 378859c..9a85d83 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_context.c<br>
+++ b/src/mesa/drivers/dri/intel/intel_context.c<br>
@@ -893,14 +893,24 @@ intel_process_dri2_buffer(struct intel_context *intel,<br>
    if (!rb)<br>
       return;<br>
<br>
+   unsigned num_samples = rb->Base.Base.NumSamples;<br>
+<br>
    /* We try to avoid closing and reopening the same BO name, because the first<br>
     * use of a mapping of the buffer involves a bunch of page faulting which is<br>
     * moderately expensive.<br>
     */<br>
-   if (rb->mt &&<br>
-       rb->mt->region &&<br>
-       rb->mt->region->name == buffer->name)<br>
-      return;<br>
+   if (num_samples == 0) {<br>
+       if (rb->mt &&<br>
+           rb->mt->region &&<br>
+           rb->mt->region->name == buffer->name)<br>
+          return;<br>
+   } else {<br>
+       if (rb->mt &&<br>
+           rb->mt->singlesample_mt &&<br>
+           rb->mt->singlesample_mt->region &&<br>
+           rb->mt->singlesample_mt->region->name == buffer->name)<br>
+          return;<br>
+   }<br>
<br>
    if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {<br>
       fprintf(stderr,<br>
@@ -920,9 +930,9 @@ intel_process_dri2_buffer(struct intel_context *intel,<br>
    if (!region)<br>
       return;<br>
<br>
-   rb->mt = intel_miptree_create_for_region(intel,<br>
-                                            GL_TEXTURE_2D,<br>
-                                            intel_rb_format(rb),<br>
-                                            region);<br>
+   rb->mt = intel_miptree_create_for_dri2_buffer(intel,<br>
+                                                 intel_rb_format(rb),<br>
+                                                 num_samples,<br>
+                                                 region);<br>
    intel_region_release(&region);<br>
 }<br>
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c<br>
index b402099..c4496ea 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c<br>
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c<br>
@@ -324,6 +324,58 @@ compute_msaa_layout(struct intel_context *intel, gl_format format)<br>
    }<br>
 }<br>
<br>
+/**<br>
+ * If the DRI2 buffer is multisampled, then its content is undefined<br>
+ * after calling this. This behavior violates the GLX spec for the<br>
+ * benefit of avoiding a performance penalty.<br>
+ */<br>
+struct intel_mipmap_tree*<br>
+intel_miptree_create_for_dri2_buffer(struct intel_context *intel,<br>
+                                     gl_format format,<br>
+                                     uint32_t num_samples,<br>
+                                     struct intel_region *region)<br>
+{<br>
+   struct intel_mipmap_tree *singlesample_mt = NULL;<br>
+   struct intel_mipmap_tree *multisample_mt = NULL;<br>
+   GLenum base_format = _mesa_get_format_base_format(format);<br>
+<br>
+   /* Only the front and back buffers, which are color buffers, are shared<br>
+    * through DRI2.<br>
+    */<br>
+   assert(base_format == GL_RGB || base_format == GL_RGBA);<br>
+<br>
+   singlesample_mt = intel_miptree_create_for_region(intel, GL_TEXTURE_2D,<br>
+                                                     format, region);<br>
+   if (!singlesample_mt)<br>
+      return NULL;<br>
+<br>
+   if (num_samples == 0) {<br>
+      return singlesample_mt;<br>
+   } else {<br>
+      multisample_mt = intel_miptree_create_for_renderbuffer(intel,<br>
+                                                             format,<br>
+                                                             region->width,<br>
+                                                             region->height,<br>
+                                                             num_samples);<br>
+      if (!multisample_mt) {<br>
+         intel_miptree_release(&singlesample_mt);<br>
+         return NULL;<br>
+      }<br>
+<br>
+      multisample_mt->singlesample_mt = singlesample_mt;<br>
+      multisample_mt->need_downsample = false;<br>
+<br>
+      /* If we wanted to preserve the contents of the DRI2 buffer, here we<br>
+       * would need to do an upsample from singlesample_mt to multisample_mt.<br>
+       * However, it is unlikely that any app desires that behavior. So we<br>
+       * invalidate its content for the benefit of avoiding the upsample<br>
+       * performance penalty.<br>
+       */<br></blockquote><div><br>Is this function called after every buffer swap, or just on the first draw and after a window resize?  If it's called after every buffer swap, I agree with you that the performance penalty of upsampling isn't justified.  But then I'm worried about the performance penalty of intel_miptree_create_for_renderbuffer (and especially intel_miptree_alloc_mcs, which it calls--that function spends CPU time clearing the MCS buffer, which seems wasteful to do on every frame).<br>
<br>If this function is only called for the first draw and after a resize, then it might be better to go ahead and upsample, just so that the behaviour is more consistent between multisampled and single-sampled visuals.<br>
 </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+      return multisample_mt;<br>
+   }<br>
+}<br>
+<br>
 struct intel_mipmap_tree*<br>
 intel_miptree_create_for_renderbuffer(struct intel_context *intel,<br>
                                       gl_format format,<br>
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h<br>
index e5e89f0..bb3fa50 100644<br>
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h<br>
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h<br>
@@ -348,6 +348,12 @@ intel_miptree_create_for_region(struct intel_context *intel,<br>
                                gl_format format,<br>
                                struct intel_region *region);<br>
<br>
+struct intel_mipmap_tree*<br>
+intel_miptree_create_for_dri2_buffer(struct intel_context *intel,<br>
+                                     gl_format format,<br>
+                                     uint32_t num_samples,<br>
+                                     struct intel_region *region);<br>
+<br>
 /**<br>
  * Create a miptree appropriate as the storage for a non-texture renderbuffer.<br>
  * The miptree has the following properties:<br>
<span><font color="#888888">--<br>
1.7.11.2<br>
<br>
</font></span></blockquote></div><br>