[Mesa-dev] [PATCH 08/15] intel: Allocate miptree for multisample DRI2 buffers

Chad Versace chad.versace at linux.intel.com
Sat Jul 21 17:36:47 PDT 2012


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 <eric at anholt.net>
CC: Paul Berry <stereotype441 at gmail.com>
Signed-off-by: Chad Versace <chad.versace at 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



More information about the mesa-dev mailing list