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(®ion);<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>