From 38bfef811578ae3edf4306fe2a6fc9925e3da605 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Sun, 25 Jul 2010 17:02:59 +0200 Subject: [PATCH 2/2] mesa/dri/radeon: Obey dri2InvalidateDrawable() requests. Add a new function radeon_prepare_render() to radeon driver. The function checks the timestamps of drawable's to detect if dri2InvalidateDrawable() was called by the DRI2 flush extension to invalidate buffers. It radeon_update_buffer()'s a drawable's buffers if so. On DRI2 this will throttle the client if bufferswaps on a target drawable are still pending and thereby prevent the client from resuming rendering into a not yet swapped backbuffer. This is part of a possible fix for: https://bugs.freedesktop.org/show_bug.cgi?id=28341 https://bugs.freedesktop.org/show_bug.cgi?id=28410 The patch only adds a radeon_prepare_render() check to the R600/R700 rendering path, not to other functions that might touch the backbuffer. If this works, radeon_prepare_render() checks will need to get added to other places in the driver. Proof of concept, tested on R600. Signed-off-by: Mario Kleiner --- src/mesa/drivers/dri/r600/r700_render.c | 4 ++ .../drivers/dri/radeon/radeon_common_context.c | 37 ++++++++++++++++++++ .../drivers/dri/radeon/radeon_common_context.h | 1 + 3 files changed, 42 insertions(+), 0 deletions(-) diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 1929b7c..316a094 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -977,6 +977,10 @@ static void r700DrawPrims(GLcontext *ctx, { GLboolean retval = GL_FALSE; + context_t *context = R700_CONTEXT(ctx); + radeonContextPtr radeon = &context->radeon; + radeon_prepare_render(radeon); + /* This check should get folded into just the places that * min/max index are really needed. */ diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 5a7d52c..030be05 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -493,6 +493,38 @@ radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) return _mesa_get_format_bytes(rb->base.Format) * 8; } +/* + * Check if drawable has been invalidated by dri2InvalidateDrawable(). + * Update renderbuffers if so. This prevents a client from accessing + * a backbuffer that has a swap pending but not yet completed. + * + * See intel_prepare_render for equivalent code in intel driver. + * + */ +void radeon_prepare_render(radeonContextPtr radeon) +{ + __DRIcontext *driContext = radeon->dri.context; + __DRIdrawable *drawable; + + drawable = driContext->driDrawablePriv; + if (drawable->dri2.stamp != driContext->dri2.draw_stamp) { + if (drawable->lastStamp != drawable->dri2.stamp) + radeon_update_renderbuffers(driContext, drawable, GL_FALSE); + + /* Intel driver does the equivalent of this, no clue if it is needed: + * radeon_draw_buffer(radeon->glCtx, &(drawable->driverPrivate)->base); + */ + driContext->dri2.draw_stamp = drawable->dri2.stamp; + } + + drawable = driContext->driReadablePriv; + if (drawable->dri2.stamp != driContext->dri2.read_stamp) { + if (drawable->lastStamp != drawable->dri2.stamp) + radeon_update_renderbuffers(driContext, drawable, GL_FALSE); + driContext->dri2.read_stamp = drawable->dri2.stamp; + } +} + void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, GLboolean front_only) @@ -514,6 +546,11 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, screen = context->driScreenPriv; radeon = (radeonContextPtr) context->driverPrivate; + /* Set this up front, so that in case our buffers get invalidated + * while we're getting new buffers, we don't clobber the stamp and + * thus ignore the invalidate. */ + drawable->lastStamp = drawable->dri2.stamp; + if (screen->dri2.loader && (screen->dri2.loader->base.version > 2) && (screen->dri2.loader->getBuffersWithFormat != NULL)) { diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 5156c5d..ec773cf 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -614,5 +614,6 @@ GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, __DRIdrawable * driDrawPriv, __DRIdrawable * driReadPriv); extern void radeonDestroyContext(__DRIcontext * driContextPriv); +void radeon_prepare_render(radeonContextPtr radeon); #endif -- 1.7.0.4