[Mesa-dev] [PATCH 08/15] intel: Allocate miptree for multisample DRI2 buffers
Chad Versace
chad.versace at linux.intel.com
Thu Jul 26 13:59:36 PDT 2012
On 07/23/2012 03:16 PM, Paul Berry wrote:
> On 21 July 2012 17:36, Chad Versace <chad.versace at linux.intel.com
> <mailto:chad.versace at linux.intel.com>> wrote:
>
> 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"
Fixed.
>
>
> 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 <mailto:eric at anholt.net>>
> CC: Paul Berry <stereotype441 at gmail.com <mailto:stereotype441 at gmail.com>>
> Signed-off-by: Chad Versace <chad.versace at linux.intel.com
> <mailto: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(®ion);
> }
> 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.
> + */
>
>
> 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).
>
> 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.
It's called only on first draw and resize.
After our discussion at lunch, I plan to upsample in
intel_miptree_create_for_dri2_buffer if intel->is_front_buffer_rendering.
I'll resubmit the patch series with that change.
More information about the mesa-dev
mailing list