* SwapBuffers with client-side throttling
*/
-static uint32_t radeonGetLastFrame(radeonContextPtr radeon)
-{
- drm_radeon_getparam_t gp;
- int ret;
- uint32_t frame = 0;
-
- gp.param = RADEON_PARAM_LAST_FRAME;
- gp.value = (int *)&frame;
- ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM,
- &gp, sizeof(gp));
- if (ret) {
- fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__,
- ret);
- exit(1);
- }
-
- return frame;
-}
-
uint32_t radeonGetAge(radeonContextPtr radeon)
{
drm_radeon_getparam_t gp;
return age;
}
-static void radeonEmitIrqLocked(radeonContextPtr radeon)
-{
- drm_radeon_irq_emit_t ie;
- int ret;
-
- ie.irq_seq = &radeon->iw.irq_seq;
- ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_IRQ_EMIT,
- &ie, sizeof(ie));
- if (ret) {
- fprintf(stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__,
- ret);
- exit(1);
- }
-}
-
-static void radeonWaitIrq(radeonContextPtr radeon)
-{
- int ret;
-
- do {
- ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT,
- &radeon->iw, sizeof(radeon->iw));
- } while (ret && (errno == EINTR || errno == EBUSY));
-
- if (ret) {
- fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__,
- ret);
- exit(1);
- }
-}
-
-static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
-{
- drm_radeon_sarea_t *sarea = radeon->sarea;
-
- if (radeon->do_irqs) {
- if (radeonGetLastFrame(radeon) < sarea->last_frame) {
- if (!radeon->irqsEmitted) {
- while (radeonGetLastFrame(radeon) <
- sarea->last_frame) ;
- } else {
- UNLOCK_HARDWARE(radeon);
- radeonWaitIrq(radeon);
- LOCK_HARDWARE(radeon);
- }
- radeon->irqsEmitted = 10;
- }
-
- if (radeon->irqsEmitted) {
- radeonEmitIrqLocked(radeon);
- radeon->irqsEmitted--;
- }
- } else {
- while (radeonGetLastFrame(radeon) < sarea->last_frame) {
- UNLOCK_HARDWARE(radeon);
- if (radeon->do_usleeps)
- DO_USLEEP(1);
- LOCK_HARDWARE(radeon);
- }
- }
-}
/* wait for idle */
void radeonWaitForIdleLocked(radeonContextPtr radeon)
}
}
-/* Copy the back color buffer to the front color buffer.
- */
-void radeonCopyBuffer( __DRIdrawable *dPriv,
- const drm_clip_rect_t *rect)
-{
- radeonContextPtr rmesa;
- GLint nbox, i, ret;
-
- assert(dPriv);
- assert(dPriv->driContextPriv);
- assert(dPriv->driContextPriv->driverPrivate);
-
- rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
-
- LOCK_HARDWARE(rmesa);
-
- if ( RADEON_DEBUG & RADEON_IOCTL ) {
- fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
- }
-
- nbox = dPriv->numClipRects; /* must be in locked region */
-
- for ( i = 0 ; i < nbox ; ) {
- GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
- drm_clip_rect_t *box = dPriv->pClipRects;
- drm_clip_rect_t *b = rmesa->sarea->boxes;
- GLint n = 0;
-
- for ( ; i < nr ; i++ ) {
-
- *b = box[i];
-
- if (rect)
- {
- if (rect->x1 > b->x1)
- b->x1 = rect->x1;
- if (rect->y1 > b->y1)
- b->y1 = rect->y1;
- if (rect->x2 < b->x2)
- b->x2 = rect->x2;
- if (rect->y2 < b->y2)
- b->y2 = rect->y2;
-
- if (b->x1 >= b->x2 || b->y1 >= b->y2)
- continue;
- }
-
- b++;
- n++;
- }
- rmesa->sarea->nbox = n;
-
- if (!n)
- continue;
-
- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
-
- if ( ret ) {
- fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret );
- UNLOCK_HARDWARE( rmesa );
- exit( 1 );
- }
- }
-
- UNLOCK_HARDWARE( rmesa );
-}
-
-static int radeonScheduleSwap(__DRIdrawable *dPriv, GLboolean *missed_target)
-{
- radeonContextPtr rmesa;
-
- rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
- radeon_firevertices(rmesa);
-
- LOCK_HARDWARE( rmesa );
-
- if (!dPriv->numClipRects) {
- UNLOCK_HARDWARE(rmesa);
- usleep(10000); /* throttle invisible client 10ms */
- return 0;
- }
-
- radeonWaitForFrameCompletion(rmesa);
-
- UNLOCK_HARDWARE(rmesa);
- driWaitForVBlank(dPriv, missed_target);
-
- return 0;
-}
-
-static GLboolean radeonPageFlip( __DRIdrawable *dPriv )
-{
- radeonContextPtr radeon;
- GLint ret;
- struct radeon_framebuffer *rfb;
-
- assert(dPriv);
- assert(dPriv->driContextPriv);
- assert(dPriv->driContextPriv->driverPrivate);
-
- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
- rfb = dPriv->driverPrivate;
-
- LOCK_HARDWARE(radeon);
-
- if ( RADEON_DEBUG & RADEON_IOCTL ) {
- fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__,
- radeon->sarea->pfCurrentPage, radeon->sarea->pfState);
- }
- drm_clip_rect_t *box = dPriv->pClipRects;
- drm_clip_rect_t *b = radeon->sarea->boxes;
- b[0] = box[0];
- radeon->sarea->nbox = 1;
-
- ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP );
-
- UNLOCK_HARDWARE(radeon);
-
- if ( ret ) {
- fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
- return GL_FALSE;
- }
-
- if (!rfb->pf_active)
- return GL_FALSE;
-
- rfb->pf_current_page = radeon->sarea->pfCurrentPage;
- radeon_flip_renderbuffers(rfb);
- radeon_draw_buffer(radeon->glCtx, &rfb->base);
-
- return GL_TRUE;
-}
-
-
-/**
- * Swap front and back buffer.
- */
-void radeonSwapBuffers(__DRIdrawable * dPriv)
-{
- int64_t ust;
- __DRIscreen *psp;
-
- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
- radeonContextPtr radeon;
- struct gl_context *ctx;
-
- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
- ctx = radeon->glCtx;
-
- if (ctx->Visual.doubleBufferMode) {
- GLboolean missed_target;
- struct radeon_framebuffer *rfb = dPriv->driverPrivate;
- _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */
-
- radeonScheduleSwap(dPriv, &missed_target);
-
- if (rfb->pf_active) {
- radeonPageFlip(dPriv);
- } else {
- radeonCopyBuffer(dPriv, NULL);
- }
-
- psp = dPriv->driScreenPriv;
-
- rfb->swap_count++;
- (*psp->systemTime->getUST)( & ust );
- if ( missed_target ) {
- rfb->swap_missed_count++;
- rfb->swap_missed_ust = ust - rfb->swap_ust;
- }
-
- rfb->swap_ust = ust;
- radeon->hw.all_dirty = GL_TRUE;
- }
- } else {
- /* XXX this shouldn't be an error but we can't handle it for now */
- _mesa_problem(NULL, "%s: drawable has no context!",
- __FUNCTION__);
- }
-}
-
-void radeonCopySubBuffer(__DRIdrawable * dPriv,
- int x, int y, int w, int h )
-{
- if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
- radeonContextPtr radeon;
- struct gl_context *ctx;
-
- radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
- ctx = radeon->glCtx;
-
- if (ctx->Visual.doubleBufferMode) {
- drm_clip_rect_t rect;
- rect.x1 = x + dPriv->x;
- rect.y1 = (dPriv->h - y - h) + dPriv->y;
- rect.x2 = rect.x1 + w;
- rect.y2 = rect.y1 + h;
- _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
- radeonCopyBuffer(dPriv, &rect);
- }
- } else {
- /* XXX this shouldn't be an error but we can't handle it for now */
- _mesa_problem(NULL, "%s: drawable has no context!",
- __FUNCTION__);
- }
-}
-
/**
* Check if we're about to draw into the front color buffer.
* If so, set the intel->front_buffer_dirty field to true.