On Wed, 2007-10-24 at 16:10 -0700, Jesse Barnes wrote: > On Tuesday, October 23, 2007 10:32 am Jesse Barnes wrote: > > On Tuesday, October 23, 2007 10:03 am Jesse Barnes wrote: > > > On Tuesday, October 23, 2007 7:32 am Michel Dänzer wrote: > > > > > Thinking about this more, I think we can make the counter not > > > > > decrease, but I don't think we can avoid bad behavior. > > > > > > > > Why not, with something like the scheme Ian outlined above? > > > > > > You snipped out the reasons: we'll get bad behavior of one sort or > > > another no matter what, unless we have genlocked displays. > > > > Ok, you guys banged this into my head on IRC. So the calculation > > will be: > > msc += last_pipe_vblank_count - cur_pipeX_vblank_count > > like Ian said (where last_pipeX_vblank_count is updated everytime the > > drawable moves onto pipe X). This gets a little ugly since I'll need > > to track both a per-drawable MSC count as well as per-pipe > > last_pipeX_vblank_count values. And unfortunately, since the > > drawable movement is tracked in per-driver SAREA fields, this code > > can't be generic. Ugg. > > Well at least some of the code can be generic, fortunately. Here's what > I have. The extension support seems to have changed a bit since my > last patch (this one is against Mesa HEAD as of yesterday), and I'm no > longer sure about the compatibility issues with the patch. > > It still has some bugs. When moving windows between screens, Mesa seems > to lose track of the right vblank count to sync against sometimes, so > my test app's calls to glXWaitVideoSyncSGI return immediately. Moving > the window back and forth between the screens a few times fixes this > problem though, maybe there's a race in the update of base_msc and > which pipe to sync against?
There can't really be a race with a single context... If this is still an issue with your updated patch, it might be related to some of the issues below. > On the plus side, I never see the MSC count decrease, so at least that > part is working I think. Nice! > diff --git a/configs/default b/configs/default The configs/ changes probably shouldn't be in here. > diff --git a/include/GL/internal/dri_interface.h > b/include/GL/internal/dri_interface.h > index e7fbf8e..f1d236a 100644 > --- a/include/GL/internal/dri_interface.h > +++ b/include/GL/internal/dri_interface.h > @@ -189,6 +189,18 @@ struct __DRImediaStreamCounterExtensionRec { > int (*waitForMSC)(__DRIdrawable *drawable, > int64_t target_msc, int64_t divisor, int64_t remainder, > int64_t * msc, int64_t * sbc); > + > + /** > + * Like the screen version of getMSC, but also takes a drawable so that > + * the appropriate pipe's counter can be retrieved. > + * > + * Get the number of vertical refreshes since some point in time before > + * this function was first called (i.e., system start up). > + * > + * \since Internal API version 20070925. __DRImediaStreamCounterExtensionRec has its own versioning now, you need to bump __DRI_MEDIA_STREAM_COUNTER_VERSION to 2. > diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c > index 707e398..cbc498a 100644 > --- a/src/glx/x11/glxcmds.c > +++ b/src/glx/x11/glxcmds.c [...] > + if ( psc->driScreen.private ) { Should be if ( psc->msc && psc->driScreen.private ) { > + /* > + * Try to use getDrawableMSC first so we get the right > + * counter... > + */ > + if (psc->msc->getDrawableMSC) > + ret = (*psc->msc->getDrawableMSC)( &psc->driScreen, > + pdraw->private, > + & temp); > + else > + ret = (*psc->msc->getMSC)( &psc->driScreen, & temp); I think you need to verify that (psc->msc->base.version >= 2) before accessing psc->msc->getDrawableMSC. > diff --git a/src/mesa/drivers/dri/common/dri_util.c > b/src/mesa/drivers/dri/common/dri_util.c > index d59ea0d..d023231 100644 > --- a/src/mesa/drivers/dri/common/dri_util.c > +++ b/src/mesa/drivers/dri/common/dri_util.c > @@ -471,6 +480,8 @@ static void *driCreateNewDrawable(__DRIscreen *screen, > pdp->numBackClipRects = 0; > pdp->pClipRects = NULL; > pdp->pBackClipRects = NULL; > + pdp->vblSeq = 0; > + pdp->vblFlags = 0; > > psp = (__DRIscreenPrivate *)screen->private; > pdp->driScreenPriv = psp; > @@ -485,6 +496,11 @@ static void *driCreateNewDrawable(__DRIscreen *screen, > pdraw->private = pdp; > pdraw->destroyDrawable = driDestroyDrawable; > pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ > + if (driCompareGLXAPIVersion(20070925) >= 0) { > + pdp->msc = 0; > + pdp->base_msc = 0; > + } > + I'm not sure this API version needs to be checked here or even bumped. Either way though, all added fields should probably be treated the same way. > diff --git a/src/mesa/drivers/dri/common/dri_util.h > b/src/mesa/drivers/dri/common/dri_util.h > index 91992a9..1e5301f 100644 > --- a/src/mesa/drivers/dri/common/dri_util.h > +++ b/src/mesa/drivers/dri/common/dri_util.h [...] > + /** > + * \name Monotonic MSC tracking > + * > + * Low level driver is responsible for updating base_msc, primary and > + * secondary_vblank_base values so that higher level code can calculate > + * a new msc value or msc target for a WaitMSC call. The new value will > + * be: > + * if (pipe == primary) > + * msc = base_msc + get_vblank_count(primary) - primary_vblank_base; > + * else > + * msc = base_msc + get_vblank_count(secondary) - > secondary_vblank_base; > + * > + * And for waiting on a value, core code will use: > + * actual_target = target_msc - base_msc + > + * (primary|secondary)_vblank_base; > + */ > + /[EMAIL PROTECTED]/ > + int64_t msc; > + int64_t base_msc; > + int64_t primary_vblank_base; > + int64_t secondary_vblank_base; Shouldn't these be unsigned? Do we really need two vblank_base values? Couldn't there be just one for the current pipe? Also, I'm not sure the msc field is needed here, couldn't the driver just increase base_msc by <current sequence of old pipe> - vblank_base? Actually I think something like that is needed anyway, as the msc field could be stale at that point? (BTW, the i915 driver changes for this seem to be missing.) > diff --git a/src/mesa/drivers/dri/common/vblank.c > b/src/mesa/drivers/dri/common/vblank.c > index 3b5acfe..032cd40 100644 > --- a/src/mesa/drivers/dri/common/vblank.c > +++ b/src/mesa/drivers/dri/common/vblank.c [...] > - *count = (int64_t)vbl.reply.sequence; > + > + if ( dPriv && !(dPriv->vblFlags & VBLANK_FLAG_SECONDARY) ) { > + /* Primary pipe */ > + dPriv->msc = dPriv->base_msc + vbl.reply.sequence - > + dPriv->primary_vblank_base; > + } else if (dPriv && (dPriv->vblFlags & VBLANK_FLAG_SECONDARY) ) { > + /* Secondary pipe */ > + dPriv->msc = dPriv->base_msc + vbl.reply.sequence - > + dPriv->secondary_vblank_base; > + } else { > + /* Old driver (no knowledge of per-drawable MSC callback) */ > + dPriv->msc += vbl.reply.sequence; > + } The last else block doesn't seem to make sense - for one, it could only seem to be hit if dPriv == NULL, in which case it would segfault. -- Earthling Michel Dänzer | http://tungstengraphics.com Libre software enthusiast | Debian, X and DRI developer ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel