summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/radeon
diff options
context:
space:
mode:
authorMario Kleiner <[email protected]>2010-07-25 16:29:24 +0200
committerJerome Glisse <[email protected]>2010-08-02 10:43:51 -0400
commit8446f257b3e3ca4a3eb2c79bc357e46343e04e87 (patch)
tree06ae4fc6d022896602969e4f813609011c40078c /src/mesa/drivers/dri/radeon
parent1f1928db001527c3dcf1d78d6a5d2ef8f519327b (diff)
radeon: Add DRI2 flush extension to so we synchronize properly.
When DRI2 swap buffer is pending (copy buffer not pageflipping) we need to make sure we have the flush extension so radeon doesn't resume rendering on the not yet blitted front buffer. Modified version of Jerome's patch to add flush extension in the correct place. This prepares a possible fix for: https://bugs.freedesktop.org/show_bug.cgi?id=28341 https://bugs.freedesktop.org/show_bug.cgi?id=28410 Signed-off-by: Jerome Glisse <[email protected]> Signed-off-by: Mario Kleiner <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c42
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c17
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_swtcl.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.c2
5 files changed, 64 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 5a7d52c4d2f..3665944c3e2 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -493,6 +493,43 @@ 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;
+ __DRIscreen *screen;
+
+ screen = driContext->driScreenPriv;
+ if (!screen->dri2.loader)
+ return;
+
+ 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 +551,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 5156c5d0d0a..ec773cfa522 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
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 82107cc6aeb..d3d7b216baa 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -376,6 +376,21 @@ static const __DRItexBufferExtension r600TexBufferExtension = {
};
#endif
+static void
+radeonDRI2Flush(__DRIdrawable *drawable)
+{
+ radeonContextPtr rmesa;
+
+ rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate;
+ radeonFlush(rmesa->glCtx);
+}
+
+static const struct __DRI2flushExtensionRec radeonFlushExtension = {
+ { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+ radeonDRI2Flush,
+ dri2InvalidateDrawable,
+};
+
static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
{
screen->device_id = device_id;
@@ -1379,6 +1394,8 @@ radeonCreateScreen2(__DRIscreen *sPriv)
screen->extensions[i++] = &r600TexBufferExtension.base;
#endif
+ screen->extensions[i++] = &radeonFlushExtension.base;
+
screen->extensions[i++] = NULL;
sPriv->extensions = screen->extensions;
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index f2fcb46688a..67be466c3f8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -408,6 +408,8 @@ static GLboolean radeon_run_render( GLcontext *ctx,
!radeon_dma_validate_render( ctx, VB ))
return GL_TRUE;
+ radeon_prepare_render(&rmesa->radeon);
+
tnl->Driver.Render.Start( ctx );
for (i = 0 ; i < VB->PrimitiveCount ; i++)
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c
index ea796e1a45f..5e1718f9dfc 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c
@@ -252,6 +252,8 @@ void radeonTclPrimitive( GLcontext *ctx,
GLuint se_cntl;
GLuint newprim = hw_prim | RADEON_CP_VC_CNTL_TCL_ENABLE;
+ radeon_prepare_render(&rmesa->radeon);
+
if (newprim != rmesa->tcl.hw_primitive ||
!discrete_prim[hw_prim&0xf]) {
RADEON_NEWPRIM( rmesa );