diff options
author | Dave Airlie <airlied@redhat.com> | 2009-01-14 13:23:24 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-01-14 13:23:24 +1000 |
commit | 7e5e327cea83d9f6d1485f9be440277540ace5c7 (patch) | |
tree | 1d3c0a24c2bc4b27c772ef15aeb37a08aa2e8738 | |
parent | d29e96bf33e91d071770b86d87ffc4ef4dfc2f70 (diff) |
radeon/r200/r300: consolidate the buffer copy/flip code into one place
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_context.c | 21 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_ioctl.c | 318 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_ioctl.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_pixel.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_span.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.c | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/radeon_ioctl.c | 322 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_context.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_misc.c | 340 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/common_misc.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.c | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.c | 295 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.h | 5 |
13 files changed, 404 insertions, 944 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 9f882fe615..85e508616b 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -262,11 +262,26 @@ static void r200_get_lock(radeonContextPtr radeon) DRI_AGE_TEXTURES( rmesa->radeon.texture_heaps[ i ] ); } } - + + +static void r200_vtbl_flush(GLcontext *ctx) +{ + R200_FIREVERTICES(R200_CONTEXT(ctx)); +} + +static void r200_vtbl_set_all_dirty(GLcontext *ctx) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + rmesa->hw.all_dirty = GL_TRUE; +} + static void r200_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r200_get_lock; radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset; + radeon->vtbl.flush = r200_vtbl_flush; + radeon->vtbl.set_all_dirty = r200_vtbl_set_all_dirty; + radeon->vtbl.update_draw_buffer = r200UpdateDrawBuffer; } /* Create the device specific rendering context. @@ -642,7 +657,7 @@ r200SwapBuffers( __DRIdrawablePrivate *dPriv ) r200PageFlip( dPriv ); } else { - r200CopyBuffer( dPriv, NULL ); + radeonCopyBuffer( dPriv, NULL ); } } } @@ -668,7 +683,7 @@ r200CopySubBuffer( __DRIdrawablePrivate *dPriv, rect.x2 = rect.x1 + w; rect.y2 = rect.y1 + h; _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - r200CopyBuffer( dPriv, &rect ); + radeonCopyBuffer( dPriv, &rect ); } } else { diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 09baffb544..fe3a471c8a 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -55,9 +55,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_IDLE_RETRY 16 -static void r200WaitForIdle( r200ContextPtr rmesa ); - - /* At this point we were in FlushCmdBufLocked but we had lost our context, so * we need to unwire our current cmdbuf, hook the one with the saved state in * it, flush it, and then put the current one back. This is so commands at the @@ -152,7 +149,7 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) if (R200_DEBUG & DEBUG_SYNC) { fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); - r200WaitForIdleLocked( rmesa ); + radeonWaitForIdleLocked( &rmesa->radeon ); } @@ -329,281 +326,6 @@ void r200AllocDmaRegion( r200ContextPtr rmesa, assert( rmesa->dma.current.ptr <= rmesa->dma.current.end ); } -/* ================================================================ - * SwapBuffers with client-side throttling - */ - -static uint32_t r200GetLastFrame(r200ContextPtr rmesa) -{ - drm_radeon_getparam_t gp; - int ret; - uint32_t frame; - - gp.param = RADEON_PARAM_LAST_FRAME; - gp.value = (int *)&frame; - ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_GETPARAM, - &gp, sizeof(gp) ); - if ( ret ) { - fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret ); - exit(1); - } - - return frame; -} - -static void r200EmitIrqLocked( r200ContextPtr rmesa ) -{ - drm_radeon_irq_emit_t ie; - int ret; - - ie.irq_seq = &rmesa->radeon.iw.irq_seq; - ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_IRQ_EMIT, - &ie, sizeof(ie) ); - if ( ret ) { - fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret ); - exit(1); - } -} - - -static void r200WaitIrq( r200ContextPtr rmesa ) -{ - int ret; - - do { - ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_IRQ_WAIT, - &rmesa->radeon.iw, sizeof(rmesa->radeon.iw) ); - } while (ret && (errno == EINTR || errno == EBUSY)); - - if ( ret ) { - fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); - exit(1); - } -} - - -static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) -{ - drm_radeon_sarea_t *sarea = rmesa->radeon.sarea; - - if (rmesa->radeon.do_irqs) { - if (r200GetLastFrame(rmesa) < sarea->last_frame) { - if (!rmesa->radeon.irqsEmitted) { - while (r200GetLastFrame (rmesa) < sarea->last_frame) - ; - } - else { - UNLOCK_HARDWARE( &rmesa->radeon ); - r200WaitIrq( rmesa ); - LOCK_HARDWARE( &rmesa->radeon ); - } - rmesa->radeon.irqsEmitted = 10; - } - - if (rmesa->radeon.irqsEmitted) { - r200EmitIrqLocked( rmesa ); - rmesa->radeon.irqsEmitted--; - } - } - else { - while (r200GetLastFrame (rmesa) < sarea->last_frame) { - UNLOCK_HARDWARE( &rmesa->radeon ); - if (rmesa->radeon.do_usleeps) - DO_USLEEP( 1 ); - LOCK_HARDWARE( &rmesa->radeon ); - } - } -} - - - -/* Copy the back color buffer to the front color buffer. - */ -void r200CopyBuffer( __DRIdrawablePrivate *dPriv, - const drm_clip_rect_t *rect) -{ - r200ContextPtr rmesa; - GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp = dPriv->driScreenPriv; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; - - if ( R200_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *)rmesa->radeon.glCtx ); - } - - R200_FIREVERTICES( rmesa ); - - LOCK_HARDWARE( &rmesa->radeon ); - - - /* Throttle the frame rate -- only allow one pending swap buffers - * request at a time. - */ - r200WaitForFrameCompletion( rmesa ); - if (!rect) - { - UNLOCK_HARDWARE( &rmesa->radeon ); - driWaitForVBlank( dPriv, & missed_target ); - LOCK_HARDWARE( &rmesa->radeon ); - } - - 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->radeon.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->radeon.sarea->nbox = n; - - if (!n) - continue; - - ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_SWAP ); - - if ( ret ) { - fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret ); - UNLOCK_HARDWARE( &rmesa->radeon ); - exit( 1 ); - } - } - - UNLOCK_HARDWARE( &rmesa->radeon ); - if (!rect) - { - rmesa->hw.all_dirty = GL_TRUE; - - rmesa->radeon.swap_count++; - (*psp->systemTime->getUST)( & ust ); - if ( missed_target ) { - rmesa->radeon.swap_missed_count++; - rmesa->radeon.swap_missed_ust = ust - rmesa->radeon.swap_ust; - } - - rmesa->radeon.swap_ust = ust; - - sched_yield(); - } -} - -void r200PageFlip( __DRIdrawablePrivate *dPriv ) -{ - r200ContextPtr rmesa; - GLint ret; - GLboolean missed_target; - __DRIscreenPrivate *psp = dPriv->driScreenPriv; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; - - if ( R200_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - rmesa->radeon.sarea->pfCurrentPage); - } - - R200_FIREVERTICES( rmesa ); - LOCK_HARDWARE( &rmesa->radeon ); - - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE( &rmesa->radeon ); - usleep( 10000 ); /* throttle invisible client 10ms */ - return; - } - - /* Need to do this for the perf box placement: - */ - { - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t *b = rmesa->radeon.sarea->boxes; - b[0] = box[0]; - rmesa->radeon.sarea->nbox = 1; - } - - /* Throttle the frame rate -- only allow a few pending swap buffers - * request at a time. - */ - r200WaitForFrameCompletion( rmesa ); - UNLOCK_HARDWARE( &rmesa->radeon ); - driWaitForVBlank( dPriv, & missed_target ); - if ( missed_target ) { - rmesa->radeon.swap_missed_count++; - (void) (*psp->systemTime->getUST)( & rmesa->radeon.swap_missed_ust ); - } - LOCK_HARDWARE( &rmesa->radeon ); - - ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_FLIP ); - - UNLOCK_HARDWARE( &rmesa->radeon ); - - if ( ret ) { - fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); - exit( 1 ); - } - - rmesa->radeon.swap_count++; - (void) (*psp->systemTime->getUST)( & rmesa->radeon.swap_ust ); - -#if 000 - if ( rmesa->radeon.sarea->pfCurrentPage == 1 ) { - rmesa->state.color.drawOffset = rmesa->radeon.radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeon.radeonScreen->frontPitch; - } else { - rmesa->state.color.drawOffset = rmesa->radeon.radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeon.radeonScreen->backPitch; - } - - R200_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset - + rmesa->radeon.radeonScreen->fbLocation; - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; - if (rmesa->radeon.sarea->tiling_enabled) { - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; - } -#else - /* Get ready for drawing next frame. Update the renderbuffers' - * flippedOffset/Pitch fields so we draw into the right place. - */ - driFlipRenderbuffers(rmesa->radeon.glCtx->WinSysDrawBuffer, - rmesa->radeon.sarea->pfCurrentPage); - - - r200UpdateDrawBuffer(rmesa->radeon.glCtx); -#endif -} - /* ================================================================ * Buffer clear @@ -790,33 +512,6 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) } -void r200WaitForIdleLocked( r200ContextPtr rmesa ) -{ - int ret; - int i = 0; - - do { - ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_CP_IDLE); - if (ret) - DO_USLEEP( 1 ); - } while (ret && ++i < 100); - - if ( ret < 0 ) { - UNLOCK_HARDWARE( &rmesa->radeon ); - fprintf( stderr, "Error: R200 timed out... exiting\n" ); - exit( -1 ); - } -} - - -static void r200WaitForIdle( r200ContextPtr rmesa ) -{ - LOCK_HARDWARE(&rmesa->radeon); - r200WaitForIdleLocked( rmesa ); - UNLOCK_HARDWARE(&rmesa->radeon); -} - - void r200Flush( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); @@ -838,17 +533,8 @@ void r200Flush( GLcontext *ctx ) */ void r200Finish( GLcontext *ctx ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); r200Flush( ctx ); - - if (rmesa->radeon.do_irqs) { - LOCK_HARDWARE( &rmesa->radeon ); - r200EmitIrqLocked( rmesa ); - UNLOCK_HARDWARE( &rmesa->radeon ); - r200WaitIrq( rmesa ); - } - else - r200WaitForIdle( rmesa ); + radeon_common_finish(ctx); } diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h index f52d2a7419..1f92705685 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.h +++ b/src/mesa/drivers/dri/r200/r200_ioctl.h @@ -89,13 +89,8 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa, struct radeon_dma_region *region, const char *caller ); -extern void r200CopyBuffer( __DRIdrawablePrivate *drawable, - const drm_clip_rect_t *rect); -extern void r200PageFlip( __DRIdrawablePrivate *drawable ); extern void r200Flush( GLcontext *ctx ); extern void r200Finish( GLcontext *ctx ); -extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); -extern void r200WaitForVBlank( r200ContextPtr rmesa ); extern void r200InitIoctlFuncs( struct dd_function_table *functions ); extern void *r200AllocateMemoryMESA( __DRIscreen *screen, GLsizei size, GLfloat readfreq, diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c index 60d25825e9..a8aa1a2773 100644 --- a/src/mesa/drivers/dri/r200/r200_pixel.c +++ b/src/mesa/drivers/dri/r200/r200_pixel.c @@ -364,7 +364,7 @@ static void do_draw_pix( GLcontext *ctx, } r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); - r200WaitForIdleLocked( rmesa ); /* required by GL */ + radeonWaitForIdleLocked( &rmesa->radeon ); /* required by GL */ UNLOCK_HARDWARE( &rmesa->radeon ); } diff --git a/src/mesa/drivers/dri/r200/r200_span.c b/src/mesa/drivers/dri/r200/r200_span.c index dfe587401d..b4da9ef6a3 100644 --- a/src/mesa/drivers/dri/r200/r200_span.c +++ b/src/mesa/drivers/dri/r200/r200_span.c @@ -243,7 +243,7 @@ static void r200SpanRenderStart( GLcontext *ctx ) R200_FIREVERTICES( rmesa ); LOCK_HARDWARE( &rmesa->radeon ); - r200WaitForIdleLocked( rmesa ); + radeonWaitForIdleLocked( &rmesa->radeon ); /* Read & rewrite the first pixel in the frame buffer. This should * be a noop, right? In fact without this conform fails as reading diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 1958484b3c..3b8ba855bb 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -198,12 +198,26 @@ static void r300_get_lock(radeonContextPtr rmesa) } } +static void r300_vtbl_flush(GLcontext *ctx) +{ + r300Flush(ctx); +} + +static void r300_vtbl_set_all_dirty(GLcontext *ctx) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + rmesa->hw.all_dirty = GL_TRUE; +} + static void r300_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r300_get_lock; radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; + radeon->vtbl.flush = r300_vtbl_flush; + radeon->vtbl.set_all_dirty = r300_vtbl_set_all_dirty; } + /* Create the device specific rendering context. */ GLboolean r300CreateContext(const __GLcontextModes * glVisual, diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c index 8712317050..120d6c03ab 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.c +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c @@ -50,307 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drirenderbuffer.h" #include "vblank.h" -static void radeonWaitForIdle(radeonContextPtr radeon); - -/* ================================================================ - * SwapBuffers with client-side throttling - */ - -static uint32_t radeonGetLastFrame(radeonContextPtr radeon) -{ - drm_radeon_getparam_t gp; - int ret; - uint32_t frame; - - 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; - int ret; - uint32_t age; - - gp.param = RADEON_PARAM_LAST_CLEAR; - gp.value = (int *)&age; - ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, - ret); - exit(1); - } - - 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); - } - } -} - -/* Copy the back color buffer to the front color buffer. - */ -void radeonCopyBuffer(__DRIdrawablePrivate * dPriv, - const drm_clip_rect_t * rect) -{ - radeonContextPtr radeon; - GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp = dPriv->driScreenPriv; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - - if (RADEON_DEBUG & DEBUG_IOCTL) { - fprintf(stderr, "\n%s( %p )\n\n", __FUNCTION__, - (void *)radeon->glCtx); - } - - r300Flush(radeon->glCtx); - - LOCK_HARDWARE(radeon); - - /* Throttle the frame rate -- only allow one pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion(radeon); - if (!rect) - { - UNLOCK_HARDWARE(radeon); - driWaitForVBlank(dPriv, &missed_target); - LOCK_HARDWARE(radeon); - } - - 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 = radeon->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++; - } - radeon->sarea->nbox = n; - - if (!n) - continue; - - ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_SWAP); - - if (ret) { - fprintf(stderr, "DRM_RADEON_SWAP: return = %d\n", - ret); - UNLOCK_HARDWARE(radeon); - exit(1); - } - } - - UNLOCK_HARDWARE(radeon); - if (!rect) - { - ((r300ContextPtr)radeon)->hw.all_dirty = GL_TRUE; - - radeon->swap_count++; - (*psp->systemTime->getUST) (&ust); - if (missed_target) { - radeon->swap_missed_count++; - radeon->swap_missed_ust = ust - radeon->swap_ust; - } - - radeon->swap_ust = ust; - - sched_yield(); - } -} - -void radeonPageFlip(__DRIdrawablePrivate * dPriv) -{ - radeonContextPtr radeon; - GLint ret; - GLboolean missed_target; - __DRIscreenPrivate *psp = dPriv->driScreenPriv; - GLframebuffer *fb = dPriv->driverPrivate; - struct radeon_renderbuffer *rrb; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - - rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - - if (RADEON_DEBUG & DEBUG_IOCTL) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - radeon->sarea->pfCurrentPage); - } - - r300Flush(radeon->glCtx); - LOCK_HARDWARE(radeon); - - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(radeon); - usleep(10000); /* throttle invisible client 10ms */ - return; - } - - /* Need to do this for the perf box placement: - */ - { - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t *b = radeon->sarea->boxes; - b[0] = box[0]; - radeon->sarea->nbox = 1; - } - - /* Throttle the frame rate -- only allow a few pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion(radeon); - UNLOCK_HARDWARE(radeon); - driWaitForVBlank(dPriv, &missed_target); - if (missed_target) { - radeon->swap_missed_count++; - (void)(*psp->systemTime->getUST) (&radeon->swap_missed_ust); - } - LOCK_HARDWARE(radeon); - - ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_FLIP); - - UNLOCK_HARDWARE(radeon); - - if (ret) { - fprintf(stderr, "DRM_RADEON_FLIP: return = %d\n", ret); - exit(1); - } - - radeon->swap_count++; - (void)(*psp->systemTime->getUST) (&radeon->swap_ust); - - driFlipRenderbuffers(radeon->glCtx->WinSysDrawBuffer, - radeon->sarea->pfCurrentPage); - - radeon->state.color.rrb = rrb; -} - -void radeonWaitForIdleLocked(radeonContextPtr radeon) -{ - int ret; - int i = 0; - - do { - ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); - if (ret) - DO_USLEEP(1); - } while (ret && ++i < 100); - - if (ret < 0) { - UNLOCK_HARDWARE(radeon); - fprintf(stderr, "Error: R300 timed out... exiting\n"); - exit(-1); - } -} - -static void radeonWaitForIdle(radeonContextPtr radeon) -{ - LOCK_HARDWARE(radeon); - radeonWaitForIdleLocked(radeon); - UNLOCK_HARDWARE(radeon); -} - void radeonFlush(GLcontext * ctx) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); @@ -365,25 +64,6 @@ void radeonFlush(GLcontext * ctx) */ void radeonFinish(GLcontext * ctx) { - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - radeonFlush(ctx); - - if (radeon->radeonScreen->kernel_mm) { - for (i = 0; i < fb->_NumColorDrawBuffers; i++) { - struct radeon_renderbuffer *rrb; - rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i]; - if (rrb->bo) - radeon_bo_wait(rrb->bo); - } - } else if (radeon->do_irqs) { - LOCK_HARDWARE(radeon); - radeonEmitIrqLocked(radeon); - UNLOCK_HARDWARE(radeon); - radeonWaitIrq(radeon); - } else { - radeonWaitForIdle(radeon); - } + radeon_common_finish(ctx); } diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h index 723f7d14fd..d157c93dcb 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -311,6 +311,9 @@ struct radeon_context { struct { void (*get_lock)(radeonContextPtr radeon); void (*update_viewport_offset)(GLcontext *ctx); + void (*flush)(GLcontext *ctx); + void (*set_all_dirty)(GLcontext *ctx); + void (*update_draw_buffer)(GLcontext *ctx); } vtbl; }; diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c index 3bfb61a084..b14ca8b51b 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ b/src/mesa/drivers/dri/radeon/common_misc.c @@ -33,6 +33,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Keith Whitwell <keith@tungstengraphics.com> */ +#include <errno.h> #include "main/glheader.h" #include "main/imports.h" #include "main/api_arrayelt.h" @@ -47,11 +48,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" +#include "drirenderbuffer.h" +#include "vblank.h" + + #include "dri_util.h" #include "radeon_drm.h" #include "radeon_screen.h" +#include "radeon_buffer.h" #include "common_context.h" #include "common_misc.h" +#include "common_lock.h" + /* ============================================================= * Scissoring */ @@ -185,3 +193,335 @@ void radeonUpdateScissor( GLcontext *ctx ) radeonRecalcScissorRects( rmesa ); } } + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +static uint32_t radeonGetLastFrame(radeonContextPtr radeon) +{ + drm_radeon_getparam_t gp; + int ret; + uint32_t frame; + + 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; + int ret; + uint32_t age; + + gp.param = RADEON_PARAM_LAST_CLEAR; + gp.value = (int *)&age; + ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, + ret); + exit(1); + } + + 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) +{ + int ret; + int i = 0; + + do { + ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_CP_IDLE); + if (ret) + DO_USLEEP(1); + } while (ret && ++i < 100); + + if (ret < 0) { + UNLOCK_HARDWARE(radeon); + fprintf(stderr, "Error: R300 timed out... exiting\n"); + exit(-1); + } +} + +static void radeonWaitForIdle(radeonContextPtr radeon) +{ + LOCK_HARDWARE(radeon); + radeonWaitForIdleLocked(radeon); + UNLOCK_HARDWARE(radeon); +} + + +/* Copy the back color buffer to the front color buffer. + */ +void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, + const drm_clip_rect_t *rect) +{ + GLcontext *ctx; + radeonContextPtr rmesa; + GLint nbox, i, ret; + GLboolean missed_target; + int64_t ust; + __DRIscreenPrivate *psp; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + ctx = (GLcontext *) dPriv->driContextPriv->driverPrivate; + rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + +/// if ( RADEON_DEBUG & DEBUG_IOCTL ) { +// fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); +// } + + rmesa->vtbl.flush(ctx); + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + radeonWaitForFrameCompletion( rmesa ); + if (!rect) + { + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( dPriv, & missed_target ); + LOCK_HARDWARE( rmesa ); + } + + 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 ); + if (!rect) + { + psp = dPriv->driScreenPriv; + rmesa->swap_count++; + (*psp->systemTime->getUST)( & ust ); + if ( missed_target ) { + rmesa->swap_missed_count++; + rmesa->swap_missed_ust = ust - rmesa->swap_ust; + } + + rmesa->swap_ust = ust; + rmesa->vtbl.set_all_dirty(ctx); + + } +} + +void radeonPageFlip( __DRIdrawablePrivate *dPriv ) +{ + radeonContextPtr rmesa; + GLint ret; + GLboolean missed_target; + __DRIscreenPrivate *psp; + struct radeon_renderbuffer *rrb; + GLframebuffer *fb = dPriv->driverPrivate; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + + psp = dPriv->driScreenPriv; + +#if 0 + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, + rmesa->sarea->pfCurrentPage); + } +#endif + + rmesa->vtbl.flush(rmesa->glCtx); + + LOCK_HARDWARE( rmesa ); + + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(rmesa); + usleep(10000); /* throttle invisible client 10ms */ + return; + } + + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t *b = rmesa->sarea->boxes; + b[0] = box[0]; + rmesa->sarea->nbox = 1; + + /* Throttle the frame rate -- only allow a few pending swap buffers + * request at a time. + */ + radeonWaitForFrameCompletion( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( dPriv, & missed_target ); + if ( missed_target ) { + rmesa->swap_missed_count++; + (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust ); + } + LOCK_HARDWARE( rmesa ); + + ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); + exit( 1 ); + } + + rmesa->swap_count++; + (void) (*psp->systemTime->getUST)( & rmesa->swap_ust ); + + /* Get ready for drawing next frame. Update the renderbuffers' + * flippedOffset/Pitch fields so we draw into the right place. + */ + driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, + rmesa->sarea->pfCurrentPage); + + rmesa->state.color.rrb = rrb; + + if (rmesa->vtbl.update_draw_buffer) + rmesa->vtbl.update_draw_buffer(rmesa->glCtx); +} + + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +void radeon_common_finish(GLcontext * ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + int i; + + if (radeon->radeonScreen->kernel_mm) { + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + struct radeon_renderbuffer *rrb; + rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i]; + if (rrb->bo) + radeon_bo_wait(rrb->bo); + } + } else if (radeon->do_irqs) { + LOCK_HARDWARE(radeon); + radeonEmitIrqLocked(radeon); + UNLOCK_HARDWARE(radeon); + radeonWaitIrq(radeon); + } else { + radeonWaitForIdle(radeon); + } +} diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h index 5653ef3183..27e869d4bb 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ b/src/mesa/drivers/dri/radeon/common_misc.h @@ -5,4 +5,11 @@ void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); +void radeonWaitForIdleLocked(radeonContextPtr radeon); +extern uint32_t radeonGetAge(radeonContextPtr radeon); +void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, + const drm_clip_rect_t *rect); +void radeonPageFlip( __DRIdrawablePrivate *dPriv ); +void radeon_common_finish(GLcontext * ctx); + #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e49be4b23b..ab2002cd90 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -218,10 +218,24 @@ static void r100_get_lock(radeonContextPtr radeon) } } +static void r100_vtbl_flush(GLcontext *ctx) +{ + RADEON_FIREVERTICES(R100_CONTEXT(ctx)); +} + +static void r100_vtbl_set_all_dirty(GLcontext *ctx) +{ + r100ContextPtr rmesa = R100_CONTEXT(ctx); + rmesa->hw.all_dirty = GL_TRUE; +} + static void r100_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r100_get_lock; radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset; + radeon->vtbl.flush = r100_vtbl_flush; + radeon->vtbl.set_all_dirty = r100_vtbl_set_all_dirty; + radeon->vtbl.update_draw_buffer = radeonUpdateDrawBuffer; } /* Create the device specific context. diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 31f4778fab..2b02d0b71f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -58,7 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RADEON_IDLE_RETRY 16 -static void radeonWaitForIdle( r100ContextPtr rmesa ); static int radeonFlushCmdBufLocked( r100ContextPtr rmesa, const char * caller ); @@ -592,7 +591,7 @@ static int radeonFlushCmdBufLocked( r100ContextPtr rmesa, if (RADEON_DEBUG & DEBUG_SYNC) { fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); - radeonWaitForIdleLocked( rmesa ); + radeonWaitForIdleLocked( &rmesa->radeon ); } out: @@ -678,7 +677,7 @@ void radeonRefillCurrentDmaRegion( r100ContextPtr rmesa ) if (RADEON_DEBUG & DEBUG_DMA) fprintf(stderr, "Waiting for buffers\n"); - radeonWaitForIdleLocked( rmesa ); + radeonWaitForIdleLocked( &rmesa->radeon ); ret = drmDMA( fd, &dma ); if ( ret != 0 ) { @@ -775,254 +774,6 @@ void radeonAllocDmaRegion( r100ContextPtr rmesa, } /* ================================================================ - * SwapBuffers with client-side throttling - */ - -static uint32_t radeonGetLastFrame (r100ContextPtr rmesa) -{ - drm_radeon_getparam_t gp; - int ret; - uint32_t frame; - - gp.param = RADEON_PARAM_LAST_FRAME; - gp.value = (int *)&frame; - ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_GETPARAM, - &gp, sizeof(gp) ); - - if ( ret ) { - fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret ); - exit(1); - } - - return frame; -} - -static void radeonEmitIrqLocked( r100ContextPtr rmesa ) -{ - drm_radeon_irq_emit_t ie; - int ret; - - ie.irq_seq = &rmesa->radeon.iw.irq_seq; - ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_IRQ_EMIT, - &ie, sizeof(ie) ); - if ( ret ) { - fprintf( stderr, "%s: drm_radeon_irq_emit_t: %d\n", __FUNCTION__, ret ); - exit(1); - } -} - - -static void radeonWaitIrq( r100ContextPtr rmesa ) -{ - int ret; - - do { - ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_IRQ_WAIT, - &rmesa->radeon.iw, sizeof(rmesa->radeon.iw) ); - } while (ret && (errno == EINTR || errno == EBUSY)); - - if ( ret ) { - fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret ); - exit(1); - } -} - - -static void radeonWaitForFrameCompletion( r100ContextPtr rmesa ) -{ - drm_radeon_sarea_t *sarea = rmesa->radeon.sarea; - - if (rmesa->radeon.do_irqs) { - if (radeonGetLastFrame(rmesa) < sarea->last_frame) { - if (!rmesa->radeon.irqsEmitted) { - while (radeonGetLastFrame (rmesa) < sarea->last_frame) - ; - } - else { - UNLOCK_HARDWARE( &rmesa->radeon ); - radeonWaitIrq( rmesa ); - LOCK_HARDWARE( &rmesa->radeon ); - } - rmesa->radeon.irqsEmitted = 10; - } - - if (rmesa->radeon.irqsEmitted) { - radeonEmitIrqLocked( rmesa ); - rmesa->radeon.irqsEmitted--; - } - } - else { - while (radeonGetLastFrame (rmesa) < sarea->last_frame) { - UNLOCK_HARDWARE( &rmesa->radeon ); - if (rmesa->radeon.do_usleeps) - DO_USLEEP( 1 ); - LOCK_HARDWARE( &rmesa->radeon ); - } - } -} - -/* Copy the back color buffer to the front color buffer. - */ -void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, - const drm_clip_rect_t *rect) -{ - r100ContextPtr rmesa; - GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (r100ContextPtr) dPriv->driContextPriv->driverPrivate; - - if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->radeon.glCtx ); - } - - RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( &rmesa->radeon ); - - /* Throttle the frame rate -- only allow one pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion( rmesa ); - if (!rect) - { - UNLOCK_HARDWARE( &rmesa->radeon ); - driWaitForVBlank( dPriv, & missed_target ); - LOCK_HARDWARE( &rmesa->radeon ); - } - - 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->radeon.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->radeon.sarea->nbox = n; - - if (!n) - continue; - - ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_SWAP ); - - if ( ret ) { - fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); - UNLOCK_HARDWARE( &rmesa->radeon ); - exit( 1 ); - } - } - - UNLOCK_HARDWARE( &rmesa->radeon ); - if (!rect) - { - psp = dPriv->driScreenPriv; - rmesa->radeon.swap_count++; - (*psp->systemTime->getUST)( & ust ); - if ( missed_target ) { - rmesa->radeon.swap_missed_count++; - rmesa->radeon.swap_missed_ust = ust - rmesa->radeon.swap_ust; - } - - rmesa->radeon.swap_ust = ust; - rmesa->hw.all_dirty = GL_TRUE; - } -} - -void radeonPageFlip( __DRIdrawablePrivate *dPriv ) -{ - r100ContextPtr rmesa; - GLint ret; - GLboolean missed_target; - __DRIscreenPrivate *psp; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (r100ContextPtr) dPriv->driContextPriv->driverPrivate; - psp = dPriv->driScreenPriv; - - if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - rmesa->radeon.sarea->pfCurrentPage); - } - - RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( &rmesa->radeon ); - - /* Need to do this for the perf box placement: - */ - if (dPriv->numClipRects) - { - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t *b = rmesa->radeon.sarea->boxes; - b[0] = box[0]; - rmesa->radeon.sarea->nbox = 1; - } - - /* Throttle the frame rate -- only allow a few pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion( rmesa ); - UNLOCK_HARDWARE( &rmesa->radeon ); - driWaitForVBlank( dPriv, & missed_target ); - if ( missed_target ) { - rmesa->radeon.swap_missed_count++; - (void) (*psp->systemTime->getUST)( & rmesa->radeon.swap_missed_ust ); - } - LOCK_HARDWARE( &rmesa->radeon ); - - ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_FLIP ); - - UNLOCK_HARDWARE( &rmesa->radeon ); - - if ( ret ) { - fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); - exit( 1 ); - } - - rmesa->radeon.swap_count++; - (void) (*psp->systemTime->getUST)( & rmesa->radeon.swap_ust ); - - /* Get ready for drawing next frame. Update the renderbuffers' - * flippedOffset/Pitch fields so we draw into the right place. - */ - driFlipRenderbuffers(rmesa->radeon.glCtx->WinSysDrawBuffer, - rmesa->radeon.sarea->pfCurrentPage); - - radeonUpdateDrawBuffer(rmesa->radeon.glCtx); -} - - -/* ================================================================ * Buffer clear */ #define RADEON_MAX_CLEARS 256 @@ -1207,37 +958,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) rmesa->hw.all_dirty = GL_TRUE; } - -void radeonWaitForIdleLocked( r100ContextPtr rmesa ) -{ - int fd = rmesa->radeon.dri.fd; - int to = 0; - int ret, i = 0; - - rmesa->c_drawWaits++; - - do { - do { - ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE); - } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); - } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); - - if ( ret < 0 ) { - UNLOCK_HARDWARE( &rmesa->radeon ); - fprintf( stderr, "Error: Radeon timed out... exiting\n" ); - exit( -1 ); - } -} - - -static void radeonWaitForIdle( r100ContextPtr rmesa ) -{ - LOCK_HARDWARE(&rmesa->radeon); - radeonWaitForIdleLocked( rmesa ); - UNLOCK_HARDWARE(&rmesa->radeon); -} - - void radeonFlush( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT( ctx ); @@ -1259,17 +979,8 @@ void radeonFlush( GLcontext *ctx ) */ void radeonFinish( GLcontext *ctx ) { - r100ContextPtr rmesa = R100_CONTEXT(ctx); radeonFlush( ctx ); - - if (rmesa->radeon.do_irqs) { - LOCK_HARDWARE( &rmesa->radeon ); - radeonEmitIrqLocked( rmesa ); - UNLOCK_HARDWARE( &rmesa->radeon ); - radeonWaitIrq( rmesa ); - } - else - radeonWaitForIdle( rmesa ); + radeon_common_finish(ctx); } diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h index c97f41d9a1..d11feb5804 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h @@ -87,13 +87,8 @@ extern void radeonReleaseDmaRegion( r100ContextPtr rmesa, struct radeon_dma_region *region, const char *caller ); -extern void radeonCopyBuffer( __DRIdrawablePrivate *drawable, - const drm_clip_rect_t *rect); -extern void radeonPageFlip( __DRIdrawablePrivate *drawable ); extern void radeonFlush( GLcontext *ctx ); extern void radeonFinish( GLcontext *ctx ); -extern void radeonWaitForIdleLocked( r100ContextPtr rmesa ); -extern void radeonWaitForVBlank( r100ContextPtr rmesa ); extern void radeonInitIoctlFuncs( GLcontext *ctx ); extern void radeonGetAllParams( r100ContextPtr rmesa ); extern void radeonSetUpAtomList( r100ContextPtr rmesa ); |