Immediately after obtaining, with DRI2GetBuffersWithFormat, the DRM buffer
handle for a DRI2 buffer, we wrap that DRM buffer handle with a region and
a miptre. This patch additionally allocates an accompanying multisample
miptree if the DRI2 buffer is multisampled.

Since we do not yet advertise multisample GL configs, the code for
allocating the multisample miptree is currently inactive.

CC: Eric Anholt <e...@anholt.net>
CC: Paul Berry <stereotype...@gmail.com>
Signed-off-by: Chad Versace <chad.vers...@linux.intel.com>
---
 src/mesa/drivers/dri/intel/intel_context.c     | 26 +++++++++----
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 52 ++++++++++++++++++++++++++
 src/mesa/drivers/dri/intel/intel_mipmap_tree.h |  6 +++
 3 files changed, 76 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_context.c 
b/src/mesa/drivers/dri/intel/intel_context.c
index 378859c..9a85d83 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -893,14 +893,24 @@ intel_process_dri2_buffer(struct intel_context *intel,
    if (!rb)
       return;
 
+   unsigned num_samples = rb->Base.Base.NumSamples;
+
    /* We try to avoid closing and reopening the same BO name, because the first
     * use of a mapping of the buffer involves a bunch of page faulting which is
     * moderately expensive.
     */
-   if (rb->mt &&
-       rb->mt->region &&
-       rb->mt->region->name == buffer->name)
-      return;
+   if (num_samples == 0) {
+       if (rb->mt &&
+           rb->mt->region &&
+           rb->mt->region->name == buffer->name)
+          return;
+   } else {
+       if (rb->mt &&
+           rb->mt->singlesample_mt &&
+           rb->mt->singlesample_mt->region &&
+           rb->mt->singlesample_mt->region->name == buffer->name)
+          return;
+   }
 
    if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
       fprintf(stderr,
@@ -920,9 +930,9 @@ intel_process_dri2_buffer(struct intel_context *intel,
    if (!region)
       return;
 
-   rb->mt = intel_miptree_create_for_region(intel,
-                                            GL_TEXTURE_2D,
-                                            intel_rb_format(rb),
-                                            region);
+   rb->mt = intel_miptree_create_for_dri2_buffer(intel,
+                                                 intel_rb_format(rb),
+                                                 num_samples,
+                                                 region);
    intel_region_release(&region);
 }
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c 
b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index b402099..c4496ea 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -324,6 +324,58 @@ compute_msaa_layout(struct intel_context *intel, gl_format 
format)
    }
 }
 
+/**
+ * If the DRI2 buffer is multisampled, then its content is undefined
+ * after calling this. This behavior violates the GLX spec for the
+ * benefit of avoiding a performance penalty.
+ */
+struct intel_mipmap_tree*
+intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
+                                     gl_format format,
+                                     uint32_t num_samples,
+                                     struct intel_region *region)
+{
+   struct intel_mipmap_tree *singlesample_mt = NULL;
+   struct intel_mipmap_tree *multisample_mt = NULL;
+   GLenum base_format = _mesa_get_format_base_format(format);
+
+   /* Only the front and back buffers, which are color buffers, are shared
+    * through DRI2.
+    */
+   assert(base_format == GL_RGB || base_format == GL_RGBA);
+
+   singlesample_mt = intel_miptree_create_for_region(intel, GL_TEXTURE_2D,
+                                                     format, region);
+   if (!singlesample_mt)
+      return NULL;
+
+   if (num_samples == 0) {
+      return singlesample_mt;
+   } else {
+      multisample_mt = intel_miptree_create_for_renderbuffer(intel,
+                                                             format,
+                                                             region->width,
+                                                             region->height,
+                                                             num_samples);
+      if (!multisample_mt) {
+         intel_miptree_release(&singlesample_mt);
+         return NULL;
+      }
+
+      multisample_mt->singlesample_mt = singlesample_mt;
+      multisample_mt->need_downsample = false;
+
+      /* If we wanted to preserve the contents of the DRI2 buffer, here we
+       * would need to do an upsample from singlesample_mt to multisample_mt.
+       * However, it is unlikely that any app desires that behavior. So we
+       * invalidate its content for the benefit of avoiding the upsample
+       * performance penalty.
+       */
+
+      return multisample_mt;
+   }
+}
+
 struct intel_mipmap_tree*
 intel_miptree_create_for_renderbuffer(struct intel_context *intel,
                                       gl_format format,
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h 
b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index e5e89f0..bb3fa50 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -348,6 +348,12 @@ intel_miptree_create_for_region(struct intel_context 
*intel,
                                gl_format format,
                                struct intel_region *region);
 
+struct intel_mipmap_tree*
+intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
+                                     gl_format format,
+                                     uint32_t num_samples,
+                                     struct intel_region *region);
+
 /**
  * Create a miptree appropriate as the storage for a non-texture renderbuffer.
  * The miptree has the following properties:
-- 
1.7.11.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to