mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 00:38:48 +02:00
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:
parent
1f1928db00
commit
8446f257b3
10 changed files with 77 additions and 0 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -614,5 +614,6 @@ GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
|
|||
__DRIdrawable * driDrawPriv,
|
||||
__DRIdrawable * driReadPriv);
|
||||
extern void radeonDestroyContext(__DRIcontext * driContextPriv);
|
||||
void radeon_prepare_render(radeonContextPtr radeon);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue