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 <jglisse@redhat.com>
Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
This commit is contained in:
Mario Kleiner 2010-07-25 16:29:24 +02:00 committed by Jerome Glisse
parent 1f1928db00
commit 8446f257b3
10 changed files with 77 additions and 0 deletions

View file

@ -612,6 +612,8 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
radeon_prepare_render(&rmesa->radeon);
if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
/* need to disable perspective-correct texturing for point sprites */
if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) {

View file

@ -264,6 +264,8 @@ void r200TclPrimitive( GLcontext *ctx,
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE;
radeon_prepare_render(&rmesa->radeon);
if (newprim != rmesa->tcl.hw_primitive ||
!discrete_prim[hw_prim&0xf]) {
/* need to disable perspective-correct texturing for point sprites */

View file

@ -327,6 +327,8 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
BATCH_LOCALS(&rmesa->radeon);
int type, num_verts;
radeon_prepare_render(&rmesa->radeon);
type = r300PrimitiveType(rmesa, prim);
num_verts = r300NumVerts(rmesa, end - start, prim);

View file

@ -48,6 +48,7 @@ static GLboolean r700ClearFast(context_t *context, GLbitfield mask)
void r700Clear(GLcontext * ctx, GLbitfield mask)
{
context_t *context = R700_CONTEXT(ctx);
radeonContextPtr radeon = &context->radeon;
__DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask[0]);
GLbitfield swrast_mask = 0, tri_mask = 0;
@ -60,6 +61,8 @@ void r700Clear(GLcontext * ctx, GLbitfield mask)
context->radeon.front_buffer_dirty = GL_TRUE;
}
radeon_prepare_render(radeon);
if( GL_TRUE == r700ClearFast(context, mask) )
{
return;

View file

@ -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.
*/

View file

@ -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)) {

View file

@ -614,5 +614,6 @@ GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv);
extern void radeonDestroyContext(__DRIcontext * driContextPriv);
void radeon_prepare_render(radeonContextPtr radeon);
#endif

View file

@ -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;

View file

@ -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++)

View file

@ -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 );