From 4637235183b80963536f2364e4d50fcb894886dd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 Jan 2009 10:44:48 +1000 Subject: radeon/r200/r300: initial attempt to convert to common context code --- src/mesa/drivers/dri/radeon/radeon_lock.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_lock.h') diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index 86e96aa7d2..e4bfa1b9d6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __RADEON_LOCK_H__ #define __RADEON_LOCK_H__ -extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); +extern void radeonGetLock(r100ContextPtr rmesa, GLuint flags); /* Turn DEBUG_LOCKING on to find locking conflicts. */ @@ -94,8 +94,8 @@ extern int prevLockLine; do { \ char __ret = 0; \ DEBUG_CHECK_LOCK(); \ - DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ + DRM_CAS( (rmesa)->radeon.dri.hwLock, (rmesa)->radeon.dri.hwContext, \ + (DRM_LOCK_HELD | (rmesa)->radeon.dri.hwContext), __ret ); \ if ( __ret ) \ radeonGetLock( (rmesa), 0 ); \ DEBUG_LOCK(); \ @@ -103,9 +103,9 @@ extern int prevLockLine; #define UNLOCK_HARDWARE( rmesa ) \ do { \ - DRM_UNLOCK( (rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext ); \ + DRM_UNLOCK( (rmesa)->radeon.dri.fd, \ + (rmesa)->radeon.dri.hwLock, \ + (rmesa)->radeon.dri.hwContext ); \ DEBUG_RESET(); \ } while (0) -- cgit v1.2.3 From d29e96bf33e91d071770b86d87ffc4ef4dfc2f70 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 14 Jan 2009 12:04:00 +1000 Subject: radeon/r200/r300: attempt to move lock to common code --- src/mesa/drivers/dri/r200/Makefile | 9 +- src/mesa/drivers/dri/r200/r200_context.c | 35 ++++- src/mesa/drivers/dri/r200/r200_context.h | 5 +- src/mesa/drivers/dri/r200/r200_ioctl.c | 88 +++++------ src/mesa/drivers/dri/r200/r200_lock.h | 68 +-------- src/mesa/drivers/dri/r200/r200_pixel.c | 12 +- src/mesa/drivers/dri/r200/r200_span.c | 4 +- src/mesa/drivers/dri/r200/r200_state.c | 157 ++------------------ src/mesa/drivers/dri/r200/r200_state_init.c | 38 ++--- src/mesa/drivers/dri/r200/r200_swtcl.c | 4 +- src/mesa/drivers/dri/r200/r200_texmem.c | 10 +- src/mesa/drivers/dri/r300/Makefile | 9 +- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 2 +- src/mesa/drivers/dri/r300/r300_context.c | 18 +++ src/mesa/drivers/dri/r300/r300_context.h | 11 -- src/mesa/drivers/dri/r300/r300_ioctl.c | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 16 +- src/mesa/drivers/dri/r300/radeon_context.c | 2 +- src/mesa/drivers/dri/r300/radeon_context.h | 1 + src/mesa/drivers/dri/r300/radeon_state.c | 129 ---------------- src/mesa/drivers/dri/r300/radeon_state.h | 4 - src/mesa/drivers/dri/radeon/Makefile | 5 +- src/mesa/drivers/dri/radeon/common_context.h | 11 +- src/mesa/drivers/dri/radeon/common_lock.c | 138 +++++++++++++++++ src/mesa/drivers/dri/radeon/common_lock.h | 111 ++++++++++++++ src/mesa/drivers/dri/radeon/common_misc.c | 187 ++++++++++++++++++++++++ src/mesa/drivers/dri/radeon/common_misc.h | 8 + src/mesa/drivers/dri/radeon/radeon_context.c | 37 ++++- src/mesa/drivers/dri/radeon/radeon_context.h | 9 +- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 86 +++++------ src/mesa/drivers/dri/radeon/radeon_lock.h | 67 +-------- src/mesa/drivers/dri/radeon/radeon_span.c | 6 +- src/mesa/drivers/dri/radeon/radeon_state.c | 156 ++------------------ src/mesa/drivers/dri/radeon/radeon_state.h | 2 - src/mesa/drivers/dri/radeon/radeon_state_init.c | 22 +-- src/mesa/drivers/dri/radeon/radeon_texmem.c | 10 +- 36 files changed, 738 insertions(+), 741 deletions(-) create mode 100644 src/mesa/drivers/dri/radeon/common_lock.c create mode 100644 src/mesa/drivers/dri/radeon/common_lock.h create mode 100644 src/mesa/drivers/dri/radeon/common_misc.c create mode 100644 src/mesa/drivers/dri/radeon/common_misc.h (limited to 'src/mesa/drivers/dri/radeon/radeon_lock.h') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index f4c173085b..34aa74735b 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -13,7 +13,6 @@ endif DRIVER_SOURCES = r200_context.c \ r200_ioctl.c \ - r200_lock.c \ r200_state.c \ r200_state_init.c \ r200_cmdbuf.c \ @@ -29,6 +28,8 @@ DRIVER_SOURCES = r200_context.c \ r200_fragshader.c \ r200_vertprog.c \ radeon_screen.c \ + common_lock.c \ + common_misc.c \ $(EGL_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -51,7 +52,11 @@ COMMON_SYMLINKS = \ radeon_screen.h \ radeon_bo_legacy.h \ radeon_buffer.h \ - common_context.h + common_context.h \ + common_lock.c \ + common_lock.h \ + common_misc.h \ + common_misc.c ##### TARGETS ##### diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 9e89c1d743..9f882fe615 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -242,6 +242,32 @@ static const struct dri_debug_control debug_control[] = { NULL, 0 } }; +static void r200_get_lock(radeonContextPtr radeon) +{ + r200ContextPtr rmesa = (r200ContextPtr)radeon; + drm_radeon_sarea_t *sarea = radeon->sarea; + int i; + + R200_STATECHANGE( rmesa, ctx ); + if (rmesa->radeon.sarea->tiling_enabled) { + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; + } + else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE; + + if ( sarea->ctx_owner != rmesa->radeon.dri.hwContext ) { + sarea->ctx_owner = rmesa->radeon.dri.hwContext; + } + + for ( i = 0 ; i < rmesa->radeon.nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( rmesa->radeon.texture_heaps[ i ] ); + } +} + +static void r200_init_vtbl(radeonContextPtr radeon) +{ + radeon->vtbl.get_lock = r200_get_lock; + radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset; +} /* Create the device specific rendering context. */ @@ -265,7 +291,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); if ( !rmesa ) return GL_FALSE; - + + r200_init_vtbl(&rmesa->radeon); /* init exp fog table data */ r200InitStaticFogData(); @@ -568,9 +595,9 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) r200FlushCmdBuf( rmesa, __FUNCTION__ ); } - if (rmesa->state.scissor.pClipRects) { - FREE(rmesa->state.scissor.pClipRects); - rmesa->state.scissor.pClipRects = NULL; + if (rmesa->radeon.state.scissor.pClipRects) { + FREE(rmesa->radeon.state.scissor.pClipRects); + rmesa->radeon.state.scissor.pClipRects = NULL; } if ( release_texture_heaps ) { diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 9ee6c15bf4..94f9b86d2f 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" #include "common_context.h" +#include "common_misc.h" struct r200_context; typedef struct r200_context r200ContextRec; @@ -519,10 +520,6 @@ struct r200_hw_state { struct r200_state { /* Derived state for internal purposes: */ - struct radeon_colorbuffer_state color; - struct radeon_depthbuffer_state depth; - struct radeon_scissor_state scissor; - struct radeon_stencilbuffer_state stencil; struct radeon_stipple_state stipple; struct r200_texture_state texture; GLuint envneeded; diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 16776abd02..09baffb544 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -108,10 +108,10 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) if (R200_DEBUG & DEBUG_SANITY) { - if (rmesa->state.scissor.enabled) + if (rmesa->radeon.state.scissor.enabled) ret = r200SanityCmdBuffer( rmesa, - rmesa->state.scissor.numClipRects, - rmesa->state.scissor.pClipRects); + rmesa->radeon.state.scissor.numClipRects, + rmesa->radeon.state.scissor.pClipRects); else ret = r200SanityCmdBuffer( rmesa, rmesa->radeon.numClipRects, @@ -135,9 +135,9 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) cmd.bufsz = rmesa->store.cmd_used; cmd.buf = rmesa->store.cmd_buf; - if (rmesa->state.scissor.enabled) { - cmd.nbox = rmesa->state.scissor.numClipRects; - cmd.boxes = (drm_clip_rect_t *)rmesa->state.scissor.pClipRects; + if (rmesa->radeon.state.scissor.enabled) { + cmd.nbox = rmesa->radeon.state.scissor.numClipRects; + cmd.boxes = (drm_clip_rect_t *)rmesa->radeon.state.scissor.pClipRects; } else { cmd.nbox = rmesa->radeon.numClipRects; cmd.boxes = (drm_clip_rect_t *)rmesa->radeon.pClipRects; @@ -174,11 +174,11 @@ void r200FlushCmdBuf( r200ContextPtr rmesa, const char *caller ) { int ret; - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); ret = r200FlushCmdBufLocked( rmesa, caller ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (ret) { fprintf(stderr, "drmRadeonCmdBuffer: %d (exiting)\n", ret); @@ -225,7 +225,7 @@ void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ) dma.request_sizes = &size; dma.granted_count = 0; - LOCK_HARDWARE(rmesa); /* no need to validate */ + LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */ while (1) { ret = drmDMA( fd, &dma ); @@ -237,13 +237,13 @@ void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ) } if (rmesa->radeon.do_usleeps) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); DO_USLEEP( 1 ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } } - UNLOCK_HARDWARE(rmesa); + UNLOCK_HARDWARE(&rmesa->radeon); if (R200_DEBUG & DEBUG_DMA) fprintf(stderr, "Allocated buffer %d\n", index); @@ -393,9 +393,9 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) ; } else { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); r200WaitIrq( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } rmesa->radeon.irqsEmitted = 10; } @@ -407,10 +407,10 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) } else { while (r200GetLastFrame (rmesa) < sarea->last_frame) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (rmesa->radeon.do_usleeps) DO_USLEEP( 1 ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } } } @@ -440,7 +440,7 @@ void r200CopyBuffer( __DRIdrawablePrivate *dPriv, R200_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* Throttle the frame rate -- only allow one pending swap buffers @@ -449,9 +449,9 @@ void r200CopyBuffer( __DRIdrawablePrivate *dPriv, r200WaitForFrameCompletion( rmesa ); if (!rect) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); driWaitForVBlank( dPriv, & missed_target ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } nbox = dPriv->numClipRects; /* must be in locked region */ @@ -493,12 +493,12 @@ void r200CopyBuffer( __DRIdrawablePrivate *dPriv, if ( ret ) { fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); exit( 1 ); } } - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (!rect) { rmesa->hw.all_dirty = GL_TRUE; @@ -535,10 +535,10 @@ void r200PageFlip( __DRIdrawablePrivate *dPriv ) } R200_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); if (!dPriv->numClipRects) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); usleep( 10000 ); /* throttle invisible client 10ms */ return; } @@ -556,17 +556,17 @@ void r200PageFlip( __DRIdrawablePrivate *dPriv ) * request at a time. */ r200WaitForFrameCompletion( rmesa ); - UNLOCK_HARDWARE( 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 ); + LOCK_HARDWARE( &rmesa->radeon ); ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_FLIP ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if ( ret ) { fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); @@ -622,8 +622,8 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) } { - LOCK_HARDWARE( rmesa ); - UNLOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); + UNLOCK_HARDWARE( &rmesa->radeon ); if ( dPriv->numClipRects == 0 ) return; } @@ -647,7 +647,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) mask &= ~BUFFER_BIT_DEPTH; } - if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) { + if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) { flags |= RADEON_STENCIL; mask &= ~BUFFER_BIT_STENCIL; } @@ -665,14 +665,14 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) flags |= RADEON_USE_COMP_ZBUF; /* if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) flags |= RADEON_USE_HIERZ; */ - if (!(rmesa->state.stencil.hwBuffer) || + if (!(rmesa->radeon.state.stencil.hwBuffer) || ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && - ((rmesa->state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) { + ((rmesa->radeon.state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) { flags |= RADEON_CLEAR_FASTZ; } } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* compute region after locking: */ cx = ctx->DrawBuffer->_Xmin; @@ -708,9 +708,9 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) } if (rmesa->radeon.do_usleeps) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); DO_USLEEP( 1 ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } } @@ -758,10 +758,10 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) rmesa->radeon.sarea->nbox = n; clear.flags = flags; - clear.clear_color = rmesa->state.color.clear; - clear.clear_depth = rmesa->state.depth.clear; /* needed for hyperz */ + clear.clear_color = rmesa->radeon.state.color.clear; + clear.clear_depth = rmesa->radeon.state.depth.clear; /* needed for hyperz */ clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; - clear.depth_mask = rmesa->state.stencil.clear; + clear.depth_mask = rmesa->radeon.state.stencil.clear; clear.depth_boxes = depth_boxes; n--; @@ -779,13 +779,13 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) if ( ret ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); exit( 1 ); } } - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); rmesa->hw.all_dirty = GL_TRUE; } @@ -802,7 +802,7 @@ void r200WaitForIdleLocked( r200ContextPtr rmesa ) } while (ret && ++i < 100); if ( ret < 0 ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); fprintf( stderr, "Error: R200 timed out... exiting\n" ); exit( -1 ); } @@ -811,9 +811,9 @@ void r200WaitForIdleLocked( r200ContextPtr rmesa ) static void r200WaitForIdle( r200ContextPtr rmesa ) { - LOCK_HARDWARE(rmesa); + LOCK_HARDWARE(&rmesa->radeon); r200WaitForIdleLocked( rmesa ); - UNLOCK_HARDWARE(rmesa); + UNLOCK_HARDWARE(&rmesa->radeon); } @@ -842,9 +842,9 @@ void r200Finish( GLcontext *ctx ) r200Flush( ctx ); if (rmesa->radeon.do_irqs) { - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); r200EmitIrqLocked( rmesa ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); r200WaitIrq( rmesa ); } else diff --git a/src/mesa/drivers/dri/r200/r200_lock.h b/src/mesa/drivers/dri/r200/r200_lock.h index f1cb624d8f..29cad5b226 100644 --- a/src/mesa/drivers/dri/r200/r200_lock.h +++ b/src/mesa/drivers/dri/r200/r200_lock.h @@ -35,72 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __R200_LOCK_H__ #define __R200_LOCK_H__ -extern void r200GetLock( r200ContextPtr rmesa, GLuint flags ); - -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( prevLockFile ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - exit( 1 ); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ - - -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - DRM_CAS( rmesa->radeon.dri.hwLock, rmesa->radeon.dri.hwContext, \ - (DRM_LOCK_HELD | rmesa->radeon.dri.hwContext), __ret ); \ - if ( __ret ) \ - r200GetLock( rmesa, 0 ); \ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - DRM_UNLOCK( rmesa->radeon.dri.fd, \ - rmesa->radeon.dri.hwLock, \ - rmesa->radeon.dri.hwContext ); \ - DEBUG_RESET(); \ - } while (0) +#include "common_lock.h" #endif /* __R200_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c index 1b28a83d70..60d25825e9 100644 --- a/src/mesa/drivers/dri/r200/r200_pixel.c +++ b/src/mesa/drivers/dri/r200/r200_pixel.c @@ -197,14 +197,14 @@ r200TryReadPixels( GLcontext *ctx, * a full command buffer expects to be called unlocked. As a * workaround, immediately flush the buffer on aquiring the lock. */ - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); if (rmesa->store.cmd_used) r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height, &size)) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (R200_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s totally clipped -- nothing to do\n", __FUNCTION__); @@ -259,7 +259,7 @@ r200TryReadPixels( GLcontext *ctx, r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); } - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); r200Finish( ctx ); /* required by GL */ @@ -318,7 +318,7 @@ static void do_draw_pix( GLcontext *ctx, } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); if (rmesa->store.cmd_used) r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); @@ -328,7 +328,7 @@ static void do_draw_pix( GLcontext *ctx, if (!clip_pixelrect(ctx, ctx->DrawBuffer, &x, &y, &width, &height, &size)) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); return; } @@ -365,7 +365,7 @@ static void do_draw_pix( GLcontext *ctx, r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); r200WaitForIdleLocked( rmesa ); /* required by GL */ - UNLOCK_HARDWARE( rmesa ); + 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 361f0fde26..dfe587401d 100644 --- a/src/mesa/drivers/dri/r200/r200_span.c +++ b/src/mesa/drivers/dri/r200/r200_span.c @@ -242,7 +242,7 @@ static void r200SpanRenderStart( GLcontext *ctx ) r200ContextPtr rmesa = R200_CONTEXT( ctx ); R200_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); r200WaitForIdleLocked( rmesa ); /* Read & rewrite the first pixel in the frame buffer. This should @@ -269,7 +269,7 @@ static void r200SpanRenderFinish( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); _swrast_flush( ctx ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); } void r200InitSpanFuncs( GLcontext *ctx ) diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 4cd87bd1b9..67357fadfd 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -383,10 +383,10 @@ static void r200ClearDepth( GLcontext *ctx, GLclampd d ) switch ( format ) { case R200_DEPTH_FORMAT_16BIT_INT_Z: - rmesa->state.depth.clear = d * 0x0000ffff; + rmesa->radeon.state.depth.clear = d * 0x0000ffff; break; case R200_DEPTH_FORMAT_24BIT_INT_Z: - rmesa->state.depth.clear = d * 0x00ffffff; + rmesa->radeon.state.depth.clear = d * 0x00ffffff; break; } } @@ -527,83 +527,6 @@ static void r200Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) */ -static GLboolean intersect_rect( drm_clip_rect_t *out, - drm_clip_rect_t *a, - drm_clip_rect_t *b ) -{ - *out = *a; - if ( b->x1 > out->x1 ) out->x1 = b->x1; - if ( b->y1 > out->y1 ) out->y1 = b->y1; - if ( b->x2 < out->x2 ) out->x2 = b->x2; - if ( b->y2 < out->y2 ) out->y2 = b->y2; - if ( out->x1 >= out->x2 ) return GL_FALSE; - if ( out->y1 >= out->y2 ) return GL_FALSE; - return GL_TRUE; -} - - -void r200RecalcScissorRects( r200ContextPtr rmesa ) -{ - drm_clip_rect_t *out; - int i; - - /* Grow cliprect store? - */ - if (rmesa->state.scissor.numAllocedClipRects < rmesa->radeon.numClipRects) { - while (rmesa->state.scissor.numAllocedClipRects < rmesa->radeon.numClipRects) { - rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ - rmesa->state.scissor.numAllocedClipRects *= 2; - } - - if (rmesa->state.scissor.pClipRects) - FREE(rmesa->state.scissor.pClipRects); - - rmesa->state.scissor.pClipRects = - MALLOC( rmesa->state.scissor.numAllocedClipRects * - sizeof(drm_clip_rect_t) ); - - if ( rmesa->state.scissor.pClipRects == NULL ) { - rmesa->state.scissor.numAllocedClipRects = 0; - return; - } - } - - out = rmesa->state.scissor.pClipRects; - rmesa->state.scissor.numClipRects = 0; - - for ( i = 0 ; i < rmesa->radeon.numClipRects ; i++ ) { - if ( intersect_rect( out, - &rmesa->radeon.pClipRects[i], - &rmesa->state.scissor.rect ) ) { - rmesa->state.scissor.numClipRects++; - out++; - } - } -} - - -static void r200UpdateScissor( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if ( rmesa->radeon.dri.drawable ) { - __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; - - int x = ctx->Scissor.X; - int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; - int w = ctx->Scissor.X + ctx->Scissor.Width - 1; - int h = dPriv->h - ctx->Scissor.Y - 1; - - rmesa->state.scissor.rect.x1 = x + dPriv->x; - rmesa->state.scissor.rect.y1 = y + dPriv->y; - rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; - rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - - r200RecalcScissorRects( rmesa ); - } -} - - static void r200Scissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { @@ -611,7 +534,7 @@ static void r200Scissor( GLcontext *ctx, if ( ctx->Scissor.Enabled ) { R200_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ - r200UpdateScissor( ctx ); + radeonUpdateScissor( ctx ); } } @@ -834,7 +757,7 @@ static void r200PolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); - float_ui32_type constant = { units * rmesa->state.depth.scale }; + float_ui32_type constant = { units * rmesa->radeon.state.depth.scale }; float_ui32_type factoru = { factor }; /* factor *= 2; */ @@ -862,14 +785,14 @@ static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask ) /* TODO: push this into cmd mechanism */ R200_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* FIXME: Use window x,y offsets into stipple RAM. */ stipple.mask = rmesa->state.stipple.mask; drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE, &stipple, sizeof(stipple) ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); } static void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) @@ -1675,7 +1598,7 @@ static void r200ClearStencil( GLcontext *ctx, GLint s ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); - rmesa->state.stencil.clear = + rmesa->radeon.state.stencil.clear = ((GLuint) (ctx->Stencil.Clear & 0xff) | (0xff << R200_STENCIL_MASK_SHIFT) | ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT)); @@ -1709,8 +1632,8 @@ void r200UpdateWindow( GLcontext *ctx ) float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; float_ui32_type sy = { - v[MAT_SY] }; float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y }; - float_ui32_type sz = { v[MAT_SZ] * rmesa->state.depth.scale }; - float_ui32_type tz = { v[MAT_TZ] * rmesa->state.depth.scale }; + float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale }; + float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale }; R200_FIREVERTICES( rmesa ); R200_STATECHANGE( rmesa, vpt ); @@ -1805,7 +1728,7 @@ static void r200ClearColor( GLcontext *ctx, const GLfloat c[4] ) CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]); CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]); CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]); - rmesa->state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, color[0], color[1], color[2], color[3] ); } @@ -1849,56 +1772,6 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode ) } -/* - * Set up the cliprects for either front or back-buffer drawing. - */ -void r200SetCliprects( r200ContextPtr rmesa ) -{ - __DRIdrawablePrivate *const drawable = rmesa->radeon.dri.drawable; - __DRIdrawablePrivate *const readable = rmesa->radeon.dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; - - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BIT_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. - */ - if ( drawable->numBackClipRects == 0 || rmesa->radeon.doPageFlip ) { - rmesa->radeon.numClipRects = drawable->numClipRects; - rmesa->radeon.pClipRects = drawable->pClipRects; - } - else { - rmesa->radeon.numClipRects = drawable->numBackClipRects; - rmesa->radeon.pClipRects = drawable->pBackClipRects; - } - } - else { - /* front buffer (or none, or multiple buffers) */ - rmesa->radeon.numClipRects = drawable->numClipRects; - rmesa->radeon.pClipRects = drawable->pClipRects; - } - - if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(rmesa->radeon.glCtx, draw_fb, - drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; - } - - if (drawable != readable) { - if ((read_fb->Width != readable->w) || - (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(rmesa->radeon.glCtx, read_fb, - readable->w, readable->h); - read_fb->Initialized = GL_TRUE; - } - } - - if (rmesa->state.scissor.enabled) - r200RecalcScissorRects( rmesa ); - - rmesa->radeon.lastStamp = drawable->lastStamp; -} - - static void r200DrawBuffer( GLcontext *ctx, GLenum mode ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -1925,7 +1798,7 @@ static void r200DrawBuffer( GLcontext *ctx, GLenum mode ) return; } - r200SetCliprects( rmesa ); + radeonSetCliprects( &rmesa->radeon ); /* We'll set the drawing engine's offset/pitch parameters later * when we update other state. @@ -2013,10 +1886,10 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) R200_STATECHANGE(rmesa, ctx ); if ( state ) { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE; - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->state.color.roundEnable; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable; } else { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE; - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; } break; @@ -2182,12 +2055,12 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_SCISSOR_TEST: R200_FIREVERTICES( rmesa ); - rmesa->state.scissor.enabled = state; + rmesa->radeon.state.scissor.enabled = state; r200UpdateScissor( ctx ); break; case GL_STENCIL_TEST: - if ( rmesa->state.stencil.hwBuffer ) { + if ( rmesa->radeon.state.stencil.hwBuffer ) { R200_STATECHANGE( rmesa, ctx ); if ( state ) { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_STENCIL_ENABLE; diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index f03a47ef46..775ccb7482 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -203,20 +203,20 @@ void r200InitState( r200ContextPtr rmesa ) exit( -1 ); } - rmesa->state.color.clear = 0x00000000; + rmesa->radeon.state.color.clear = 0x00000000; switch ( ctx->Visual.depthBits ) { case 16: - rmesa->state.depth.clear = 0x0000ffff; - rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; + rmesa->radeon.state.depth.clear = 0x0000ffff; + rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff; depth_fmt = R200_DEPTH_FORMAT_16BIT_INT_Z; - rmesa->state.stencil.clear = 0x00000000; + rmesa->radeon.state.stencil.clear = 0x00000000; break; case 24: - rmesa->state.depth.clear = 0x00ffffff; - rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; + rmesa->radeon.state.depth.clear = 0x00ffffff; + rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff; depth_fmt = R200_DEPTH_FORMAT_24BIT_INT_Z; - rmesa->state.stencil.clear = 0xffff0000; + rmesa->radeon.state.stencil.clear = 0xffff0000; break; default: fprintf( stderr, "Error: Unsupported depth %d... exiting\n", @@ -225,7 +225,7 @@ void r200InitState( r200ContextPtr rmesa ) } /* Only have hw stencil when depth buffer is 24 bits deep */ - rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && + rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ); rmesa->radeon.Fallback = 0; @@ -239,15 +239,15 @@ void r200InitState( r200ContextPtr rmesa ) } #if 000 if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { - rmesa->state.color.drawOffset = rmesa->radeon.radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeon.radeonScreen->backPitch; + rmesa->radeon.state.color.drawOffset = rmesa->radeon.radeonScreen->backOffset; + rmesa->radeon.state.color.drawPitch = rmesa->radeon.radeonScreen->backPitch; } else { - rmesa->state.color.drawOffset = rmesa->radeon.radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeon.radeonScreen->frontPitch; + rmesa->radeon.state.color.drawOffset = rmesa->radeon.radeonScreen->frontOffset; + rmesa->radeon.state.color.drawPitch = rmesa->radeon.radeonScreen->frontPitch; } - rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; - rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; + rmesa->state.pixel.readOffset = rmesa->radeon.state.color.drawOffset; + rmesa->state.pixel.readPitch = rmesa->radeon.state.color.drawPitch; #endif rmesa->hw.max_state_size = 0; @@ -617,21 +617,21 @@ void r200InitState( r200ContextPtr rmesa ) } if ( driQueryOptioni( &rmesa->radeon.optionCache, "round_mode" ) == DRI_CONF_ROUND_ROUND ) - rmesa->state.color.roundEnable = R200_ROUND_ENABLE; + rmesa->radeon.state.color.roundEnable = R200_ROUND_ENABLE; else - rmesa->state.color.roundEnable = 0; + rmesa->radeon.state.color.roundEnable = 0; if ( driQueryOptioni (&rmesa->radeon.optionCache, "color_reduction" ) == DRI_CONF_COLOR_REDUCTION_DITHER ) rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_DITHER_ENABLE; else - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; #if 000 - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset + + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->radeon.state.color.drawOffset + rmesa->radeon.radeonScreen->fbLocation) & R200_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->radeon.state.color.drawPitch & R200_COLORPITCH_MASK) | R200_COLOR_ENDIAN_NO_SWAP); #else diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index d5cba26ddd..1130c3544d 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -872,8 +872,8 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, /* Update window height */ - LOCK_HARDWARE( rmesa ); - UNLOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); + UNLOCK_HARDWARE( &rmesa->radeon ); h = rmesa->radeon.dri.drawable->h + rmesa->radeon.dri.drawable->y; px += rmesa->radeon.dri.drawable->x; diff --git a/src/mesa/drivers/dri/r200/r200_texmem.c b/src/mesa/drivers/dri/r200/r200_texmem.c index 93ae3260cc..e8b6876dd3 100644 --- a/src/mesa/drivers/dri/r200/r200_texmem.c +++ b/src/mesa/drivers/dri/r200/r200_texmem.c @@ -422,7 +422,7 @@ static void uploadSubImage( r200ContextPtr rmesa, radeonTexObjPtr t, } } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); do { ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE, &tex, sizeof(drm_radeon_texture_t) ); @@ -433,7 +433,7 @@ static void uploadSubImage( r200ContextPtr rmesa, radeonTexObjPtr t, } } while ( ret == -EAGAIN ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if ( ret ) { fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); @@ -476,7 +476,7 @@ int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face ) r200Finish( rmesa->radeon.glCtx ); } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); if ( t->base.memBlock == NULL ) { int heap; @@ -484,7 +484,7 @@ int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face ) heap = driAllocateTexture( rmesa->radeon.texture_heaps, rmesa->radeon.nr_heaps, (driTextureObject *) t ); if ( heap == -1 ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); return -1; } @@ -506,7 +506,7 @@ int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face ) /* Let the world know we've used this memory recently. */ driUpdateTextureLRU( (driTextureObject *) t ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); /* Upload any images that are new */ if (t->base.dirty_images[face]) { diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 7357cf74c9..18fab1d780 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -24,9 +24,10 @@ DRIVER_SOURCES = \ radeon_bo_legacy.c \ radeon_cs_legacy.c \ radeon_screen.c \ + common_lock.c \ + common_misc.c \ radeon_context.c \ radeon_ioctl.c \ - radeon_lock.c \ radeon_span.c \ radeon_state.c \ r300_context.c \ @@ -78,7 +79,11 @@ COMMON_SYMLINKS = \ radeon_cs_legacy.c \ radeon_bo_legacy.h \ radeon_cs_legacy.h \ - common_context.h + common_context.h \ + common_lock.c \ + common_lock.h \ + common_misc.c \ + common_misc.h DRI_LIB_DEPS += -ldrm_radeon diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index bd9d25d2f0..32d0dcf547 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -397,7 +397,7 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom) struct radeon_renderbuffer *rrb; uint32_t zbpitch; - rrb = r300->radeon.state.depth_buffer; + rrb = r300->radeon.state.depth.rrb; if (!rrb) return; diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 5fce8413bb..1958484b3c 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -187,6 +187,23 @@ static void r300RunPipeline(GLcontext * ctx) _mesa_unlock_context_textures(ctx); } +static void r300_get_lock(radeonContextPtr rmesa) +{ + drm_radeon_sarea_t *sarea = rmesa->sarea; + + if (sarea->ctx_owner != rmesa->dri.hwContext) { + sarea->ctx_owner = rmesa->dri.hwContext; + if (!rmesa->radeonScreen->kernel_mm) + radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom); + } +} + +static void r300_init_vtbl(radeonContextPtr radeon) +{ + radeon->vtbl.get_lock = r300_get_lock; + radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; +} + /* Create the device specific rendering context. */ GLboolean r300CreateContext(const __GLcontextModes * glVisual, @@ -212,6 +229,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, if (!(screen->chip_flags & RADEON_CHIPSET_TCL)) hw_tcl_on = future_hw_tcl_on = 0; + r300_init_vtbl(&r300->radeon); /* Parse configuration files. * Do this here so that initialMaxAnisotropy is set before we create * the default textures. diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index e631e81007..de188c3f36 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -522,14 +522,6 @@ struct r300_cmdbuf { * State cache */ -struct r300_depthbuffer_state { - GLfloat scale; -}; - -struct r300_stencilbuffer_state { - GLboolean hw_stencil; -}; - /* Vertex shader state */ /* Perhaps more if we store programs in vmem? */ @@ -773,7 +765,6 @@ struct r300_aos { }; struct r300_state { - struct r300_depthbuffer_state depth; struct r300_texture_state texture; int sw_tcl_inputs[VERT_ATTRIB_MAX]; struct r300_vertex_shader_state vertex_shader; @@ -786,8 +777,6 @@ struct r300_state { DECLARE_RENDERINPUTS(render_inputs_bitset); /* actual render inputs that R300 was configured for. They are the same as tnl->render_inputs for fixed pipeline */ - struct r300_stencilbuffer_state stencil; - }; #define R300_FALLBACK_NONE 0 diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 064732d458..e70e5f6d52 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -576,7 +576,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) mask &= ~BUFFER_BIT_DEPTH; } - if ((mask & BUFFER_BIT_STENCIL) && r300->state.stencil.hw_stencil) { + if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) { bits |= CLEARBUFFER_STENCIL; mask &= ~BUFFER_BIT_STENCIL; } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c79e69ae04..d98b83c506 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -591,7 +591,7 @@ static void r300SetStencilState(GLcontext * ctx, GLboolean state) { r300ContextPtr r300 = R300_CONTEXT(ctx); - if (r300->state.stencil.hw_stencil) { + if (r300->radeon.state.stencil.hwBuffer) { R300_STATECHANGE(r300, zs); if (state) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= @@ -1084,8 +1084,8 @@ static void r300UpdateWindow(GLcontext * ctx) GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; GLfloat sy = -v[MAT_SY]; GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y; - GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale; - GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale; + GLfloat sz = v[MAT_SZ] * rmesa->radeon.state.depth.scale; + GLfloat tz = v[MAT_TZ] * rmesa->radeon.state.depth.scale; R300_FIREVERTICES(rmesa); R300_STATECHANGE(rmesa, vpt); @@ -2361,7 +2361,7 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000; r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff; - rrb = r300->radeon.state.depth_buffer; + rrb = r300->radeon.state.depth.rrb; if (rrb && rrb->bo && (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)) { /* XXX: Turn off when clearing buffers ? */ r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; @@ -2694,11 +2694,11 @@ void r300InitState(r300ContextPtr r300) switch (ctx->Visual.depthBits) { case 16: - r300->state.depth.scale = 1.0 / (GLfloat) 0xffff; + r300->radeon.state.depth.scale = 1.0 / (GLfloat) 0xffff; depth_fmt = R300_DEPTHFORMAT_16BIT_INT_Z; break; case 24: - r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff; + r300->radeon.state.depth.scale = 1.0 / (GLfloat) 0xffffff; depth_fmt = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; break; default: @@ -2708,8 +2708,8 @@ void r300InitState(r300ContextPtr r300) } /* Only have hw stencil when depth buffer is 24 bits deep */ - r300->state.stencil.hw_stencil = (ctx->Visual.stencilBits > 0 && - ctx->Visual.depthBits == 24); + r300->radeon.state.stencil.hwBuffer = (ctx->Visual.stencilBits > 0 && + ctx->Visual.depthBits == 24); memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index 2bb679b479..092562b8f9 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -554,7 +554,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, radeon_update_renderbuffers(driContextPriv, driReadPriv); radeon->state.color.rrb = (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - radeon->state.depth_buffer = + radeon->state.depth.rrb = (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; } diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 7dfc3b3b91..d46a2d20ff 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -51,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" #include "common_context.h" +#include "common_misc.h" #if R200_MERGED extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode); diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 14d489bf1a..0ee5313043 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -56,83 +56,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Scissoring */ -static GLboolean intersect_rect(drm_clip_rect_t * out, - drm_clip_rect_t * a, drm_clip_rect_t * b) -{ - *out = *a; - if (b->x1 > out->x1) - out->x1 = b->x1; - if (b->y1 > out->y1) - out->y1 = b->y1; - if (b->x2 < out->x2) - out->x2 = b->x2; - if (b->y2 < out->y2) - out->y2 = b->y2; - if (out->x1 >= out->x2) - return GL_FALSE; - if (out->y1 >= out->y2) - return GL_FALSE; - return GL_TRUE; -} - -void radeonRecalcScissorRects(radeonContextPtr radeon) -{ - drm_clip_rect_t *out; - int i; - - /* Grow cliprect store? - */ - if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { - while (radeon->state.scissor.numAllocedClipRects < - radeon->numClipRects) { - radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ - radeon->state.scissor.numAllocedClipRects *= 2; - } - - if (radeon->state.scissor.pClipRects) - FREE(radeon->state.scissor.pClipRects); - - radeon->state.scissor.pClipRects = - MALLOC(radeon->state.scissor.numAllocedClipRects * - sizeof(drm_clip_rect_t)); - - if (radeon->state.scissor.pClipRects == NULL) { - radeon->state.scissor.numAllocedClipRects = 0; - return; - } - } - - out = radeon->state.scissor.pClipRects; - radeon->state.scissor.numClipRects = 0; - - for (i = 0; i < radeon->numClipRects; i++) { - if (intersect_rect(out, - &radeon->pClipRects[i], - &radeon->state.scissor.rect)) { - radeon->state.scissor.numClipRects++; - out++; - } - } -} - -void radeonUpdateScissor(GLcontext* ctx) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - - if (radeon->dri.drawable) { - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; - int x1 = dPriv->x + ctx->Scissor.X; - int y1 = dPriv->y + dPriv->h - (ctx->Scissor.Y + ctx->Scissor.Height); - - radeon->state.scissor.rect.x1 = x1; - radeon->state.scissor.rect.y1 = y1; - radeon->state.scissor.rect.x2 = x1 + ctx->Scissor.Width; - radeon->state.scissor.rect.y2 = y1 + ctx->Scissor.Height; - - radeonRecalcScissorRects(radeon); - } -} - static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) { if (ctx->Scissor.Enabled) { @@ -142,58 +65,6 @@ static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h } } - -/** - * Update cliprects and scissors. - */ -void radeonSetCliprects(radeonContextPtr radeon) -{ - __DRIdrawablePrivate *const drawable = radeon->dri.drawable; - __DRIdrawablePrivate *const readable = radeon->dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; - - if (!radeon->radeonScreen->driScreen->dri2.enabled) { - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. */ - if (drawable->numBackClipRects == 0 || radeon->doPageFlip || - radeon->sarea->pfCurrentPage == 1) { - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } else { - radeon->numClipRects = drawable->numBackClipRects; - radeon->pClipRects = drawable->pBackClipRects; - } - } else { - /* front buffer (or none, or multiple buffers */ - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } - } - - if ((draw_fb->Width != drawable->w) || - (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, draw_fb, - drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; - } - - if (drawable != readable) { - if ((read_fb->Width != readable->w) || - (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, read_fb, - readable->w, readable->h); - read_fb->Initialized = GL_TRUE; - } - } - - if (radeon->state.scissor.enabled) - radeonRecalcScissorRects(radeon); - - radeon->lastStamp = drawable->lastStamp; -} - - /** * Handle common enable bits. * Called as a fallback by r200Enable/r300Enable. diff --git a/src/mesa/drivers/dri/r300/radeon_state.h b/src/mesa/drivers/dri/r300/radeon_state.h index 821cb40c7e..279b108412 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.h +++ b/src/mesa/drivers/dri/r300/radeon_state.h @@ -31,10 +31,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __RADEON_STATE_H__ #define __RADEON_STATE_H__ -extern void radeonRecalcScissorRects(radeonContextPtr radeon); -extern void radeonSetCliprects(radeonContextPtr radeon); -extern void radeonUpdateScissor(GLcontext* ctx); - extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state); extern void radeonInitState(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index f223b2d922..50c27b81bc 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -11,7 +11,6 @@ MINIGLX_SOURCES = server/radeon_dri.c DRIVER_SOURCES = \ radeon_context.c \ radeon_ioctl.c \ - radeon_lock.c \ radeon_screen.c \ radeon_state.c \ radeon_state_init.c \ @@ -22,7 +21,9 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_span.c \ radeon_maos.c \ - radeon_sanity.c + radeon_sanity.c \ + common_lock.c \ + common_misc.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h index 5778adf9fb..723f7d14fd 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -249,10 +249,11 @@ typedef void (*radeon_line_func) (radeonContextPtr, typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); -struct r300_radeon_state { +struct radeon_state { struct radeon_colorbuffer_state color; + struct radeon_depthbuffer_state depth; struct radeon_scissor_state scissor; - struct radeon_renderbuffer *depth_buffer; + struct radeon_stencilbuffer_state stencil; }; struct radeon_context { @@ -301,12 +302,16 @@ struct radeon_context { GLuint swap_missed_count; /* Derived state - for r300 only */ - struct r300_radeon_state state; + struct radeon_state state; /* Configuration cache */ driOptionCache optionCache; + struct { + void (*get_lock)(radeonContextPtr radeon); + void (*update_viewport_offset)(GLcontext *ctx); + } vtbl; }; #define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/radeon/common_lock.c b/src/mesa/drivers/dri/radeon/common_lock.c new file mode 100644 index 0000000000..fe38fc95bc --- /dev/null +++ b/src/mesa/drivers/dri/radeon/common_lock.c @@ -0,0 +1,138 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Keith Whitwell + * Kevin E. Martin + */ + +#include "main/glheader.h" +#include "main/mtypes.h" +#include "main/colormac.h" +#include "dri_util.h" +#include "radeon_screen.h" +#include "common_context.h" +#include "common_lock.h" + +#include "drirenderbuffer.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + +#ifdef RADEON_COMMON_FOR_R300 +/* Turn on/off page flipping according to the flags in the sarea: + */ +void radeonUpdatePageFlipping(radeonContextPtr rmesa) +{ + int use_back; + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + GLframebuffer *fb = drawable->driverPrivate; + + rmesa->doPageFlip = rmesa->sarea->pfState; + if (rmesa->glCtx->WinSysDrawBuffer) { + r300UpdateDrawBuffer(rmesa->glCtx); + } + + use_back = rmesa->glCtx->DrawBuffer ? + (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == + BUFFER_BACK_LEFT) : 1; + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if (use_back) + rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + else + rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + + rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; +} +#else +/* Turn on/off page flipping according to the flags in the sarea: + */ +static void radeonUpdatePageFlipping(radeonContextPtr rmesa) +{ + rmesa->doPageFlip = rmesa->sarea->pfState; + if (rmesa->glCtx->WinSysDrawBuffer) { + driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, + rmesa->sarea->pfCurrentPage); + } +} +#endif + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void radeonGetLock(radeonContextPtr rmesa, GLuint flags) +{ + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + __DRIscreenPrivate *sPriv = rmesa->dri.screen; + drm_radeon_sarea_t *sarea = rmesa->sarea; + + assert(drawable != NULL); + + drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); + } + + if (rmesa->lastStamp != drawable->lastStamp) { + radeonUpdatePageFlipping(rmesa); + radeonSetCliprects(rmesa); + rmesa->vtbl.update_viewport_offset(rmesa->glCtx); + driUpdateFramebufferSize(rmesa->glCtx, drawable); + } + + rmesa->vtbl.get_lock(rmesa); + + rmesa->lost_context = GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/common_lock.h b/src/mesa/drivers/dri/radeon/common_lock.h new file mode 100644 index 0000000000..50a4a0b05a --- /dev/null +++ b/src/mesa/drivers/dri/radeon/common_lock.h @@ -0,0 +1,111 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Keith Whitwell + * Kevin E. Martin + */ + +#ifndef COMMON_LOCK_H +#define COMMON_LOCK_H +extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); + +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 + +#if DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if ( prevLockFile ) { \ + fprintf( stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ + exit( 1 ); \ + } \ + } while (0) + +#else + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + +#endif + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( rmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ + (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( (rmesa), 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +#define UNLOCK_HARDWARE( rmesa ) \ + do { \ + DRM_UNLOCK( (rmesa)->dri.fd, \ + (rmesa)->dri.hwLock, \ + (rmesa)->dri.hwContext ); \ + DEBUG_RESET(); \ + } while (0) + +#endif diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c new file mode 100644 index 0000000000..3bfb61a084 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/common_misc.c @@ -0,0 +1,187 @@ +/************************************************************************** + +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + */ + +#include "main/glheader.h" +#include "main/imports.h" +#include "main/api_arrayelt.h" +#include "main/enums.h" +#include "main/colormac.h" +#include "main/light.h" +#include "main/framebuffer.h" + +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" + +#include "dri_util.h" +#include "radeon_drm.h" +#include "radeon_screen.h" +#include "common_context.h" +#include "common_misc.h" +/* ============================================================= + * Scissoring + */ + +static GLboolean intersect_rect(drm_clip_rect_t * out, + drm_clip_rect_t * a, drm_clip_rect_t * b) +{ + *out = *a; + if (b->x1 > out->x1) + out->x1 = b->x1; + if (b->y1 > out->y1) + out->y1 = b->y1; + if (b->x2 < out->x2) + out->x2 = b->x2; + if (b->y2 < out->y2) + out->y2 = b->y2; + if (out->x1 >= out->x2) + return GL_FALSE; + if (out->y1 >= out->y2) + return GL_FALSE; + return GL_TRUE; +} + +void radeonRecalcScissorRects(radeonContextPtr radeon) +{ + drm_clip_rect_t *out; + int i; + + /* Grow cliprect store? + */ + if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { + while (radeon->state.scissor.numAllocedClipRects < + radeon->numClipRects) { + radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ + radeon->state.scissor.numAllocedClipRects *= 2; + } + + if (radeon->state.scissor.pClipRects) + FREE(radeon->state.scissor.pClipRects); + + radeon->state.scissor.pClipRects = + MALLOC(radeon->state.scissor.numAllocedClipRects * + sizeof(drm_clip_rect_t)); + + if (radeon->state.scissor.pClipRects == NULL) { + radeon->state.scissor.numAllocedClipRects = 0; + return; + } + } + + out = radeon->state.scissor.pClipRects; + radeon->state.scissor.numClipRects = 0; + + for (i = 0; i < radeon->numClipRects; i++) { + if (intersect_rect(out, + &radeon->pClipRects[i], + &radeon->state.scissor.rect)) { + radeon->state.scissor.numClipRects++; + out++; + } + } +} + +/** + * Update cliprects and scissors. + */ +void radeonSetCliprects(radeonContextPtr radeon) +{ + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. */ + if (drawable->numBackClipRects == 0 || radeon->doPageFlip || + radeon->sarea->pfCurrentPage == 1) { + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } else { + radeon->numClipRects = drawable->numBackClipRects; + radeon->pClipRects = drawable->pBackClipRects; + } + } else { + /* front buffer (or none, or multiple buffers */ + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } + } + + if ((draw_fb->Width != drawable->w) || + (draw_fb->Height != drawable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + drawable->w, drawable->h); + draw_fb->Initialized = GL_TRUE; + } + + if (drawable != readable) { + if ((read_fb->Width != readable->w) || + (read_fb->Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, read_fb, + readable->w, readable->h); + read_fb->Initialized = GL_TRUE; + } + } + + if (radeon->state.scissor.enabled) + radeonRecalcScissorRects(radeon); + + radeon->lastStamp = drawable->lastStamp; +} + +void radeonUpdateScissor( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( rmesa->dri.drawable ) { + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + + int x = ctx->Scissor.X; + int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; + int w = ctx->Scissor.X + ctx->Scissor.Width - 1; + int h = dPriv->h - ctx->Scissor.Y - 1; + + rmesa->state.scissor.rect.x1 = x + dPriv->x; + rmesa->state.scissor.rect.y1 = y + dPriv->y; + rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; + rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; + + radeonRecalcScissorRects( rmesa ); + } +} diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h new file mode 100644 index 0000000000..5653ef3183 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/common_misc.h @@ -0,0 +1,8 @@ +#ifndef COMMON_MISC_H +#define COMMON_MISC_H + +void radeonRecalcScissorRects(radeonContextPtr radeon); +void radeonSetCliprects(radeonContextPtr radeon); +void radeonUpdateScissor( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e2b2323a65..e49be4b23b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -194,6 +194,35 @@ static const struct dri_debug_control debug_control[] = { NULL, 0 } }; +static void r100_get_lock(radeonContextPtr radeon) +{ + r100ContextPtr rmesa = (r100ContextPtr)radeon; + drm_radeon_sarea_t *sarea = radeon->sarea; + + RADEON_STATECHANGE(rmesa, ctx); + if (rmesa->radeon.sarea->tiling_enabled) { + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= + RADEON_COLOR_TILE_ENABLE; + } else { + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= + ~RADEON_COLOR_TILE_ENABLE; + } + + if (sarea->ctx_owner != rmesa->radeon.dri.hwContext) { + int i; + sarea->ctx_owner = rmesa->radeon.dri.hwContext; + + for (i = 0; i < rmesa->radeon.nr_heaps; i++) { + DRI_AGE_TEXTURES(rmesa->radeon.texture_heaps[i]); + } + } +} + +static void r100_init_vtbl(radeonContextPtr radeon) +{ + radeon->vtbl.get_lock = r100_get_lock; + radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset; +} /* Create the device specific context. */ @@ -219,6 +248,8 @@ radeonCreateContext( const __GLcontextModes *glVisual, if ( !rmesa ) return GL_FALSE; + r100_init_vtbl(&rmesa->radeon); + /* init exp fog table data */ radeonInitStaticFogData(); @@ -488,9 +519,9 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) _mesa_vector4f_free( &rmesa->tcl.ObjClean ); - if (rmesa->state.scissor.pClipRects) { - FREE(rmesa->state.scissor.pClipRects); - rmesa->state.scissor.pClipRects = NULL; + if (rmesa->radeon.state.scissor.pClipRects) { + FREE(rmesa->radeon.state.scissor.pClipRects); + rmesa->radeon.state.scissor.pClipRects = NULL; } if ( release_texture_heaps ) { diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index fb2b6eac76..0ca49cc078 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -54,6 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" #include "common_context.h" +#include "common_misc.h" struct r100_context; @@ -328,11 +329,7 @@ struct radeon_hw_state { }; -struct radeon_state { - struct radeon_colorbuffer_state color; - struct radeon_depthbuffer_state depth; - struct radeon_scissor_state scissor; - struct radeon_stencilbuffer_state stencil; +struct r100_state { struct radeon_stipple_state stipple; struct radeon_texture_state texture; }; @@ -423,7 +420,7 @@ struct r100_context { /* Driver and hardware state management */ struct radeon_hw_state hw; - struct radeon_state state; + struct r100_state state; /* Vertex buffers */ diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 5e2b986713..31f4778fab 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -557,10 +557,10 @@ static int radeonFlushCmdBufLocked( r100ContextPtr rmesa, if (RADEON_DEBUG & DEBUG_SANITY) { - if (rmesa->state.scissor.enabled) + if (rmesa->radeon.state.scissor.enabled) ret = radeonSanityCmdBuffer( rmesa, - rmesa->state.scissor.numClipRects, - rmesa->state.scissor.pClipRects); + rmesa->radeon.state.scissor.numClipRects, + rmesa->radeon.state.scissor.pClipRects); else ret = radeonSanityCmdBuffer( rmesa, rmesa->radeon.numClipRects, @@ -575,9 +575,9 @@ static int radeonFlushCmdBufLocked( r100ContextPtr rmesa, cmd.bufsz = rmesa->store.cmd_used; cmd.buf = rmesa->store.cmd_buf; - if (rmesa->state.scissor.enabled) { - cmd.nbox = rmesa->state.scissor.numClipRects; - cmd.boxes = rmesa->state.scissor.pClipRects; + if (rmesa->radeon.state.scissor.enabled) { + cmd.nbox = rmesa->radeon.state.scissor.numClipRects; + cmd.boxes = rmesa->radeon.state.scissor.pClipRects; } else { cmd.nbox = rmesa->radeon.numClipRects; cmd.boxes = rmesa->radeon.pClipRects; @@ -614,11 +614,11 @@ void radeonFlushCmdBuf( r100ContextPtr rmesa, const char *caller ) int ret; - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); ret = radeonFlushCmdBufLocked( rmesa, caller ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (ret) { fprintf(stderr, "drm_radeon_cmd_buffer_t: %d (exiting)\n", ret); @@ -664,7 +664,7 @@ void radeonRefillCurrentDmaRegion( r100ContextPtr rmesa ) dma.request_sizes = &size; dma.granted_count = 0; - LOCK_HARDWARE(rmesa); /* no need to validate */ + LOCK_HARDWARE(&rmesa->radeon); /* no need to validate */ ret = drmDMA( fd, &dma ); @@ -682,13 +682,13 @@ void radeonRefillCurrentDmaRegion( r100ContextPtr rmesa ) ret = drmDMA( fd, &dma ); if ( ret != 0 ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); fprintf( stderr, "Error: Could not get dma buffer... exiting\n" ); exit( -1 ); } } - UNLOCK_HARDWARE(rmesa); + UNLOCK_HARDWARE(&rmesa->radeon); if (RADEON_DEBUG & DEBUG_DMA) fprintf(stderr, "Allocated buffer %d\n", index); @@ -839,9 +839,9 @@ static void radeonWaitForFrameCompletion( r100ContextPtr rmesa ) ; } else { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); radeonWaitIrq( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } rmesa->radeon.irqsEmitted = 10; } @@ -853,10 +853,10 @@ static void radeonWaitForFrameCompletion( r100ContextPtr rmesa ) } else { while (radeonGetLastFrame (rmesa) < sarea->last_frame) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (rmesa->radeon.do_usleeps) DO_USLEEP( 1 ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } } } @@ -883,7 +883,7 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, } RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* Throttle the frame rate -- only allow one pending swap buffers * request at a time. @@ -891,9 +891,9 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, radeonWaitForFrameCompletion( rmesa ); if (!rect) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); driWaitForVBlank( dPriv, & missed_target ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } nbox = dPriv->numClipRects; /* must be in locked region */ @@ -935,12 +935,12 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, if ( ret ) { fprintf( stderr, "DRM_RADEON_SWAP_BUFFERS: return = %d\n", ret ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); exit( 1 ); } } - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if (!rect) { psp = dPriv->driScreenPriv; @@ -976,7 +976,7 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv ) } RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* Need to do this for the perf box placement: */ @@ -992,17 +992,17 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv ) * request at a time. */ radeonWaitForFrameCompletion( rmesa ); - UNLOCK_HARDWARE( 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 ); + LOCK_HARDWARE( &rmesa->radeon ); ret = drmCommandNone( rmesa->radeon.dri.fd, DRM_RADEON_FLIP ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if ( ret ) { fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); @@ -1043,8 +1043,8 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) } { - LOCK_HARDWARE( rmesa ); - UNLOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); + UNLOCK_HARDWARE( &rmesa->radeon ); if ( dPriv->numClipRects == 0 ) return; } @@ -1068,7 +1068,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) mask &= ~BUFFER_BIT_DEPTH; } - if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) { + if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) { flags |= RADEON_STENCIL; mask &= ~BUFFER_BIT_STENCIL; } @@ -1086,14 +1086,14 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) flags |= RADEON_USE_COMP_ZBUF; /* if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) flags |= RADEON_USE_HIERZ; */ - if (!(rmesa->state.stencil.hwBuffer) || + if (!(rmesa->radeon.state.stencil.hwBuffer) || ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) && - ((rmesa->state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) { + ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) { flags |= RADEON_CLEAR_FASTZ; } } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* compute region after locking: */ cx = ctx->DrawBuffer->_Xmin; @@ -1126,9 +1126,9 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) } if ( rmesa->radeon.do_usleeps ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); DO_USLEEP( 1 ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); } } @@ -1176,10 +1176,10 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) rmesa->radeon.sarea->nbox = n; clear.flags = flags; - clear.clear_color = rmesa->state.color.clear; - clear.clear_depth = rmesa->state.depth.clear; + clear.clear_color = rmesa->radeon.state.color.clear; + clear.clear_depth = rmesa->radeon.state.depth.clear; clear.color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK]; - clear.depth_mask = rmesa->state.stencil.clear; + clear.depth_mask = rmesa->radeon.state.stencil.clear; clear.depth_boxes = depth_boxes; n--; @@ -1190,20 +1190,20 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2; depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2; depth_boxes[n].f[CLEAR_DEPTH] = - (float)rmesa->state.depth.clear; + (float)rmesa->radeon.state.depth.clear; } ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR, &clear, sizeof(drm_radeon_clear_t)); if ( ret ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret ); exit( 1 ); } } - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); rmesa->hw.all_dirty = GL_TRUE; } @@ -1223,7 +1223,7 @@ void radeonWaitForIdleLocked( r100ContextPtr rmesa ) } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); if ( ret < 0 ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); fprintf( stderr, "Error: Radeon timed out... exiting\n" ); exit( -1 ); } @@ -1232,9 +1232,9 @@ void radeonWaitForIdleLocked( r100ContextPtr rmesa ) static void radeonWaitForIdle( r100ContextPtr rmesa ) { - LOCK_HARDWARE(rmesa); + LOCK_HARDWARE(&rmesa->radeon); radeonWaitForIdleLocked( rmesa ); - UNLOCK_HARDWARE(rmesa); + UNLOCK_HARDWARE(&rmesa->radeon); } @@ -1263,9 +1263,9 @@ void radeonFinish( GLcontext *ctx ) radeonFlush( ctx ); if (rmesa->radeon.do_irqs) { - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); radeonEmitIrqLocked( rmesa ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); radeonWaitIrq( rmesa ); } else diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index e4bfa1b9d6..f2d17a54d4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -42,71 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __RADEON_LOCK_H__ #define __RADEON_LOCK_H__ -extern void radeonGetLock(r100ContextPtr rmesa, GLuint flags); - -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( prevLockFile ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - exit( 1 ); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ - -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - DRM_CAS( (rmesa)->radeon.dri.hwLock, (rmesa)->radeon.dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->radeon.dri.hwContext), __ret ); \ - if ( __ret ) \ - radeonGetLock( (rmesa), 0 ); \ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - DRM_UNLOCK( (rmesa)->radeon.dri.fd, \ - (rmesa)->radeon.dri.hwLock, \ - (rmesa)->radeon.dri.hwContext ); \ - DEBUG_RESET(); \ - } while (0) +#include "common_lock.h" #endif /* __RADEON_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 9733025fa9..423f3ca7e3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -282,19 +282,17 @@ static void radeonSpanRenderStart(GLcontext * ctx) #ifdef COMPILE_R300 r300ContextPtr r300 = (r300ContextPtr) rmesa; R300_FIREVERTICES(r300); - LOCK_HARDWARE(rmesa); #else r100ContextPtr r100 = (r100ContextPtr) rmesa; RADEON_FIREVERTICES(r100); - LOCK_HARDWARE(r100); #endif - + LOCK_HARDWARE(rmesa); radeonWaitForIdleLocked(rmesa); } static void radeonSpanRenderFinish(GLcontext * ctx) { - r100ContextPtr rmesa = R100_CONTEXT(ctx); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); _swrast_flush(ctx); UNLOCK_HARDWARE(rmesa); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 7e5306073f..67f861a48e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -311,10 +311,10 @@ static void radeonClearDepth( GLcontext *ctx, GLclampd d ) switch ( format ) { case RADEON_DEPTH_FORMAT_16BIT_INT_Z: - rmesa->state.depth.clear = d * 0x0000ffff; + rmesa->radeon.state.depth.clear = d * 0x0000ffff; break; case RADEON_DEPTH_FORMAT_24BIT_INT_Z: - rmesa->state.depth.clear = d * 0x00ffffff; + rmesa->radeon.state.depth.clear = d * 0x00ffffff; break; } } @@ -410,85 +410,6 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) /* ============================================================= * Scissoring */ - - -static GLboolean intersect_rect( drm_clip_rect_t *out, - drm_clip_rect_t *a, - drm_clip_rect_t *b ) -{ - *out = *a; - if ( b->x1 > out->x1 ) out->x1 = b->x1; - if ( b->y1 > out->y1 ) out->y1 = b->y1; - if ( b->x2 < out->x2 ) out->x2 = b->x2; - if ( b->y2 < out->y2 ) out->y2 = b->y2; - if ( out->x1 >= out->x2 ) return GL_FALSE; - if ( out->y1 >= out->y2 ) return GL_FALSE; - return GL_TRUE; -} - - -void radeonRecalcScissorRects( r100ContextPtr rmesa ) -{ - drm_clip_rect_t *out; - int i; - - /* Grow cliprect store? - */ - if (rmesa->state.scissor.numAllocedClipRects < rmesa->radeon.numClipRects) { - while (rmesa->state.scissor.numAllocedClipRects < rmesa->radeon.numClipRects) { - rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ - rmesa->state.scissor.numAllocedClipRects *= 2; - } - - if (rmesa->state.scissor.pClipRects) - FREE(rmesa->state.scissor.pClipRects); - - rmesa->state.scissor.pClipRects = - MALLOC( rmesa->state.scissor.numAllocedClipRects * - sizeof(drm_clip_rect_t) ); - - if ( rmesa->state.scissor.pClipRects == NULL ) { - rmesa->state.scissor.numAllocedClipRects = 0; - return; - } - } - - out = rmesa->state.scissor.pClipRects; - rmesa->state.scissor.numClipRects = 0; - - for ( i = 0 ; i < rmesa->radeon.numClipRects ; i++ ) { - if ( intersect_rect( out, - &rmesa->radeon.pClipRects[i], - &rmesa->state.scissor.rect ) ) { - rmesa->state.scissor.numClipRects++; - out++; - } - } -} - - -static void radeonUpdateScissor( GLcontext *ctx ) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - - if ( rmesa->radeon.dri.drawable ) { - __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; - - int x = ctx->Scissor.X; - int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; - int w = ctx->Scissor.X + ctx->Scissor.Width - 1; - int h = dPriv->h - ctx->Scissor.Y - 1; - - rmesa->state.scissor.rect.x1 = x + dPriv->x; - rmesa->state.scissor.rect.y1 = y + dPriv->y; - rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; - rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - - radeonRecalcScissorRects( rmesa ); - } -} - - static void radeonScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { @@ -624,7 +545,7 @@ static void radeonPolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - float_ui32_type constant = { units * rmesa->state.depth.scale }; + float_ui32_type constant = { units * rmesa->radeon.state.depth.scale }; float_ui32_type factoru = { factor }; RADEON_STATECHANGE( rmesa, zbs ); @@ -647,14 +568,14 @@ static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ) /* TODO: push this into cmd mechanism */ RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); /* FIXME: Use window x,y offsets into stipple RAM. */ stipple.mask = rmesa->state.stipple.mask; drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE, &stipple, sizeof(drm_radeon_stipple_t) ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); } static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ) @@ -1457,7 +1378,7 @@ static void radeonClearStencil( GLcontext *ctx, GLint s ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - rmesa->state.stencil.clear = + rmesa->radeon.state.stencil.clear = ((GLuint) (ctx->Stencil.Clear & 0xff) | (0xff << RADEON_STENCIL_MASK_SHIFT) | ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT)); @@ -1491,8 +1412,8 @@ void radeonUpdateWindow( GLcontext *ctx ) float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; float_ui32_type sy = { - v[MAT_SY] }; float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y }; - float_ui32_type sz = { v[MAT_SZ] * rmesa->state.depth.scale }; - float_ui32_type tz = { v[MAT_TZ] * rmesa->state.depth.scale }; + float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale }; + float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale }; RADEON_FIREVERTICES( rmesa ); RADEON_STATECHANGE( rmesa, vpt ); @@ -1586,7 +1507,7 @@ static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] ) CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); - rmesa->state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, c[0], c[1], c[2], c[3] ); } @@ -1629,55 +1550,6 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) } -/** - * Set up the cliprects for either front or back-buffer drawing. - */ -void radeonSetCliprects( r100ContextPtr rmesa ) -{ - __DRIdrawablePrivate *const drawable = rmesa->radeon.dri.drawable; - __DRIdrawablePrivate *const readable = rmesa->radeon.dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; - - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. - */ - if ( drawable->numBackClipRects == 0 || rmesa->radeon.doPageFlip ) { - rmesa->radeon.numClipRects = drawable->numClipRects; - rmesa->radeon.pClipRects = drawable->pClipRects; - } - else { - rmesa->radeon.numClipRects = drawable->numBackClipRects; - rmesa->radeon.pClipRects = drawable->pBackClipRects; - } - } - else { - /* front buffer (or none, or multiple buffers */ - rmesa->radeon.numClipRects = drawable->numClipRects; - rmesa->radeon.pClipRects = drawable->pClipRects; - } - - if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(rmesa->radeon.glCtx, draw_fb, - drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; - } - - if (drawable != readable) { - if ((read_fb->Width != readable->w) || (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(rmesa->radeon.glCtx, read_fb, - readable->w, readable->h); - read_fb->Initialized = GL_TRUE; - } - } - - if (rmesa->state.scissor.enabled) - radeonRecalcScissorRects( rmesa ); - - rmesa->radeon.lastStamp = drawable->lastStamp; -} - - /** * Called via glDrawBuffer. */ @@ -1707,7 +1579,7 @@ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) return; } - radeonSetCliprects( rmesa ); + radeonSetCliprects( &rmesa->radeon ); /* We'll set the drawing engine's offset/pitch parameters later * when we update other state. @@ -1821,10 +1693,10 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) RADEON_STATECHANGE(rmesa, ctx ); if ( state ) { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->state.color.roundEnable; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable; } else { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE; - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; } break; @@ -1972,12 +1844,12 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_SCISSOR_TEST: RADEON_FIREVERTICES( rmesa ); - rmesa->state.scissor.enabled = state; + rmesa->radeon.state.scissor.enabled = state; radeonUpdateScissor( ctx ); break; case GL_STENCIL_TEST: - if ( rmesa->state.stencil.hwBuffer ) { + if ( rmesa->radeon.state.stencil.hwBuffer ) { RADEON_STATECHANGE( rmesa, ctx ); if ( state ) { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h index 20b2d89001..17c2b11222 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.h +++ b/src/mesa/drivers/dri/radeon/radeon_state.h @@ -44,8 +44,6 @@ extern void radeonInitStateFuncs( GLcontext *ctx ); extern void radeonUpdateMaterial( GLcontext *ctx ); -extern void radeonSetCliprects( r100ContextPtr rmesa ); -extern void radeonRecalcScissorRects( r100ContextPtr rmesa ); extern void radeonUpdateViewportOffset( GLcontext *ctx ); extern void radeonUpdateWindow( GLcontext *ctx ); extern void radeonUpdateDrawBuffer( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index d5b83191b6..affa9313c9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -168,20 +168,20 @@ void radeonInitState( r100ContextPtr rmesa ) exit( -1 ); } - rmesa->state.color.clear = 0x00000000; + rmesa->radeon.state.color.clear = 0x00000000; switch ( ctx->Visual.depthBits ) { case 16: - rmesa->state.depth.clear = 0x0000ffff; - rmesa->state.depth.scale = 1.0 / (GLfloat)0xffff; + rmesa->radeon.state.depth.clear = 0x0000ffff; + rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff; depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; - rmesa->state.stencil.clear = 0x00000000; + rmesa->radeon.state.stencil.clear = 0x00000000; break; case 24: - rmesa->state.depth.clear = 0x00ffffff; - rmesa->state.depth.scale = 1.0 / (GLfloat)0xffffff; + rmesa->radeon.state.depth.clear = 0x00ffffff; + rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff; depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; - rmesa->state.stencil.clear = 0xffff0000; + rmesa->radeon.state.stencil.clear = 0xffff0000; break; default: fprintf( stderr, "Error: Unsupported depth %d... exiting\n", @@ -190,7 +190,7 @@ void radeonInitState( r100ContextPtr rmesa ) } /* Only have hw stencil when depth buffer is 24 bits deep */ - rmesa->state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && + rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ); rmesa->radeon.Fallback = 0; @@ -399,14 +399,14 @@ void radeonInitState( r100ContextPtr rmesa ) } if ( driQueryOptioni( &rmesa->radeon.optionCache, "round_mode" ) == DRI_CONF_ROUND_ROUND ) - rmesa->state.color.roundEnable = RADEON_ROUND_ENABLE; + rmesa->radeon.state.color.roundEnable = RADEON_ROUND_ENABLE; else - rmesa->state.color.roundEnable = 0; + rmesa->radeon.state.color.roundEnable = 0; if ( driQueryOptioni (&rmesa->radeon.optionCache, "color_reduction" ) == DRI_CONF_COLOR_REDUCTION_DITHER ) rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; else - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((drawOffset + rmesa->radeon.radeonScreen->fbLocation) diff --git a/src/mesa/drivers/dri/radeon/radeon_texmem.c b/src/mesa/drivers/dri/radeon/radeon_texmem.c index 77810ef7e1..0cf5badf4f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texmem.c +++ b/src/mesa/drivers/dri/radeon/radeon_texmem.c @@ -298,13 +298,13 @@ static void uploadSubImage( r100ContextPtr rmesa, radeonTexObjPtr t, } } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); do { ret = drmCommandWriteRead( rmesa->radeon.dri.fd, DRM_RADEON_TEXTURE, &tex, sizeof(drm_radeon_texture_t) ); } while ( ret == -EAGAIN ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); if ( ret ) { fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); @@ -349,7 +349,7 @@ int radeonUploadTexImages( r100ContextPtr rmesa, radeonTexObjPtr t, GLuint face radeonFinish( rmesa->radeon.glCtx ); } - LOCK_HARDWARE( rmesa ); + LOCK_HARDWARE( &rmesa->radeon ); if ( t->base.memBlock == NULL ) { int heap; @@ -357,7 +357,7 @@ int radeonUploadTexImages( r100ContextPtr rmesa, radeonTexObjPtr t, GLuint face heap = driAllocateTexture( rmesa->radeon.texture_heaps, rmesa->radeon.nr_heaps, (driTextureObject *) t ); if ( heap == -1 ) { - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); return -1; } @@ -380,7 +380,7 @@ int radeonUploadTexImages( r100ContextPtr rmesa, radeonTexObjPtr t, GLuint face /* Let the world know we've used this memory recently. */ driUpdateTextureLRU( (driTextureObject *) t ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( &rmesa->radeon ); /* Upload any images that are new */ -- cgit v1.2.3 From 23d3559bd4ece1fcab5513ebdaa38600d6654374 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Feb 2009 22:38:10 +1000 Subject: radeon: renaming and headers cleanup --- src/mesa/drivers/dri/radeon/Makefile | 17 +- src/mesa/drivers/dri/radeon/common_cmdbuf.h | 143 -- src/mesa/drivers/dri/radeon/common_context.h | 502 ---- src/mesa/drivers/dri/radeon/common_lock.c | 126 - src/mesa/drivers/dri/radeon/common_lock.h | 120 - src/mesa/drivers/dri/radeon/common_misc.c | 2715 -------------------- src/mesa/drivers/dri/radeon/common_misc.h | 166 -- src/mesa/drivers/dri/radeon/radeon_bo_legacy.c | 2 +- src/mesa/drivers/dri/radeon/radeon_cmdbuf.h | 143 ++ src/mesa/drivers/dri/radeon/radeon_common.c | 843 ++++++ src/mesa/drivers/dri/radeon/radeon_common.h | 56 + .../drivers/dri/radeon/radeon_common_context.c | 584 +++++ .../drivers/dri/radeon/radeon_common_context.h | 513 ++++ src/mesa/drivers/dri/radeon/radeon_context.c | 42 +- src/mesa/drivers/dri/radeon/radeon_context.h | 3 +- src/mesa/drivers/dri/radeon/radeon_cs_legacy.c | 4 +- src/mesa/drivers/dri/radeon/radeon_cs_legacy.h | 2 +- src/mesa/drivers/dri/radeon/radeon_dma.c | 323 +++ src/mesa/drivers/dri/radeon/radeon_dma.h | 51 + src/mesa/drivers/dri/radeon/radeon_ioctl.c | 2 +- src/mesa/drivers/dri/radeon/radeon_lock.c | 124 + src/mesa/drivers/dri/radeon/radeon_lock.h | 81 +- src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h | 2 +- src/mesa/drivers/dri/radeon/radeon_screen.c | 4 +- src/mesa/drivers/dri/radeon/radeon_span.c | 226 +- src/mesa/drivers/dri/radeon/radeon_state.c | 1 - src/mesa/drivers/dri/radeon/radeon_state_init.c | 1 - src/mesa/drivers/dri/radeon/radeon_swtcl.c | 1 - src/mesa/drivers/dri/radeon/radeon_tcl.c | 2 +- src/mesa/drivers/dri/radeon/radeon_texture.c | 849 ++++++ src/mesa/drivers/dri/radeon/radeon_texture.h | 108 + 31 files changed, 3916 insertions(+), 3840 deletions(-) delete mode 100644 src/mesa/drivers/dri/radeon/common_cmdbuf.h delete mode 100644 src/mesa/drivers/dri/radeon/common_context.h delete mode 100644 src/mesa/drivers/dri/radeon/common_lock.c delete mode 100644 src/mesa/drivers/dri/radeon/common_lock.h delete mode 100644 src/mesa/drivers/dri/radeon/common_misc.c delete mode 100644 src/mesa/drivers/dri/radeon/common_misc.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_cmdbuf.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_common.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_common.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_common_context.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_common_context.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_dma.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_dma.h create mode 100644 src/mesa/drivers/dri/radeon/radeon_lock.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_texture.c create mode 100644 src/mesa/drivers/dri/radeon/radeon_texture.h (limited to 'src/mesa/drivers/dri/radeon/radeon_lock.h') diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 2d00f521a6..16bc063baf 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -8,6 +8,16 @@ LIBNAME = radeon_dri.so MINIGLX_SOURCES = server/radeon_dri.c +RADEON_COMMON_SOURCES = \ + radeon_texture.c \ + radeon_common_context.c \ + radeon_dma.c \ + radeon_lock.c \ + radeon_bo_legacy.c \ + radeon_cs_legacy.c \ + radeon_mipmap_tree.c \ + radeon_span.c + DRIVER_SOURCES = \ radeon_context.c \ radeon_ioctl.c \ @@ -18,14 +28,9 @@ DRIVER_SOURCES = \ radeon_texstate.c \ radeon_tcl.c \ radeon_swtcl.c \ - radeon_span.c \ radeon_maos.c \ radeon_sanity.c \ - common_lock.c \ - common_misc.c \ - radeon_bo_legacy.c \ - radeon_cs_legacy.c \ - radeon_mipmap_tree.c + $(RADEON_COMMON_SOURCES) C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/radeon/common_cmdbuf.h b/src/mesa/drivers/dri/radeon/common_cmdbuf.h deleted file mode 100644 index 5526934209..0000000000 --- a/src/mesa/drivers/dri/radeon/common_cmdbuf.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef COMMON_CMDBUF_H -#define COMMON_CMDBUF_H - -#include "radeon_cs.h" - -void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); -int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); -int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); -void rcommonInitCmdBuf(radeonContextPtr rmesa); -void rcommonDestroyCmdBuf(radeonContextPtr rmesa); - -void rcommonBeginBatch(radeonContextPtr rmesa, - int n, - int dostate, - const char *file, - const char *function, - int line); - -#define RADEON_CP_PACKET3_NOP 0xC0001000 -#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 -#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 -#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 -#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 -#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 -#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 -#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 -#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 -#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 -#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 -#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 -#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 -#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 -#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 -#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 -#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 -#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 -#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 -#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 -#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 - -#define CP_PACKET2 (2 << 30) -#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) -#define CP_PACKET0_ONE(reg, n) (RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2)) -#define CP_PACKET3( pkt, n ) \ - (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) - -/** - * Every function writing to the command buffer needs to declare this - * to get the necessary local variables. - */ -#define BATCH_LOCALS(rmesa) \ - const radeonContextPtr b_l_rmesa = rmesa - -/** - * Prepare writing n dwords to the command buffer, - * including producing any necessary state emits on buffer wraparound. - */ -#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, 1, __FILE__, __FUNCTION__, __LINE__) - -/** - * Same as BEGIN_BATCH, but do not cause automatic state emits. - */ -#define BEGIN_BATCH_NO_AUTOSTATE(n) rcommonBeginBatch(b_l_rmesa, n, 0, __FILE__, __FUNCTION__, __LINE__) - -/** - * Write one dword to the command buffer. - */ -#define OUT_BATCH(data) \ - do { \ - radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\ - } while(0) - -/** - * Write a relocated dword to the command buffer. - */ -#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ - do { \ - if (0 && offset) { \ - fprintf(stderr, "(%s:%s:%d) offset : %d\n", \ - __FILE__, __FUNCTION__, __LINE__, offset); \ - } \ - radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \ - radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \ - bo, rd, wd, flags); \ - if (!b_l_rmesa->radeonScreen->kernel_mm) \ - b_l_rmesa->cmdbuf.cs->section_cdw += 2; \ - } while(0) - - -/** - * Write n dwords from ptr to the command buffer. - */ -#define OUT_BATCH_TABLE(ptr,n) \ - do { \ - int _i; \ - for (_i=0; _i < n; _i++) {\ - radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\ - }\ - } while(0) - -/** - * Finish writing dwords to the command buffer. - * The number of (direct or indirect) OUT_BATCH calls between the previous - * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. - */ -#define END_BATCH() \ - do { \ - radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ - } while(0) - -/** - * After the last END_BATCH() of rendering, this indicates that flushing - * the command buffer now is okay. - */ -#define COMMIT_BATCH() \ - do { \ - } while(0) - - -/** Single register write to command buffer; requires 2 dwords. */ -#define OUT_BATCH_REGVAL(reg, val) \ - OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \ - OUT_BATCH((val)) - -/** Continuous register range write to command buffer; requires 1 dword, - * expects count dwords afterwards for register contents. */ -#define OUT_BATCH_REGSEQ(reg, count) \ - OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count))); - -/** Write a 32 bit float to the ring; requires 1 dword. */ -#define OUT_BATCH_FLOAT32(f) \ - OUT_BATCH(radeonPackFloat32((f))); - - -/* Fire the buffered vertices no matter what. - */ -static INLINE void radeon_firevertices(radeonContextPtr radeon) -{ - if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) - radeonFlush(radeon->glCtx); -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h deleted file mode 100644 index c3a445e0d2..0000000000 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ /dev/null @@ -1,502 +0,0 @@ - -#ifndef COMMON_CONTEXT_H -#define COMMON_CONTEXT_H - -#include "main/mm.h" -#include "math/m_vector.h" -#include "texmem.h" -#include "tnl/t_context.h" -#include "main/colormac.h" - -#include "radeon_screen.h" -#include "radeon_drm.h" -#include "dri_util.h" -#include "tnl/t_vertex.h" - -/* This union is used to avoid warnings/miscompilation - with float to uint32_t casts due to strict-aliasing */ -typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; - -struct radeon_context; -typedef struct radeon_context radeonContextRec; -typedef struct radeon_context *radeonContextPtr; - - -#define TEX_0 0x1 -#define TEX_1 0x2 -#define TEX_2 0x4 -#define TEX_3 0x8 -#define TEX_4 0x10 -#define TEX_5 0x20 - -/* Rasterizing fallbacks */ -/* See correponding strings in r200_swtcl.c */ -#define RADEON_FALLBACK_TEXTURE 0x0001 -#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 -#define RADEON_FALLBACK_STENCIL 0x0004 -#define RADEON_FALLBACK_RENDER_MODE 0x0008 -#define RADEON_FALLBACK_BLEND_EQ 0x0010 -#define RADEON_FALLBACK_BLEND_FUNC 0x0020 -#define RADEON_FALLBACK_DISABLE 0x0040 -#define RADEON_FALLBACK_BORDER_MODE 0x0080 - -#define R200_FALLBACK_TEXTURE 0x01 -#define R200_FALLBACK_DRAW_BUFFER 0x02 -#define R200_FALLBACK_STENCIL 0x04 -#define R200_FALLBACK_RENDER_MODE 0x08 -#define R200_FALLBACK_DISABLE 0x10 -#define R200_FALLBACK_BORDER_MODE 0x20 - -#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ -#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ -#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ -#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ -#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ -#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ -#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ -#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ -#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */ - -/* The blit width for texture uploads - */ -#define BLIT_WIDTH_BYTES 1024 - -/* Use the templated vertex format: - */ -#define COLOR_IS_RGBA -#define TAG(x) radeon##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -struct radeon_colorbuffer_state { - GLuint clear; - int roundEnable; - struct radeon_renderbuffer *rrb; -}; - -struct radeon_depthbuffer_state { - GLuint clear; - GLfloat scale; - struct radeon_renderbuffer *rrb; -}; - -struct radeon_scissor_state { - drm_clip_rect_t rect; - GLboolean enabled; - - GLuint numClipRects; /* Cliprects active */ - GLuint numAllocedClipRects; /* Cliprects available */ - drm_clip_rect_t *pClipRects; -}; - -struct radeon_stencilbuffer_state { - GLboolean hwBuffer; - GLuint clear; /* rb3d_stencilrefmask value */ -}; - -struct radeon_stipple_state { - GLuint mask[32]; -}; - -struct radeon_state_atom { - struct radeon_state_atom *next, *prev; - const char *name; /* for debug */ - int cmd_size; /* size in bytes */ - GLuint idx; - GLuint is_tcl; - GLuint *cmd; /* one or more cmd's */ - GLuint *lastcmd; /* one or more cmd's */ - GLboolean dirty; /* dirty-mark in emit_state_list */ - int (*check) (GLcontext *, struct radeon_state_atom *atom); /* is this state active? */ - void (*emit) (GLcontext *, struct radeon_state_atom *atom); -}; - -struct radeon_hw_state { - /* Head of the linked list of state atoms. */ - struct radeon_state_atom atomlist; - int max_state_size; /* Number of bytes necessary for a full state emit. */ - GLboolean is_dirty, all_dirty; -}; - - -/* Texture related */ -typedef struct _radeon_texture_image radeon_texture_image; - -struct _radeon_texture_image { - struct gl_texture_image base; - - /** - * If mt != 0, the image is stored in hardware format in the - * given mipmap tree. In this case, base.Data may point into the - * mapping of the buffer object that contains the mipmap tree. - * - * If mt == 0, the image is stored in normal memory pointed to - * by base.Data. - */ - struct _radeon_mipmap_tree *mt; - struct radeon_bo *bo; - - int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ - int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ -}; - - -static INLINE radeon_texture_image *get_radeon_texture_image(struct gl_texture_image *image) -{ - return (radeon_texture_image*)image; -} - - -typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; - -#define RADEON_TXO_MICRO_TILE (1 << 3) - -/* Texture object in locally shared texture space. - */ -struct radeon_tex_obj { - // driTextureObject base; - struct gl_texture_object base; - struct _radeon_mipmap_tree *mt; - - /** - * This is true if we've verified that the mipmap tree above is complete - * and so on. - */ - GLboolean validated; - - GLuint override_offset; - GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ - GLuint tile_bits; /* hw texture tile bits used on this texture */ - struct radeon_bo *bo; - - GLuint bufAddr; /* Offset to start of locally - shared texture block */ - - GLuint dirty_state; /* Flags (1 per texunit) for - whether or not this texobj - has dirty hardware state - (pp_*) that needs to be - brought into the - texunit. */ - - drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; - /* Six, for the cube faces */ - - - - GLuint pp_txfilter; /* hardware register values */ - GLuint pp_txformat; - GLuint pp_txformat_x; - GLuint pp_txoffset; /* Image location in texmem. - All cube faces follow. */ - GLuint pp_txsize; /* npot only */ - GLuint pp_txpitch; /* npot only */ - GLuint pp_border_color; - GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ - - GLuint pp_txfilter_1; /* r300 */ - - GLboolean border_fallback; - - -}; - -static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) -{ - return (radeonTexObj*)texObj; -} - -/* Need refcounting on dma buffers: - */ -struct radeon_dma_buffer { - int refcount; /* the number of retained regions in buf */ - drmBufPtr buf; -}; - -struct radeon_aos { - struct radeon_bo *bo; /** Buffer object where vertex data is stored */ - int offset; /** Offset into buffer object, in bytes */ - int components; /** Number of components per vertex */ - int stride; /** Stride in dwords (may be 0 for repeating) */ - int count; /** Number of vertices */ -}; - -struct radeon_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ - struct radeon_bo *current; /** Buffer that DMA memory is allocated from */ - int current_used; /** Number of bytes allocated and forgotten about */ - int current_vertexptr; /** End of active vertex region */ - - /** - * If current_vertexptr != current_used then flush must be non-zero. - * flush must be called before non-active vertex allocations can be - * performed. - */ - void (*flush) (GLcontext *); - - /* Number of "in-flight" DMA buffers, i.e. the number of buffers - * for which a DISCARD command is currently queued in the command buffer -. - */ - GLuint nr_released_bufs; -}; - -/* radeon_swtcl.c - */ -struct radeon_swtcl_info { - - GLuint RenderIndex; - GLuint vertex_size; - GLubyte *verts; - - /* Fallback rasterization functions - */ - GLuint hw_primitive; - GLenum render_primitive; - GLuint numverts; - - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - GLuint vertex_attr_count; - -}; - -struct radeon_ioctl { - GLuint vertex_offset; - struct radeon_bo *bo; - GLuint vertex_size; -}; - -#define RADEON_MAX_PRIMS 64 - -struct radeon_prim { - GLuint start; - GLuint end; - GLuint prim; -}; - -static INLINE GLuint radeonPackColor(GLuint cpp, - GLubyte r, GLubyte g, - GLubyte b, GLubyte a) -{ - switch (cpp) { - case 2: - return PACK_COLOR_565(r, g, b); - case 4: - return PACK_COLOR_8888(a, r, g, b); - default: - return 0; - } -} - -#define MAX_CMD_BUF_SZ (16*1024) - -#define MAX_DMA_BUF_SZ (64*1024) - -struct radeon_store { - GLuint statenr; - GLuint primnr; - char cmd_buf[MAX_CMD_BUF_SZ]; - int cmd_used; - int elts_start; -}; - -struct radeon_dri_mirror { - __DRIcontextPrivate *context; /* DRI context */ - __DRIscreenPrivate *screen; /* DRI screen */ - - /** - * DRI drawable bound to this context for drawing. - */ - __DRIdrawablePrivate *drawable; - - /** - * DRI drawable bound to this context for reading. - */ - __DRIdrawablePrivate *readable; - - drm_context_t hwContext; - drm_hw_lock_t *hwLock; - int fd; - int drmMinor; -}; - -#define DEBUG_TEXTURE 0x001 -#define DEBUG_STATE 0x002 -#define DEBUG_IOCTL 0x004 -#define DEBUG_PRIMS 0x008 -#define DEBUG_VERTS 0x010 -#define DEBUG_FALLBACKS 0x020 -#define DEBUG_VFMT 0x040 -#define DEBUG_CODEGEN 0x080 -#define DEBUG_VERBOSE 0x100 -#define DEBUG_DRI 0x200 -#define DEBUG_DMA 0x400 -#define DEBUG_SANITY 0x800 -#define DEBUG_SYNC 0x1000 -#define DEBUG_PIXEL 0x2000 -#define DEBUG_MEMORY 0x4000 - - - -typedef void (*radeon_tri_func) (radeonContextPtr, - radeonVertex *, - radeonVertex *, radeonVertex *); - -typedef void (*radeon_line_func) (radeonContextPtr, - radeonVertex *, radeonVertex *); - -typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); - -struct radeon_state { - struct radeon_colorbuffer_state color; - struct radeon_depthbuffer_state depth; - struct radeon_scissor_state scissor; - struct radeon_stencilbuffer_state stencil; -}; - -/** - * This structure holds the command buffer while it is being constructed. - * - * The first batch of commands in the buffer is always the state that needs - * to be re-emitted when the context is lost. This batch can be skipped - * otherwise. - */ -struct radeon_cmdbuf { - struct radeon_cs_manager *csm; - struct radeon_cs *cs; - int size; /** # of dwords total */ - unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ -}; - -struct radeon_context { - GLcontext *glCtx; - radeonScreenPtr radeonScreen; /* Screen private DRI data */ - - /* Texture object bookkeeping - */ - unsigned nr_heaps; - driTexHeap * texture_heaps[ RADEON_NR_TEX_HEAPS ]; - driTextureObject swapped; - int texture_depth; - float initialMaxAnisotropy; - - struct radeon_dma dma; - struct radeon_hw_state hw; - /* Rasterization and vertex state: - */ - GLuint TclFallback; - GLuint Fallback; - GLuint NewGLState; - DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ - - /* Page flipping */ - GLuint doPageFlip; - - /* Drawable, cliprect and scissor information */ - GLuint numClipRects; /* Cliprects for the draw buffer */ - drm_clip_rect_t *pClipRects; - unsigned int lastStamp; - GLboolean lost_context; - drm_radeon_sarea_t *sarea; /* Private SAREA data */ - - /* Mirrors of some DRI state */ - struct radeon_dri_mirror dri; - - /* Busy waiting */ - GLuint do_usleeps; - GLuint do_irqs; - GLuint irqsEmitted; - drm_radeon_irq_wait_t iw; - - /* buffer swap */ - int64_t swap_ust; - int64_t swap_missed_ust; - - GLuint swap_count; - GLuint swap_missed_count; - - /* Derived state - for r300 only */ - struct radeon_state state; - - struct radeon_swtcl_info swtcl; - /* Configuration cache - */ - driOptionCache optionCache; - - struct radeon_cmdbuf cmdbuf; - - struct { - void (*get_lock)(radeonContextPtr radeon); - void (*update_viewport_offset)(GLcontext *ctx); - void (*update_draw_buffer)(GLcontext *ctx); - void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); - void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); - void (*pre_emit_atoms)(radeonContextPtr rmesa); - void (*pre_emit_state)(radeonContextPtr rmesa); - } vtbl; -}; - -#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) - -/** - * This function takes a float and packs it into a uint32_t - */ -static INLINE uint32_t radeonPackFloat32(float fl) -{ - union { - float fl; - uint32_t u; - } u; - - u.fl = fl; - return u.u; -} - -/* This is probably wrong for some values, I need to test this - * some more. Range checking would be a good idea also.. - * - * But it works for most things. I'll fix it later if someone - * else with a better clue doesn't - */ -static INLINE uint32_t radeonPackFloat24(float f) -{ - float mantissa; - int exponent; - uint32_t float24 = 0; - - if (f == 0.0) - return 0; - - mantissa = frexpf(f, &exponent); - - /* Handle -ve */ - if (mantissa < 0) { - float24 |= (1 << 23); - mantissa = mantissa * -1.0; - } - /* Handle exponent, bias of 63 */ - exponent += 62; - float24 |= (exponent << 16); - /* Kill 7 LSB of mantissa */ - float24 |= (radeonPackFloat32(mantissa) & 0x7FFFFF) >> 7; - - return float24; -} - -/* ================================================================ - * Debugging: - */ -#define DO_DEBUG 1 - -#if DO_DEBUG -extern int RADEON_DEBUG; -#else -#define RADEON_DEBUG 0 -#endif - -#include "common_misc.h" -#include "common_cmdbuf.h" -#endif diff --git a/src/mesa/drivers/dri/radeon/common_lock.c b/src/mesa/drivers/dri/radeon/common_lock.c deleted file mode 100644 index 91600ac4cd..0000000000 --- a/src/mesa/drivers/dri/radeon/common_lock.c +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - VA Linux Systems Inc., Fremont, California. -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Gareth Hughes - * Keith Whitwell - * Kevin E. Martin - */ - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/colormac.h" -#include "dri_util.h" -#include "radeon_screen.h" -#include "common_context.h" -#include "common_lock.h" -#include "common_misc.h" - -#include "drirenderbuffer.h" - -#if DEBUG_LOCKING -char *prevLockFile = NULL; -int prevLockLine = 0; -#endif - -/* Turn on/off page flipping according to the flags in the sarea: - */ -void radeonUpdatePageFlipping(radeonContextPtr rmesa) -{ - int use_back; - __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; - GLframebuffer *fb = drawable->driverPrivate; - - rmesa->doPageFlip = rmesa->sarea->pfState; - if (rmesa->glCtx->WinSysDrawBuffer) { - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); - } - - use_back = rmesa->glCtx->DrawBuffer ? - (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == - BUFFER_BACK_LEFT) : 1; - use_back ^= (rmesa->sarea->pfCurrentPage == 1); - - if (use_back) - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - else - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - - rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; -} - -/* Update the hardware state. This is called if another context has - * grabbed the hardware lock, which includes the X server. This - * function also updates the driver's window state after the X server - * moves, resizes or restacks a window -- the change will be reflected - * in the drawable position and clip rects. Since the X server grabs - * the hardware lock when it changes the window state, this routine will - * automatically be called after such a change. - */ -void radeonGetLock(radeonContextPtr rmesa, GLuint flags) -{ - __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; - __DRIdrawablePrivate *const readable = rmesa->dri.readable; - __DRIscreenPrivate *sPriv = rmesa->dri.screen; - drm_radeon_sarea_t *sarea = rmesa->sarea; - - assert(drawable != NULL); - - drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); - - /* The window might have moved, so we might need to get new clip - * rects. - * - * NOTE: This releases and regrabs the hw lock to allow the X server - * to respond to the DRI protocol request for new drawable info. - * Since the hardware state depends on having the latest drawable - * clip rects, all state checking must be done _after_ this call. - */ - DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); - if (drawable != readable) { - DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); - } - - if (rmesa->lastStamp != drawable->lastStamp) { - radeonUpdatePageFlipping(rmesa); - radeonSetCliprects(rmesa); - rmesa->vtbl.update_viewport_offset(rmesa->glCtx); - driUpdateFramebufferSize(rmesa->glCtx, drawable); - } - - rmesa->vtbl.get_lock(rmesa); - - rmesa->lost_context = GL_TRUE; -} diff --git a/src/mesa/drivers/dri/radeon/common_lock.h b/src/mesa/drivers/dri/radeon/common_lock.h deleted file mode 100644 index 431b076f02..0000000000 --- a/src/mesa/drivers/dri/radeon/common_lock.h +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - VA Linux Systems Inc., Fremont, California. -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Gareth Hughes - * Keith Whitwell - * Kevin E. Martin - */ - -#ifndef COMMON_LOCK_H -#define COMMON_LOCK_H - -#include "main/colormac.h" -#include "radeon_screen.h" -#include "common_context.h" - -extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); - -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( prevLockFile ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - exit( 1 ); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ - -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ - if ( __ret ) \ - radeonGetLock( (rmesa), 0 ); \ - } \ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_UNLOCK( (rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext ); \ - DEBUG_RESET(); \ - } \ - } while (0) - -#endif diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c deleted file mode 100644 index f0035e54cf..0000000000 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ /dev/null @@ -1,2715 +0,0 @@ -/************************************************************************** - -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell - */ - -#include -#include "main/glheader.h" -#include "main/imports.h" -#include "main/context.h" -#include "main/api_arrayelt.h" -#include "main/enums.h" -#include "main/colormac.h" -#include "main/light.h" -#include "main/framebuffer.h" -#include "main/simple_list.h" - -#include "swrast/swrast.h" -#include "vbo/vbo.h" -#include "tnl/tnl.h" -#include "tnl/t_pipeline.h" -#include "swrast_setup/swrast_setup.h" -#include "main/mipmap.h" -#include "main/texformat.h" -#include "main/texstore.h" -#include "main/teximage.h" -#include "main/texobj.h" - -#include "drirenderbuffer.h" -#include "vblank.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ - -#include "radeon_bo.h" -#include "radeon_cs.h" -#include "radeon_bo_legacy.h" -#include "radeon_cs_legacy.h" -#include "radeon_bo_gem.h" -#include "radeon_cs_gem.h" -#include "dri_util.h" -#include "radeon_drm.h" -#include "radeon_buffer.h" -#include "radeon_screen.h" -#include "common_context.h" -#include "common_misc.h" -#include "common_lock.h" -#include "common_cmdbuf.h" -#include "radeon_mipmap_tree.h" -#include "radeon_span.h" - -#define DRIVER_DATE "20090101" - -#ifndef RADEON_DEBUG -int RADEON_DEBUG = (0); -#endif - -#define DEBUG_CMDBUF 0 - -/* ============================================================= - * Scissoring - */ - -static GLboolean intersect_rect(drm_clip_rect_t * out, - drm_clip_rect_t * a, drm_clip_rect_t * b) -{ - *out = *a; - if (b->x1 > out->x1) - out->x1 = b->x1; - if (b->y1 > out->y1) - out->y1 = b->y1; - if (b->x2 < out->x2) - out->x2 = b->x2; - if (b->y2 < out->y2) - out->y2 = b->y2; - if (out->x1 >= out->x2) - return GL_FALSE; - if (out->y1 >= out->y2) - return GL_FALSE; - return GL_TRUE; -} - -void radeonRecalcScissorRects(radeonContextPtr radeon) -{ - drm_clip_rect_t *out; - int i; - - /* Grow cliprect store? - */ - if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { - while (radeon->state.scissor.numAllocedClipRects < - radeon->numClipRects) { - radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ - radeon->state.scissor.numAllocedClipRects *= 2; - } - - if (radeon->state.scissor.pClipRects) - FREE(radeon->state.scissor.pClipRects); - - radeon->state.scissor.pClipRects = - MALLOC(radeon->state.scissor.numAllocedClipRects * - sizeof(drm_clip_rect_t)); - - if (radeon->state.scissor.pClipRects == NULL) { - radeon->state.scissor.numAllocedClipRects = 0; - return; - } - } - - out = radeon->state.scissor.pClipRects; - radeon->state.scissor.numClipRects = 0; - - for (i = 0; i < radeon->numClipRects; i++) { - if (intersect_rect(out, - &radeon->pClipRects[i], - &radeon->state.scissor.rect)) { - radeon->state.scissor.numClipRects++; - out++; - } - } -} - -/** - * Update cliprects and scissors. - */ -void radeonSetCliprects(radeonContextPtr radeon) -{ - __DRIdrawablePrivate *const drawable = radeon->dri.drawable; - __DRIdrawablePrivate *const readable = radeon->dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; - - if (!radeon->radeonScreen->driScreen->dri2.enabled) { - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. */ - if (drawable->numBackClipRects == 0 || radeon->doPageFlip || - radeon->sarea->pfCurrentPage == 1) { - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } else { - radeon->numClipRects = drawable->numBackClipRects; - radeon->pClipRects = drawable->pBackClipRects; - } - } else { - /* front buffer (or none, or multiple buffers */ - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } - } - - if ((draw_fb->Width != drawable->w) || - (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, draw_fb, - drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; - } - - if (drawable != readable) { - if ((read_fb->Width != readable->w) || - (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, read_fb, - readable->w, readable->h); - read_fb->Initialized = GL_TRUE; - } - } - - if (radeon->state.scissor.enabled) - radeonRecalcScissorRects(radeon); - - radeon->lastStamp = drawable->lastStamp; -} - -void radeonUpdateScissor( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if ( rmesa->dri.drawable ) { - __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; - - int x = ctx->Scissor.X; - int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; - int w = ctx->Scissor.X + ctx->Scissor.Width - 1; - int h = dPriv->h - ctx->Scissor.Y - 1; - - rmesa->state.scissor.rect.x1 = x + dPriv->x; - rmesa->state.scissor.rect.y1 = y + dPriv->y; - rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; - rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - - radeonRecalcScissorRects( rmesa ); - } -} - -/* ============================================================= - * Scissoring - */ - -void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - if (ctx->Scissor.Enabled) { - /* We don't pipeline cliprect changes */ - radeon_firevertices(radeon); - radeonUpdateScissor(ctx); - } -} - - -/* ================================================================ - * 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) -{ - radeonContextPtr rmesa; - GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp; - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - - if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); - } - - radeon_firevertices(rmesa); - 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->hw.all_dirty = GL_TRUE; - - } -} - -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 ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - rmesa->sarea->pfCurrentPage); - } - - radeon_firevertices(rmesa); - - 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); -} - -void radeonFlush(GLcontext *ctx) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (radeon->dma.flush) - radeon->dma.flush( ctx ); - - radeonEmitState(radeon); - - if (radeon->cmdbuf.cs->cdw) - rcommonFlushCmdBuf(radeon, __FUNCTION__); -} - -static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) -{ - BATCH_LOCALS(radeon); - struct radeon_state_atom *atom; - int dwords; - - if (radeon->vtbl.pre_emit_atoms) - radeon->vtbl.pre_emit_atoms(radeon); - - /* Emit actual atoms */ - foreach(atom, &radeon->hw.atomlist) { - if ((atom->dirty || radeon->hw.all_dirty) == dirty) { - dwords = (*atom->check) (radeon->glCtx, atom); - if (dwords) { - if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { - radeon_print_state_atom(atom); - } - if (atom->emit) { - (*atom->emit)(radeon->glCtx, atom); - } else { - BEGIN_BATCH_NO_AUTOSTATE(dwords); - OUT_BATCH_TABLE(atom->cmd, dwords); - END_BATCH(); - } - atom->dirty = GL_FALSE; - } else { - if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { - fprintf(stderr, " skip state %s\n", - atom->name); - } - } - } - } - - COMMIT_BATCH(); -} - -void radeonEmitState(radeonContextPtr radeon) -{ - if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (radeon->vtbl.pre_emit_state) - radeon->vtbl.pre_emit_state(radeon); - - /* this code used to return here but now it emits zbs */ - if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) - return; - - /* To avoid going across the entire set of states multiple times, just check - * for enough space for the case of emitting all state, and inline the - * radeonAllocCmdBuf code here without all the checks. - */ - rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__); - - /* We always always emit zbs, this is due to a bug found by keithw in - the hardware and rediscovered after Erics changes by me. - if you ever touch this code make sure you emit zbs otherwise - you get tcl lockups on at least M7/7500 class of chips - airlied */ - /* special r100 case */ - // rmesa->hw.zbs.dirty=1; - - if (!radeon->cmdbuf.cs->cdw) { - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Begin reemit state\n"); - - radeonEmitAtoms(radeon, GL_FALSE); - } - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "Begin dirty state\n"); - - radeonEmitAtoms(radeon, GL_TRUE); - radeon->hw.is_dirty = GL_FALSE; - radeon->hw.all_dirty = GL_FALSE; - -} - - -/* Make sure all commands have been sent to the hardware and have - * completed processing. - */ -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); - } -} - -/** - * Swap front and back buffer. - */ -void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - radeonContextPtr radeon; - GLcontext *ctx; - - radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - ctx = radeon->glCtx; - - if (ctx->Visual.doubleBufferMode) { - _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ - if (radeon->doPageFlip) { - radeonPageFlip(dPriv); - } else { - radeonCopyBuffer(dPriv, NULL); - } - } - } 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(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h ) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - radeonContextPtr radeon; - GLcontext *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__); - } -} - -/* cmdbuffer */ -/** - * Send the current command buffer via ioctl to the hardware. - */ -int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) -{ - int ret = 0; - - if (rmesa->cmdbuf.flushing) { - fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); - exit(-1); - } - rmesa->cmdbuf.flushing = 1; - if (rmesa->cmdbuf.cs->cdw) { - ret = radeon_cs_emit(rmesa->cmdbuf.cs); - rmesa->hw.all_dirty = GL_TRUE; - } - radeon_cs_erase(rmesa->cmdbuf.cs); - rmesa->cmdbuf.flushing = 0; - return ret; -} - -int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) -{ - int ret; - - radeonReleaseDmaRegion(rmesa); - - LOCK_HARDWARE(rmesa); - ret = rcommonFlushCmdBufLocked(rmesa, caller); - UNLOCK_HARDWARE(rmesa); - - if (ret) { - fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); - _mesa_exit(ret); - } - - return ret; -} - -/** - * Make sure that enough space is available in the command buffer - * by flushing if necessary. - * - * \param dwords The number of dwords we need to be free on the command buffer - */ -void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) -{ - if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size || - radeon_cs_need_flush(rmesa->cmdbuf.cs)) { - rcommonFlushCmdBuf(rmesa, caller); - } -} - -void rcommonInitCmdBuf(radeonContextPtr rmesa) -{ - GLuint size; - /* Initialize command buffer */ - size = 256 * driQueryOptioni(&rmesa->optionCache, - "command_buffer_size"); - if (size < 2 * rmesa->hw.max_state_size) { - size = 2 * rmesa->hw.max_state_size + 65535; - } - if (size > 64 * 256) - size = 64 * 256; - - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { - fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", - sizeof(drm_r300_cmd_header_t)); - fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", - sizeof(drm_radeon_cmd_buffer_t)); - fprintf(stderr, - "Allocating %d bytes command buffer (max state is %d bytes)\n", - size * 4, rmesa->hw.max_state_size * 4); - } - - if (rmesa->radeonScreen->kernel_mm) { - int fd = rmesa->radeonScreen->driScreen->fd; - rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); - } else { - rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); - } - if (rmesa->cmdbuf.csm == NULL) { - /* FIXME: fatal error */ - return; - } - rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); - assert(rmesa->cmdbuf.cs != NULL); - rmesa->cmdbuf.size = size; - - if (!rmesa->radeonScreen->kernel_mm) { - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); - } else { - struct drm_radeon_gem_info mminfo; - - if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) - { - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_size); - radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size); - } - } - -} -/** - * Destroy the command buffer - */ -void rcommonDestroyCmdBuf(radeonContextPtr rmesa) -{ - radeon_cs_destroy(rmesa->cmdbuf.cs); - if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { - radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); - } else { - radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); - } -} - -void rcommonBeginBatch(radeonContextPtr rmesa, int n, - int dostate, - const char *file, - const char *function, - int line) -{ - rcommonEnsureCmdBufSpace(rmesa, n, function); - if (!rmesa->cmdbuf.cs->cdw && dostate) { - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "Reemit state after flush (from %s)\n", function); - radeonEmitState(rmesa); - } - radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); -} - - - -/* Return various strings for glGetString(). - */ -static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) -{ - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - static char buffer[128]; - - switch (name) { - case GL_VENDOR: - if (IS_R300_CLASS(radeon->radeonScreen)) - return (GLubyte *) "DRI R300 Project"; - else - return (GLubyte *) "Tungsten Graphics, Inc."; - - case GL_RENDERER: - { - unsigned offset; - GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : - radeon->radeonScreen->AGPMode; - const char* chipname; - - if (IS_R300_CLASS(radeon->radeonScreen)) - chipname = "R300"; - else if (IS_R200_CLASS(radeon->radeonScreen)) - chipname = "R200"; - else - chipname = "R100"; - - offset = driGetRendererString(buffer, chipname, DRIVER_DATE, - agp_mode); - - if (IS_R300_CLASS(radeon->radeonScreen)) { - sprintf(&buffer[offset], " %sTCL", - (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) - ? "" : "NO-"); - } else { - sprintf(&buffer[offset], " %sTCL", - !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) - ? "" : "NO-"); - } - - if (radeon->radeonScreen->driScreen->dri2.enabled) - strcat(buffer, " DRI2"); - - return (GLubyte *) buffer; - } - - default: - return NULL; - } -} - -/* Initialize the driver's misc functions. - */ -static void radeonInitDriverFuncs(struct dd_function_table *functions) -{ - functions->GetString = radeonGetString; -} - -/** - * Create and initialize all common fields of the context, - * including the Mesa context itself. - */ -GLboolean radeonInitContext(radeonContextPtr radeon, - struct dd_function_table* functions, - const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); - GLcontext* ctx; - GLcontext* shareCtx; - int fthrottle_mode; - - /* Fill in additional standard functions. */ - radeonInitDriverFuncs(functions); - - radeon->radeonScreen = screen; - /* Allocate and initialize the Mesa context */ - if (sharedContextPrivate) - shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; - else - shareCtx = NULL; - radeon->glCtx = _mesa_create_context(glVisual, shareCtx, - functions, (void *)radeon); - if (!radeon->glCtx) - return GL_FALSE; - - ctx = radeon->glCtx; - driContextPriv->driverPrivate = radeon; - - /* DRI fields */ - radeon->dri.context = driContextPriv; - radeon->dri.screen = sPriv; - radeon->dri.drawable = NULL; - radeon->dri.readable = NULL; - radeon->dri.hwContext = driContextPriv->hHWContext; - radeon->dri.hwLock = &sPriv->pSAREA->lock; - radeon->dri.fd = sPriv->fd; - radeon->dri.drmMinor = sPriv->drm_version.minor; - - radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + - screen->sarea_priv_offset); - - /* Setup IRQs */ - fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); - radeon->iw.irq_seq = -1; - radeon->irqsEmitted = 0; - radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && - radeon->radeonScreen->irq); - - radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - - if (!radeon->do_irqs) - fprintf(stderr, - "IRQ's not enabled, falling back to %s: %d %d\n", - radeon->do_usleeps ? "usleeps" : "busy waits", - fthrottle_mode, radeon->radeonScreen->irq); - - (*sPriv->systemTime->getUST) (&radeon->swap_ust); - - return GL_TRUE; -} - -/** - * Cleanup common context fields. - * Called by r200DestroyContext/r300DestroyContext - */ -void radeonCleanupContext(radeonContextPtr radeon) -{ - FILE *track; - struct radeon_renderbuffer *rb; - GLframebuffer *fb; - - /* free the Mesa context */ - _mesa_destroy_context(radeon->glCtx); - - fb = (void*)radeon->dri.drawable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - fb = (void*)radeon->dri.readable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - - /* _mesa_destroy_context() might result in calls to functions that - * depend on the DriverCtx, so don't set it to NULL before. - * - * radeon->glCtx->DriverCtx = NULL; - */ - - - - /* free the option cache */ - driDestroyOptionCache(&radeon->optionCache); - - rcommonDestroyCmdBuf(radeon); - - if (radeon->state.scissor.pClipRects) { - FREE(radeon->state.scissor.pClipRects); - radeon->state.scissor.pClipRects = 0; - } - track = fopen("/tmp/tracklog", "w"); - if (track) { - radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); - fclose(track); - } -} - -/* Force the context `c' to be unbound from its buffer. - */ -GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p\n", __FUNCTION__, - radeon->glCtx); - - return GL_TRUE; -} - - -static void -radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) -{ - /* if radeon->fake */ - struct radeon_renderbuffer *rb; - - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->frontOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->backOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } -} - -static void -radeon_make_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) -{ - int size = 4096*4096*4; - /* if radeon->fake */ - struct radeon_renderbuffer *rb; - - if (radeon->radeonScreen->kernel_mm) { - radeon_make_kernel_renderbuffer_current(radeon, draw); - return; - } - - - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->frontOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->backOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { - if (!rb->bo) { - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - radeon->radeonScreen->depthOffset + - radeon->radeonScreen->fbLocation, - size, - 4096, - RADEON_GEM_DOMAIN_VRAM, - 0); - } - rb->cpp = radeon->radeonScreen->cpp; - rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; - } -} - - -void -radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) -{ - unsigned int attachments[10]; - __DRIbuffer *buffers; - __DRIscreen *screen; - struct radeon_renderbuffer *rb; - int i, count; - GLframebuffer *draw; - radeonContextPtr radeon; - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); - - draw = drawable->driverPrivate; - screen = context->driScreenPriv; - radeon = (radeonContextPtr) context->driverPrivate; - i = 0; - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { - attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { - attachments[i++] = __DRI_BUFFER_DEPTH; - } - - buffers = (*screen->dri2.loader->getBuffers)(drawable, - &drawable->w, - &drawable->h, - attachments, i, - &count, - drawable->loaderPrivate); - if (buffers == NULL) - return; - - /* set one cliprect to cover the whole drawable */ - drawable->x = 0; - drawable->y = 0; - drawable->backX = 0; - drawable->backY = 0; - drawable->numClipRects = 1; - drawable->pClipRects[0].x1 = 0; - drawable->pClipRects[0].y1 = 0; - drawable->pClipRects[0].x2 = drawable->w; - drawable->pClipRects[0].y2 = drawable->h; - drawable->numBackClipRects = 1; - drawable->pBackClipRects[0].x1 = 0; - drawable->pBackClipRects[0].y1 = 0; - drawable->pBackClipRects[0].x2 = drawable->w; - drawable->pBackClipRects[0].y2 = drawable->h; - for (i = 0; i < count; i++) { - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb->cpp = buffers[i].cpp; - rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; - rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - if (rb->bo == NULL) { - fprintf(stderr, "failled to attach front %d\n", - buffers[i].name); - } - break; - case __DRI_BUFFER_BACK_LEFT: - rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb->cpp = buffers[i].cpp; - rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; - rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - break; - case __DRI_BUFFER_DEPTH: - rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb->cpp = buffers[i].cpp; - rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; - rb->has_surface = 0; - rb->bo = radeon_bo_open(radeon->radeonScreen->bom, - buffers[i].name, - 0, - 0, - RADEON_GEM_DOMAIN_VRAM, - buffers[i].flags); - break; - case __DRI_BUFFER_STENCIL: - break; - case __DRI_BUFFER_ACCUM: - default: - fprintf(stderr, - "unhandled buffer attach event, attacment type %d\n", - buffers[i].attachment); - return; - } - } - radeon = (radeonContextPtr) context->driverPrivate; - driUpdateFramebufferSize(radeon->glCtx, drawable); -} - -/* Force the context `c' to be the current context and associate with it - * buffer `b'. - */ -GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - radeonContextPtr radeon; - GLframebuffer *dfb, *rfb; - - if (!driContextPriv) { - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx is null\n", __FUNCTION__); - _mesa_make_current(NULL, NULL, NULL); - return GL_TRUE; - } - radeon = (radeonContextPtr) driContextPriv->driverPrivate; - dfb = driDrawPriv->driverPrivate; - rfb = driReadPriv->driverPrivate; - - if (driContextPriv->driScreenPriv->dri2.enabled) { - radeon_update_renderbuffers(driContextPriv, driDrawPriv); - if (driDrawPriv != driReadPriv) - radeon_update_renderbuffers(driContextPriv, driReadPriv); - radeon->state.color.rrb = - (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - radeon->state.depth.rrb = - (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; - } else { - radeon_make_renderbuffer_current(radeon, dfb); - } - - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb); - - driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); - if (driReadPriv != driDrawPriv) - driUpdateFramebufferSize(radeon->glCtx, driReadPriv); - - - - _mesa_make_current(radeon->glCtx, dfb, rfb); - - if (radeon->dri.drawable != driDrawPriv) { - if (driDrawPriv->swap_interval == (unsigned)-1) { - driDrawPriv->vblFlags = - (radeon->radeonScreen->irq != 0) - ? driGetDefaultVBlankFlags(&radeon-> - optionCache) - : VBLANK_FLAG_NO_IRQ; - - driDrawableInitVBlank(driDrawPriv); - } - } - - radeon->dri.readable = driReadPriv; - - if (radeon->dri.drawable != driDrawPriv || - radeon->lastStamp != driDrawPriv->lastStamp) { - radeon->dri.drawable = driDrawPriv; - - radeonSetCliprects(radeon); - radeon->vtbl.update_viewport_offset(radeon->glCtx); - } - - _mesa_update_state(radeon->glCtx); - - if (!driContextPriv->driScreenPriv->dri2.enabled) { - radeonUpdatePageFlipping(radeon); - } - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "End %s\n", __FUNCTION__); - return GL_TRUE; -} - - -#if defined(USE_X86_ASM) -#define COPY_DWORDS( dst, src, nr ) \ -do { \ - int __tmp; \ - __asm__ __volatile__( "rep ; movsl" \ - : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ - : "0" (nr), \ - "D" ((long)dst), \ - "S" ((long)src) ); \ -} while (0) -#else -#define COPY_DWORDS( dst, src, nr ) \ -do { \ - int j; \ - for ( j = 0 ; j < nr ; j++ ) \ - dst[j] = ((int *)src)[j]; \ - dst += nr; \ -} while (0) -#endif - -static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 4) - COPY_DWORDS(out, data, count); - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out++; - data += stride; - } -} - -void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 8) - COPY_DWORDS(out, data, count * 2); - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out[1] = *(int *)(data + 4); - out += 2; - data += stride; - } -} - -void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 12) { - COPY_DWORDS(out, data, count * 3); - } - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out[1] = *(int *)(data + 4); - out[2] = *(int *)(data + 8); - out += 3; - data += stride; - } -} - -static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count) -{ - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s count %d stride %d out %p data %p\n", - __FUNCTION__, count, stride, (void *)out, (void *)data); - - if (stride == 16) - COPY_DWORDS(out, data, count * 4); - else - for (i = 0; i < count; i++) { - out[0] = *(int *)data; - out[1] = *(int *)(data + 4); - out[2] = *(int *)(data + 8); - out[3] = *(int *)(data + 12); - out += 4; - data += stride; - } -} - -void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, - GLvoid * data, int size, int stride, int count) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - uint32_t *out; - - if (stride == 0) { - radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); - count = 1; - aos->stride = 0; - } else { - radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); - aos->stride = size; - } - - aos->components = size; - aos->count = count; - - out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); - switch (size) { - case 1: radeonEmitVec4(out, data, stride, count); break; - case 2: radeonEmitVec8(out, data, stride, count); break; - case 3: radeonEmitVec12(out, data, stride, count); break; - case 4: radeonEmitVec16(out, data, stride, count); break; - default: - assert(0); - break; - } -} - - -void radeon_print_state_atom( struct radeon_state_atom *state ) -{ - int i; - - fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); - - if (RADEON_DEBUG & DEBUG_VERBOSE) - for (i = 0 ; i < state->cmd_size ; i++) - fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); - -} - -/* textures */ -/** - * Allocate an empty texture image object. - */ -struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) -{ - return CALLOC(sizeof(radeon_texture_image)); -} - -/** - * Free memory associated with this texture image. - */ -void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) -{ - radeon_texture_image* image = get_radeon_texture_image(timage); - - if (image->mt) { - radeon_miptree_unreference(image->mt); - image->mt = 0; - assert(!image->base.Data); - } else { - _mesa_free_texture_image_data(ctx, timage); - } - if (image->bo) { - radeon_bo_unref(image->bo); - image->bo = NULL; - } - if (timage->Data) { - _mesa_free_texmemory(timage->Data); - timage->Data = NULL; - } -} - -/* Set Data pointer and additional data for mapped texture image */ -static void teximage_set_map_data(radeon_texture_image *image) -{ - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - - image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; - image->base.RowStride = lvl->rowstride / image->mt->bpp; -} - - -/** - * Map a single texture image for glTexImage and friends. - */ -void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) -{ - if (image->mt) { - assert(!image->base.Data); - - radeon_bo_map(image->mt->bo, write_enable); - teximage_set_map_data(image); - } -} - - -void radeon_teximage_unmap(radeon_texture_image *image) -{ - if (image->mt) { - assert(image->base.Data); - - image->base.Data = 0; - radeon_bo_unmap(image->mt->bo); - } -} - -/** - * Map a validated texture for reading during software rendering. - */ -void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - int face, level; - - /* for r100 3D sw fallbacks don't have mt */ - if (!t->mt) - return; - - radeon_bo_map(t->mt->bo, GL_FALSE); - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) - teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); - } -} - -void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - int face, level; - - /* for r100 3D sw fallbacks don't have mt */ - if (!t->mt) - return; - - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) - texObj->Image[face][level]->Data = 0; - } - radeon_bo_unmap(t->mt->bo); -} - -GLuint radeon_face_for_target(GLenum target) -{ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - default: - return 0; - } -} - -/** - * Wraps Mesa's implementation to ensure that the base level image is mapped. - * - * This relies on internal details of _mesa_generate_mipmap, in particular - * the fact that the memory for recreated texture images is always freed. - */ -static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - int i, face; - - - _mesa_generate_mipmap(ctx, target, texObj); - - for (face = 0; face < nr_faces; face++) { - for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { - radeon_texture_image *image; - - image = get_radeon_texture_image(texObj->Image[face][i]); - - if (image == NULL) - break; - - image->mtlevel = i; - image->mtface = face; - - radeon_miptree_unreference(image->mt); - image->mt = NULL; - } - } - -} - -void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) -{ - GLuint face = radeon_face_for_target(target); - radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); - - radeon_teximage_map(baseimage, GL_FALSE); - radeon_generate_mipmap(ctx, target, texObj); - radeon_teximage_unmap(baseimage); -} - - -/* try to find a format which will only need a memcopy */ -static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa, - GLenum srcFormat, - GLenum srcType) -{ - const GLuint ui = 1; - const GLubyte littleEndian = *((const GLubyte *)&ui); - - /* r100 can only do this */ - if (IS_R100_CLASS(rmesa->radeonScreen)) - return _dri_texformat_argb8888; - - if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || - (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { - return &_mesa_texformat_rgba8888; - } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || - (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || - (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { - return &_mesa_texformat_rgba8888_rev; - } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || - srcType == GL_UNSIGNED_INT_8_8_8_8)) { - return &_mesa_texformat_argb8888_rev; - } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { - return &_mesa_texformat_argb8888; - } else - return _dri_texformat_argb8888; -} - -const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, - GLint internalFormat, - GLenum format, - GLenum type) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - const GLboolean do32bpt = - (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); - const GLboolean force16bpt = - (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); - (void)format; - -#if 0 - fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", - _mesa_lookup_enum_by_nr(internalFormat), internalFormat, - _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); - fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); -#endif - - switch (internalFormat) { - case 4: - case GL_RGBA: - case GL_COMPRESSED_RGBA: - switch (type) { - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - return do32bpt ? _dri_texformat_argb8888 : - _dri_texformat_argb1555; - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return _dri_texformat_argb4444; - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return _dri_texformat_argb1555; - default: - return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) : - _dri_texformat_argb4444; - } - - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return _dri_texformat_argb4444; - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return _dri_texformat_argb1555; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - return _dri_texformat_rgb565; - default: - return do32bpt ? _dri_texformat_argb8888 : - _dri_texformat_rgb565; - } - - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return !force16bpt ? - radeonChoose8888TexFormat(rmesa, format,type) : - _dri_texformat_argb4444; - - case GL_RGBA4: - case GL_RGBA2: - return _dri_texformat_argb4444; - - case GL_RGB5_A1: - return _dri_texformat_argb1555; - - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return !force16bpt ? _dri_texformat_argb8888 : - _dri_texformat_rgb565; - - case GL_RGB5: - case GL_RGB4: - case GL_R3_G3_B2: - return _dri_texformat_rgb565; - - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case GL_COMPRESSED_ALPHA: - return _dri_texformat_a8; - - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case GL_COMPRESSED_LUMINANCE: - return _dri_texformat_l8; - - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - case GL_COMPRESSED_LUMINANCE_ALPHA: - return _dri_texformat_al88; - - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case GL_COMPRESSED_INTENSITY: - return _dri_texformat_i8; - - case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_APPLE || - type == GL_UNSIGNED_BYTE) - return &_mesa_texformat_ycbcr; - else - return &_mesa_texformat_ycbcr_rev; - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return &_mesa_texformat_rgb_dxt1; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return &_mesa_texformat_rgba_dxt1; - - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return &_mesa_texformat_rgba_dxt3; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return &_mesa_texformat_rgba_dxt5; - - case GL_ALPHA16F_ARB: - return &_mesa_texformat_alpha_float16; - case GL_ALPHA32F_ARB: - return &_mesa_texformat_alpha_float32; - case GL_LUMINANCE16F_ARB: - return &_mesa_texformat_luminance_float16; - case GL_LUMINANCE32F_ARB: - return &_mesa_texformat_luminance_float32; - case GL_LUMINANCE_ALPHA16F_ARB: - return &_mesa_texformat_luminance_alpha_float16; - case GL_LUMINANCE_ALPHA32F_ARB: - return &_mesa_texformat_luminance_alpha_float32; - case GL_INTENSITY16F_ARB: - return &_mesa_texformat_intensity_float16; - case GL_INTENSITY32F_ARB: - return &_mesa_texformat_intensity_float32; - case GL_RGB16F_ARB: - return &_mesa_texformat_rgba_float16; - case GL_RGB32F_ARB: - return &_mesa_texformat_rgba_float32; - case GL_RGBA16F_ARB: - return &_mesa_texformat_rgba_float16; - case GL_RGBA32F_ARB: - return &_mesa_texformat_rgba_float32; - - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: -#if 0 - switch (type) { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT: - return &_mesa_texformat_z16; - case GL_UNSIGNED_INT: - return &_mesa_texformat_z32; - case GL_UNSIGNED_INT_24_8_EXT: - default: - return &_mesa_texformat_z24_s8; - } -#else - return &_mesa_texformat_z16; -#endif - - default: - _mesa_problem(ctx, - "unexpected internalFormat 0x%x in r300ChooseTextureFormat", - (int)internalFormat); - return NULL; - } - - return NULL; /* never get here */ -} - -/** - * All glTexImage calls go through this function. - */ -static void radeon_teximage( - GLcontext *ctx, int dims, - GLint face, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLsizei imageSize, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - int compressed) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - - radeon_firevertices(rmesa); - - t->validated = GL_FALSE; - - /* Choose and fill in the texture format for this image */ - texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type); - _mesa_set_fetch_functions(texImage, dims); - - if (texImage->TexFormat->TexelBytes == 0) { - texImage->IsCompressed = GL_TRUE; - texImage->CompressedSize = - ctx->Driver.CompressedTextureSize(ctx, texImage->Width, - texImage->Height, texImage->Depth, - texImage->TexFormat->MesaFormat); - } else { - texImage->IsCompressed = GL_FALSE; - texImage->CompressedSize = 0; - } - - /* Allocate memory for image */ - radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ - - if (!t->mt) - radeon_try_alloc_miptree(rmesa, t, texImage, face, level); - if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { - image->mt = t->mt; - image->mtlevel = level - t->mt->firstLevel; - image->mtface = face; - radeon_miptree_reference(t->mt); - } else { - int size; - if (texImage->IsCompressed) { - size = texImage->CompressedSize; - } else { - size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes; - } - texImage->Data = _mesa_alloc_texmemory(size); - } - - /* Upload texture image; note that the spec allows pixels to be NULL */ - if (compressed) { - pixels = _mesa_validate_pbo_compressed_teximage( - ctx, imageSize, pixels, packing, "glCompressedTexImage"); - } else { - pixels = _mesa_validate_pbo_teximage( - ctx, dims, width, height, depth, - format, type, pixels, packing, "glTexImage"); - } - - if (pixels) { - radeon_teximage_map(image, GL_TRUE); - - if (compressed) { - memcpy(texImage->Data, pixels, imageSize); - } else { - GLuint dstRowStride; - if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; - } - if (!texImage->TexFormat->StoreImage(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - } - - } - - /* SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); - } - - if (pixels) - radeon_teximage_unmap(image); - - _mesa_unmap_teximage_pbo(ctx, packing); - - -} - -void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, - 0, format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) - -{ - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, - 0, format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, - imageSize, 0, 0, data, 0, texObj, texImage, 1); -} - -void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, - 0, format, type, pixels, packing, texObj, texImage, 0); -} - -/** - * Update a subregion of the given texture image. - */ -static void radeon_texsubimage(GLcontext* ctx, int dims, int level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - int compressed) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - - radeon_firevertices(rmesa); - - t->validated = GL_FALSE; - pixels = _mesa_validate_pbo_teximage(ctx, dims, - width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); - - if (pixels) { - GLint dstRowStride; - radeon_teximage_map(image, GL_TRUE); - - if (image->mt) { - radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; - dstRowStride = lvl->rowstride; - } else { - dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; - } - - if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); - - - } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); - } - radeon_teximage_unmap(image); - - _mesa_unmap_teximage_pbo(ctx, packing); - - -} - -void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, - format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, - 1, format, type, pixels, packing, texObj, texImage, - 0); -} - -void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, - format, 0, data, 0, texObj, texImage, 1); -} - - -void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, - format, type, pixels, packing, texObj, texImage, 0); -} - -static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, - GLuint numrows, GLuint rowsize) -{ - assert(rowsize <= dststride); - assert(rowsize <= srcstride); - - if (rowsize == srcstride && rowsize == dststride) { - memcpy(dst, src, numrows*rowsize); - } else { - GLuint i; - for(i = 0; i < numrows; ++i) { - memcpy(dst, src, rowsize); - dst += dststride; - src += srcstride; - } - } -} - - -/** - * Ensure that the given image is stored in the given miptree from now on. - */ -static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) -{ - radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; - unsigned char *dest; - - assert(image->mt != mt); - assert(dstlvl->width == image->base.Width); - assert(dstlvl->height == image->base.Height); - assert(dstlvl->depth == image->base.Depth); - - - radeon_bo_map(mt->bo, GL_TRUE); - dest = mt->bo->ptr + dstlvl->faces[face].offset; - - if (image->mt) { - /* Format etc. should match, so we really just need a memcpy(). - * In fact, that memcpy() could be done by the hardware in many - * cases, provided that we have a proper memory manager. - */ - radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; - - assert(srclvl->size == dstlvl->size); - assert(srclvl->rowstride == dstlvl->rowstride); - - radeon_bo_map(image->mt->bo, GL_FALSE); - - memcpy(dest, - image->mt->bo->ptr + srclvl->faces[face].offset, - dstlvl->size); - radeon_bo_unmap(image->mt->bo); - - radeon_miptree_unreference(image->mt); - } else { - uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; - -// if (mt->tilebits) -// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); - - copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, - image->base.Height * image->base.Depth, srcrowstride); - - _mesa_free_texmemory(image->base.Data); - image->base.Data = 0; - } - - radeon_bo_unmap(mt->bo); - - image->mt = mt; - image->mtface = face; - image->mtlevel = level; - radeon_miptree_reference(image->mt); -} - -int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj *t = radeon_tex_obj(texObj); - radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); - int face, level; - - if (t->validated || t->image_override) - return GL_TRUE; - - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); - - if (baseimage->base.Border > 0) - return GL_FALSE; - - /* Ensure a matching miptree exists. - * - * Differing mipmap trees can result when the app uses TexImage to - * change texture dimensions. - * - * Prefer to use base image's miptree if it - * exists, since that most likely contains more valid data (remember - * that the base level is usually significantly larger than the rest - * of the miptree, so cubemaps are the only possible exception). - */ - if (baseimage->mt && - baseimage->mt != t->mt && - radeon_miptree_matches_texture(baseimage->mt, &t->base)) { - radeon_miptree_unreference(t->mt); - t->mt = baseimage->mt; - radeon_miptree_reference(t->mt); - } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - } - - if (!t->mt) { - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, " Allocate new miptree\n"); - radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); - if (!t->mt) { - _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); - return GL_FALSE; - } - } - - /* Ensure all images are stored in the single main miptree */ - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { - radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); - if (t->mt == image->mt) { - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "OK\n"); - continue; - } - - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "migrating\n"); - migrate_image_to_miptree(t->mt, image, face, level); - } - } - - return GL_TRUE; -} - - -GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint nmacroblkpl; - GLint nmicroblkpl; - - x += dPriv->x; - y += dPriv->y; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - nmacroblkpl = rrb->pitch >> 5; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x >> 5) << 11; - offset += ((x & 31) >> 2) << 5; - offset += (x & 3) << 2; - } else { - nmacroblkpl = rrb->pitch >> 6; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x >> 6) << 11; - offset += ((x & 63) >> 3) << 5; - offset += (x & 7) << 2; - } - } else { - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x >> 3) << 5; - offset += (x & 7) << 2; - } - } - return &ptr[offset]; -} - -GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint nmacroblkpl; - GLint nmicroblkpl; - - x += dPriv->x; - y += dPriv->y; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - nmacroblkpl = rrb->pitch >> 6; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x >> 6) << 11; - offset += ((x & 63) >> 3) << 5; - offset += (x & 7) << 1; - } else { - nmacroblkpl = rrb->pitch >> 7; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x >> 7) << 11; - offset += ((x & 127) >> 4) << 5; - offset += (x & 15) << 2; - } - } else { - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x >> 4) << 5; - offset += (x & 15) << 2; - } - } - return &ptr[offset]; -} - -GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - const __DRIdrawablePrivate *dPriv = rrb->dPriv; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint microblkxs; - GLint macroblkxs; - GLint nmacroblkpl; - GLint nmicroblkpl; - - x += dPriv->x; - y += dPriv->y; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - microblkxs = 16 / rrb->cpp; - macroblkxs = 128 / rrb->cpp; - nmacroblkpl = rrb->pitch / macroblkxs; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x / macroblkxs) << 11; - offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } else { - microblkxs = 32 / rrb->cpp; - macroblkxs = 256 / rrb->cpp; - nmacroblkpl = rrb->pitch / macroblkxs; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x / macroblkxs) << 11; - offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } - } else { - microblkxs = 32 / rrb->cpp; - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } - } - return &ptr[offset]; -} - - -static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) -{ - struct radeon_renderbuffer *rrb = (void*)rb; - int r; - - if (rrb->bo) { - r = radeon_bo_map(rrb->bo, write); - if (r) { - fprintf(stderr, "(%s) error(%d) mapping buffer.\n", - __FUNCTION__, r); - } - } -} - -static void unmap_buffer(struct gl_renderbuffer *rb) -{ - struct radeon_renderbuffer *rrb = (void*)rb; - - if (rrb->bo) { - radeon_bo_unmap(rrb->bo); - } -} - -void radeonSpanRenderStart(GLcontext * ctx) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - radeon_firevertices(rmesa); - - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) - ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); - } - - /* color draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); - } - - map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); - - if (ctx->DrawBuffer->_DepthBuffer) { - map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); - } - if (ctx->DrawBuffer->_StencilBuffer) - map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); - - /* The locking and wait for idle should really only be needed in classic mode. - * In a future memory manager based implementation, this should become - * unnecessary due to the fact that mapping our buffers, textures, etc. - * should implicitly wait for any previous rendering commands that must - * be waited on. */ - LOCK_HARDWARE(rmesa); - radeonWaitForIdleLocked(rmesa); -} - -void radeonSpanRenderFinish(GLcontext * ctx) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - _swrast_flush(ctx); - UNLOCK_HARDWARE(rmesa); - - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) - ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); - } - - /* color draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) - unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); - - unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer); - - if (ctx->DrawBuffer->_DepthBuffer) - unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); - if (ctx->DrawBuffer->_StencilBuffer) - unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); -} - -void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) -{ - struct radeon_cs_space_check bos[1]; - int flushed = 0, ret; - - size = MAX2(size, MAX_DMA_BUF_SZ * 16); - - if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->dma.flush) { - rmesa->dma.flush(rmesa->glCtx); - } - - if (rmesa->dma.nr_released_bufs > 4) { - rcommonFlushCmdBuf(rmesa, __FUNCTION__); - rmesa->dma.nr_released_bufs = 0; - } - - if (rmesa->dma.current) { - radeon_bo_unmap(rmesa->dma.current); - radeon_bo_unref(rmesa->dma.current); - rmesa->dma.current = 0; - } - -again_alloc: - rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, - 0, size, 4, RADEON_GEM_DOMAIN_GTT, - 0); - - if (!rmesa->dma.current) { - rcommonFlushCmdBuf(rmesa, __FUNCTION__); - rmesa->dma.nr_released_bufs = 0; - goto again_alloc; - } - - rmesa->dma.current_used = 0; - rmesa->dma.current_vertexptr = 0; - - bos[0].bo = rmesa->dma.current; - bos[0].read_domains = RADEON_GEM_DOMAIN_GTT; - bos[0].write_domain =0 ; - bos[0].new_accounted = 0; - - ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1); - if (ret == RADEON_CS_SPACE_OP_TO_BIG) { - fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen"); - assert(0); - } else if (ret == RADEON_CS_SPACE_FLUSH) { - rcommonFlushCmdBuf(rmesa, __FUNCTION__); - if (flushed) { - fprintf(stderr,"flushed but still no space\n"); - assert(0); - } - flushed = 1; - goto again_alloc; - } - radeon_bo_map(rmesa->dma.current, 1); -} - -/* Allocates a region from rmesa->dma.current. If there isn't enough - * space in current, grab a new buffer (and discard what was left of current) - */ -void radeonAllocDmaRegion(radeonContextPtr rmesa, - struct radeon_bo **pbo, int *poffset, - int bytes, int alignment) -{ - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); - - if (rmesa->dma.flush) - rmesa->dma.flush(rmesa->glCtx); - - assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); - - alignment--; - rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; - - if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) - radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); - - *poffset = rmesa->dma.current_used; - *pbo = rmesa->dma.current; - radeon_bo_ref(*pbo); - - /* Always align to at least 16 bytes */ - rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; - rmesa->dma.current_vertexptr = rmesa->dma.current_used; - - assert(rmesa->dma.current_used <= rmesa->dma.current->size); -} - -void radeonReleaseDmaRegion(radeonContextPtr rmesa) -{ - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current); - if (rmesa->dma.current) { - rmesa->dma.nr_released_bufs++; - radeon_bo_unmap(rmesa->dma.current); - radeon_bo_unref(rmesa->dma.current); - } - rmesa->dma.current = NULL; -} - - -/* Flush vertices in the current dma region. - */ -void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct radeon_dma *dma = &rmesa->dma; - - - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - dma->flush = NULL; - - if (dma->current) { - GLuint current_offset = dma->current_used; - - assert (dma->current_used + - rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == - dma->current_vertexptr); - - if (dma->current_used != dma->current_vertexptr) { - dma->current_used = dma->current_vertexptr; - - rmesa->vtbl.swtcl_flush(ctx, current_offset); - } - rmesa->swtcl.numverts = 0; - } -} -/* Alloc space in the current dma region. - */ -void * -rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) -{ - GLuint bytes = vsize * nverts; - void *head; - - if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) { - radeonRefillCurrentDmaRegion(rmesa, bytes); - } - - if (!rmesa->dma.flush) { - rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - rmesa->dma.flush = rcommon_flush_last_swtcl_prim; - } - - ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); - ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); - ASSERT( rmesa->dma.current_used + - rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == - rmesa->dma.current_vertexptr ); - -// fprintf(stderr,"current %p %x\n", rmesa->radeon.dma.current->ptr, -// rmesa->radeon.dma.current_vertexptr); - head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr); - rmesa->dma.current_vertexptr += bytes; - rmesa->swtcl.numverts += nverts; - return head; -} diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h deleted file mode 100644 index ebf287a031..0000000000 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef COMMON_MISC_H -#define COMMON_MISC_H - -#include "common_context.h" -#include "radeon_buffer.h" -void radeonRecalcScissorRects(radeonContextPtr radeon); -void radeonSetCliprects(radeonContextPtr radeon); -void radeonUpdateScissor( GLcontext *ctx ); -void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); - -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); -void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); -void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h ); - -void radeonUpdatePageFlipping(radeonContextPtr rmesa); - -GLboolean radeonInitContext(radeonContextPtr radeon, - struct dd_function_table* functions, - const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -void radeonCleanupContext(radeonContextPtr radeon); -GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); -void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); -GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - -void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count); -void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count); - -void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, - GLvoid * data, int size, int stride, int count); -void radeon_print_state_atom( struct radeon_state_atom *state ); - -struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx); -void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage); - -void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); -void radeon_teximage_unmap(radeon_texture_image *image); -void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); -void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); -void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); -int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); -GLuint radeon_face_for_target(GLenum target); -const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, - GLint internalFormat, - GLenum format, - GLenum type); - -void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); -void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void radeonSpanRenderStart(GLcontext * ctx); -void radeonSpanRenderFinish(GLcontext * ctx); -GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, - GLint x, GLint y); -GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, - GLint x, GLint y); -GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, - GLint x, GLint y); -void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); -void radeonAllocDmaRegion(radeonContextPtr rmesa, - struct radeon_bo **pbo, int *poffset, - int bytes, int alignment); -void radeonReleaseDmaRegion(radeonContextPtr rmesa); - -void rcommon_flush_last_swtcl_prim(GLcontext *ctx); - -void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); - -void radeonFlush(GLcontext *ctx); -void radeonFinish(GLcontext * ctx); -void radeonEmitState(radeonContextPtr radeon); - -static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) -{ - struct radeon_renderbuffer *rrb; - rrb = rmesa->state.depth.rrb; - if (!rrb) - return NULL; - - return rrb; -} - -static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) -{ - struct radeon_renderbuffer *rrb; - GLframebuffer *fb = rmesa->dri.drawable->driverPrivate; - - rrb = rmesa->state.color.rrb; - if (rmesa->radeonScreen->driScreen->dri2.enabled) { - rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } - if (!rrb) - return NULL; - return rrb; -} - - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index a716f1059b..b7658353af 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -47,7 +47,7 @@ #include "radeon_drm.h" #include "radeon_bo.h" #include "radeon_bo_legacy.h" -#include "common_context.h" +#include "radeon_common.h" struct bo_legacy { struct radeon_bo base; diff --git a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h new file mode 100644 index 0000000000..5526934209 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h @@ -0,0 +1,143 @@ +#ifndef COMMON_CMDBUF_H +#define COMMON_CMDBUF_H + +#include "radeon_cs.h" + +void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller); +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller); +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller); +void rcommonInitCmdBuf(radeonContextPtr rmesa); +void rcommonDestroyCmdBuf(radeonContextPtr rmesa); + +void rcommonBeginBatch(radeonContextPtr rmesa, + int n, + int dostate, + const char *file, + const char *function, + int line); + +#define RADEON_CP_PACKET3_NOP 0xC0001000 +#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 +#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 +#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 +#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 +#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 +#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 +#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 + +#define CP_PACKET2 (2 << 30) +#define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) +#define CP_PACKET0_ONE(reg, n) (RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2)) +#define CP_PACKET3( pkt, n ) \ + (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + +/** + * Every function writing to the command buffer needs to declare this + * to get the necessary local variables. + */ +#define BATCH_LOCALS(rmesa) \ + const radeonContextPtr b_l_rmesa = rmesa + +/** + * Prepare writing n dwords to the command buffer, + * including producing any necessary state emits on buffer wraparound. + */ +#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, 1, __FILE__, __FUNCTION__, __LINE__) + +/** + * Same as BEGIN_BATCH, but do not cause automatic state emits. + */ +#define BEGIN_BATCH_NO_AUTOSTATE(n) rcommonBeginBatch(b_l_rmesa, n, 0, __FILE__, __FUNCTION__, __LINE__) + +/** + * Write one dword to the command buffer. + */ +#define OUT_BATCH(data) \ + do { \ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\ + } while(0) + +/** + * Write a relocated dword to the command buffer. + */ +#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \ + do { \ + if (0 && offset) { \ + fprintf(stderr, "(%s:%s:%d) offset : %d\n", \ + __FILE__, __FUNCTION__, __LINE__, offset); \ + } \ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \ + radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \ + bo, rd, wd, flags); \ + if (!b_l_rmesa->radeonScreen->kernel_mm) \ + b_l_rmesa->cmdbuf.cs->section_cdw += 2; \ + } while(0) + + +/** + * Write n dwords from ptr to the command buffer. + */ +#define OUT_BATCH_TABLE(ptr,n) \ + do { \ + int _i; \ + for (_i=0; _i < n; _i++) {\ + radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\ + }\ + } while(0) + +/** + * Finish writing dwords to the command buffer. + * The number of (direct or indirect) OUT_BATCH calls between the previous + * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time. + */ +#define END_BATCH() \ + do { \ + radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\ + } while(0) + +/** + * After the last END_BATCH() of rendering, this indicates that flushing + * the command buffer now is okay. + */ +#define COMMIT_BATCH() \ + do { \ + } while(0) + + +/** Single register write to command buffer; requires 2 dwords. */ +#define OUT_BATCH_REGVAL(reg, val) \ + OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \ + OUT_BATCH((val)) + +/** Continuous register range write to command buffer; requires 1 dword, + * expects count dwords afterwards for register contents. */ +#define OUT_BATCH_REGSEQ(reg, count) \ + OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count))); + +/** Write a 32 bit float to the ring; requires 1 dword. */ +#define OUT_BATCH_FLOAT32(f) \ + OUT_BATCH(radeonPackFloat32((f))); + + +/* Fire the buffered vertices no matter what. + */ +static INLINE void radeon_firevertices(radeonContextPtr radeon) +{ + if (radeon->cmdbuf.cs->cdw || radeon->dma.flush ) + radeonFlush(radeon->glCtx); +} + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c new file mode 100644 index 0000000000..87b6dac40b --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -0,0 +1,843 @@ +/************************************************************************** + +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + */ + +/* + - Scissor implementation + - buffer swap/copy ioctls + - finish/flush + - state emission + - cmdbuffer management +*/ + +#include +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/api_arrayelt.h" +#include "main/enums.h" +#include "main/colormac.h" +#include "main/light.h" +#include "main/framebuffer.h" +#include "main/simple_list.h" + +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "swrast_setup/swrast_setup.h" + +#include "dri_util.h" +#include "drirenderbuffer.h" +#include "vblank.h" + +#include "radeon_common.h" +#include "radeon_common.h" +#include "radeon_bo.h" +#include "radeon_cs.h" +#include "radeon_bo_legacy.h" +#include "radeon_cs_legacy.h" +#include "radeon_bo_gem.h" +#include "radeon_cs_gem.h" +#include "radeon_drm.h" +#include "radeon_mipmap_tree.h" + +#define DEBUG_CMDBUF 0 + +/* ============================================================= + * Scissoring + */ + +static GLboolean intersect_rect(drm_clip_rect_t * out, + drm_clip_rect_t * a, drm_clip_rect_t * b) +{ + *out = *a; + if (b->x1 > out->x1) + out->x1 = b->x1; + if (b->y1 > out->y1) + out->y1 = b->y1; + if (b->x2 < out->x2) + out->x2 = b->x2; + if (b->y2 < out->y2) + out->y2 = b->y2; + if (out->x1 >= out->x2) + return GL_FALSE; + if (out->y1 >= out->y2) + return GL_FALSE; + return GL_TRUE; +} + +void radeonRecalcScissorRects(radeonContextPtr radeon) +{ + drm_clip_rect_t *out; + int i; + + /* Grow cliprect store? + */ + if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { + while (radeon->state.scissor.numAllocedClipRects < + radeon->numClipRects) { + radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ + radeon->state.scissor.numAllocedClipRects *= 2; + } + + if (radeon->state.scissor.pClipRects) + FREE(radeon->state.scissor.pClipRects); + + radeon->state.scissor.pClipRects = + MALLOC(radeon->state.scissor.numAllocedClipRects * + sizeof(drm_clip_rect_t)); + + if (radeon->state.scissor.pClipRects == NULL) { + radeon->state.scissor.numAllocedClipRects = 0; + return; + } + } + + out = radeon->state.scissor.pClipRects; + radeon->state.scissor.numClipRects = 0; + + for (i = 0; i < radeon->numClipRects; i++) { + if (intersect_rect(out, + &radeon->pClipRects[i], + &radeon->state.scissor.rect)) { + radeon->state.scissor.numClipRects++; + out++; + } + } +} + +/** + * Update cliprects and scissors. + */ +void radeonSetCliprects(radeonContextPtr radeon) +{ + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. */ + if (drawable->numBackClipRects == 0 || radeon->doPageFlip || + radeon->sarea->pfCurrentPage == 1) { + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } else { + radeon->numClipRects = drawable->numBackClipRects; + radeon->pClipRects = drawable->pBackClipRects; + } + } else { + /* front buffer (or none, or multiple buffers */ + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } + } + + if ((draw_fb->Width != drawable->w) || + (draw_fb->Height != drawable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + drawable->w, drawable->h); + draw_fb->Initialized = GL_TRUE; + } + + if (drawable != readable) { + if ((read_fb->Width != readable->w) || + (read_fb->Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, read_fb, + readable->w, readable->h); + read_fb->Initialized = GL_TRUE; + } + } + + if (radeon->state.scissor.enabled) + radeonRecalcScissorRects(radeon); + + radeon->lastStamp = drawable->lastStamp; +} + +void radeonUpdateScissor( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( rmesa->dri.drawable ) { + __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + + int x = ctx->Scissor.X; + int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; + int w = ctx->Scissor.X + ctx->Scissor.Width - 1; + int h = dPriv->h - ctx->Scissor.Y - 1; + + rmesa->state.scissor.rect.x1 = x + dPriv->x; + rmesa->state.scissor.rect.y1 = y + dPriv->y; + rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; + rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; + + radeonRecalcScissorRects( rmesa ); + } +} + +/* ============================================================= + * Scissoring + */ + +void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (ctx->Scissor.Enabled) { + /* We don't pipeline cliprect changes */ + radeon_firevertices(radeon); + radeonUpdateScissor(ctx); + } +} + + +/* ================================================================ + * 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) +{ + radeonContextPtr rmesa; + GLint nbox, i, ret; + GLboolean missed_target; + int64_t ust; + __DRIscreenPrivate *psp; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + + if ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); + } + + radeon_firevertices(rmesa); + 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->hw.all_dirty = GL_TRUE; + + } +} + +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 ( RADEON_DEBUG & DEBUG_IOCTL ) { + fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, + rmesa->sarea->pfCurrentPage); + } + + radeon_firevertices(rmesa); + + 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); +} + + +/** + * Swap front and back buffer. + */ +void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + radeonContextPtr radeon; + GLcontext *ctx; + + radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = radeon->glCtx; + + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ + if (radeon->doPageFlip) { + radeonPageFlip(dPriv); + } else { + radeonCopyBuffer(dPriv, NULL); + } + } + } 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(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h ) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + radeonContextPtr radeon; + GLcontext *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__); + } +} + + +static void radeon_print_state_atom( struct radeon_state_atom *state ) +{ + int i; + + fprintf(stderr, "emit %s/%d\n", state->name, state->cmd_size); + + if (RADEON_DEBUG & DEBUG_VERBOSE) + for (i = 0 ; i < state->cmd_size ; i++) + fprintf(stderr, "\t%s[%d]: %x\n", state->name, i, state->cmd[i]); + +} + +static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) +{ + BATCH_LOCALS(radeon); + struct radeon_state_atom *atom; + int dwords; + + if (radeon->vtbl.pre_emit_atoms) + radeon->vtbl.pre_emit_atoms(radeon); + + /* Emit actual atoms */ + foreach(atom, &radeon->hw.atomlist) { + if ((atom->dirty || radeon->hw.all_dirty) == dirty) { + dwords = (*atom->check) (radeon->glCtx, atom); + if (dwords) { + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { + radeon_print_state_atom(atom); + } + if (atom->emit) { + (*atom->emit)(radeon->glCtx, atom); + } else { + BEGIN_BATCH_NO_AUTOSTATE(dwords); + OUT_BATCH_TABLE(atom->cmd, dwords); + END_BATCH(); + } + atom->dirty = GL_FALSE; + } else { + if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) { + fprintf(stderr, " skip state %s\n", + atom->name); + } + } + } + } + + COMMIT_BATCH(); +} + +void radeonEmitState(radeonContextPtr radeon) +{ + if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (radeon->vtbl.pre_emit_state) + radeon->vtbl.pre_emit_state(radeon); + + /* this code used to return here but now it emits zbs */ + if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty) + return; + + /* To avoid going across the entire set of states multiple times, just check + * for enough space for the case of emitting all state, and inline the + * radeonAllocCmdBuf code here without all the checks. + */ + rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__); + + if (!radeon->cmdbuf.cs->cdw) { + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Begin reemit state\n"); + + radeonEmitAtoms(radeon, GL_FALSE); + } + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "Begin dirty state\n"); + + radeonEmitAtoms(radeon, GL_TRUE); + radeon->hw.is_dirty = GL_FALSE; + radeon->hw.all_dirty = GL_FALSE; + +} + + +void radeonFlush(GLcontext *ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (radeon->dma.flush) + radeon->dma.flush( ctx ); + + radeonEmitState(radeon); + + if (radeon->cmdbuf.cs->cdw) + rcommonFlushCmdBuf(radeon, __FUNCTION__); +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +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); + } +} + +/* cmdbuffer */ +/** + * Send the current command buffer via ioctl to the hardware. + */ +int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller) +{ + int ret = 0; + + if (rmesa->cmdbuf.flushing) { + fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n"); + exit(-1); + } + rmesa->cmdbuf.flushing = 1; + if (rmesa->cmdbuf.cs->cdw) { + ret = radeon_cs_emit(rmesa->cmdbuf.cs); + rmesa->hw.all_dirty = GL_TRUE; + } + radeon_cs_erase(rmesa->cmdbuf.cs); + rmesa->cmdbuf.flushing = 0; + return ret; +} + +int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller) +{ + int ret; + + radeonReleaseDmaRegion(rmesa); + + LOCK_HARDWARE(rmesa); + ret = rcommonFlushCmdBufLocked(rmesa, caller); + UNLOCK_HARDWARE(rmesa); + + if (ret) { + fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + _mesa_exit(ret); + } + + return ret; +} + +/** + * Make sure that enough space is available in the command buffer + * by flushing if necessary. + * + * \param dwords The number of dwords we need to be free on the command buffer + */ +void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller) +{ + if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size || + radeon_cs_need_flush(rmesa->cmdbuf.cs)) { + rcommonFlushCmdBuf(rmesa, caller); + } +} + +void rcommonInitCmdBuf(radeonContextPtr rmesa) +{ + GLuint size; + /* Initialize command buffer */ + size = 256 * driQueryOptioni(&rmesa->optionCache, + "command_buffer_size"); + if (size < 2 * rmesa->hw.max_state_size) { + size = 2 * rmesa->hw.max_state_size + 65535; + } + if (size > 64 * 256) + size = 64 * 256; + + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) { + fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n", + sizeof(drm_r300_cmd_header_t)); + fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", + sizeof(drm_radeon_cmd_buffer_t)); + fprintf(stderr, + "Allocating %d bytes command buffer (max state is %d bytes)\n", + size * 4, rmesa->hw.max_state_size * 4); + } + + if (rmesa->radeonScreen->kernel_mm) { + int fd = rmesa->radeonScreen->driScreen->fd; + rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd); + } else { + rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa); + } + if (rmesa->cmdbuf.csm == NULL) { + /* FIXME: fatal error */ + return; + } + rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size); + assert(rmesa->cmdbuf.cs != NULL); + rmesa->cmdbuf.size = size; + + if (!rmesa->radeonScreen->kernel_mm) { + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); + } else { + struct drm_radeon_gem_info mminfo; + + if (!drmCommandWriteRead(rmesa->dri.fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo))) + { + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, mminfo.vram_size); + radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, mminfo.gart_size); + } + } + +} +/** + * Destroy the command buffer + */ +void rcommonDestroyCmdBuf(radeonContextPtr rmesa) +{ + radeon_cs_destroy(rmesa->cmdbuf.cs); + if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) { + radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm); + } else { + radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm); + } +} + +void rcommonBeginBatch(radeonContextPtr rmesa, int n, + int dostate, + const char *file, + const char *function, + int line) +{ + rcommonEnsureCmdBufSpace(rmesa, n, function); + if (!rmesa->cmdbuf.cs->cdw && dostate) { + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "Reemit state after flush (from %s)\n", function); + radeonEmitState(rmesa); + } + radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line); +} + + + diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h new file mode 100644 index 0000000000..cc9d579ea1 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -0,0 +1,56 @@ +#ifndef COMMON_MISC_H +#define COMMON_MISC_H + +#include "radeon_common_context.h" +#include "radeon_buffer.h" +#include "radeon_dma.h" +#include "radeon_texture.h" + +void radeonRecalcScissorRects(radeonContextPtr radeon); +void radeonSetCliprects(radeonContextPtr radeon); +void radeonUpdateScissor( GLcontext *ctx ); +void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h); + +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 radeonSwapBuffers(__DRIdrawablePrivate * dPriv); +void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h ); + +void radeonUpdatePageFlipping(radeonContextPtr rmesa); + +void radeonFlush(GLcontext *ctx); +void radeonFinish(GLcontext * ctx); +void radeonEmitState(radeonContextPtr radeon); + +static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) +{ + struct radeon_renderbuffer *rrb; + rrb = rmesa->state.depth.rrb; + if (!rrb) + return NULL; + + return rrb; +} + +static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) +{ + struct radeon_renderbuffer *rrb; + GLframebuffer *fb = rmesa->dri.drawable->driverPrivate; + + rrb = rmesa->state.color.rrb; + if (rmesa->radeonScreen->driScreen->dri2.enabled) { + rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + } + if (!rrb) + return NULL; + return rrb; +} + +#include "radeon_cmdbuf.h" + + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c new file mode 100644 index 0000000000..8acde2b90c --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -0,0 +1,584 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "radeon_common.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ +#include "utils.h" +#include "drirenderbuffer.h" +#include "vblank.h" + +#define DRIVER_DATE "20090101" + +#ifndef RADEON_DEBUG +int RADEON_DEBUG = (0); +#endif + +/* Return various strings for glGetString(). + */ +static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + static char buffer[128]; + + switch (name) { + case GL_VENDOR: + if (IS_R300_CLASS(radeon->radeonScreen)) + return (GLubyte *) "DRI R300 Project"; + else + return (GLubyte *) "Tungsten Graphics, Inc."; + + case GL_RENDERER: + { + unsigned offset; + GLuint agp_mode = (radeon->radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : + radeon->radeonScreen->AGPMode; + const char* chipname; + + if (IS_R300_CLASS(radeon->radeonScreen)) + chipname = "R300"; + else if (IS_R200_CLASS(radeon->radeonScreen)) + chipname = "R200"; + else + chipname = "R100"; + + offset = driGetRendererString(buffer, chipname, DRIVER_DATE, + agp_mode); + + if (IS_R300_CLASS(radeon->radeonScreen)) { + sprintf(&buffer[offset], " %sTCL", + (radeon->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) + ? "" : "NO-"); + } else { + sprintf(&buffer[offset], " %sTCL", + !(radeon->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) + ? "" : "NO-"); + } + + if (radeon->radeonScreen->driScreen->dri2.enabled) + strcat(buffer, " DRI2"); + + return (GLubyte *) buffer; + } + + default: + return NULL; + } +} + +/* Initialize the driver's misc functions. + */ +static void radeonInitDriverFuncs(struct dd_function_table *functions) +{ + functions->GetString = radeonGetString; +} + +/** + * Create and initialize all common fields of the context, + * including the Mesa context itself. + */ +GLboolean radeonInitContext(radeonContextPtr radeon, + struct dd_function_table* functions, + const __GLcontextModes * glVisual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); + GLcontext* ctx; + GLcontext* shareCtx; + int fthrottle_mode; + + /* Fill in additional standard functions. */ + radeonInitDriverFuncs(functions); + + radeon->radeonScreen = screen; + /* Allocate and initialize the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + radeon->glCtx = _mesa_create_context(glVisual, shareCtx, + functions, (void *)radeon); + if (!radeon->glCtx) + return GL_FALSE; + + ctx = radeon->glCtx; + driContextPriv->driverPrivate = radeon; + + /* DRI fields */ + radeon->dri.context = driContextPriv; + radeon->dri.screen = sPriv; + radeon->dri.drawable = NULL; + radeon->dri.readable = NULL; + radeon->dri.hwContext = driContextPriv->hHWContext; + radeon->dri.hwLock = &sPriv->pSAREA->lock; + radeon->dri.fd = sPriv->fd; + radeon->dri.drmMinor = sPriv->drm_version.minor; + + radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + + screen->sarea_priv_offset); + + /* Setup IRQs */ + fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode"); + radeon->iw.irq_seq = -1; + radeon->irqsEmitted = 0; + radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS && + radeon->radeonScreen->irq); + + radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + if (!radeon->do_irqs) + fprintf(stderr, + "IRQ's not enabled, falling back to %s: %d %d\n", + radeon->do_usleeps ? "usleeps" : "busy waits", + fthrottle_mode, radeon->radeonScreen->irq); + + (*sPriv->systemTime->getUST) (&radeon->swap_ust); + + return GL_TRUE; +} + +/** + * Cleanup common context fields. + * Called by r200DestroyContext/r300DestroyContext + */ +void radeonCleanupContext(radeonContextPtr radeon) +{ + FILE *track; + struct radeon_renderbuffer *rb; + GLframebuffer *fb; + + /* free the Mesa context */ + _mesa_destroy_context(radeon->glCtx); + + fb = (void*)radeon->dri.drawable->driverPrivate; + rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + fb = (void*)radeon->dri.readable->driverPrivate; + rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (rb && rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + + /* _mesa_destroy_context() might result in calls to functions that + * depend on the DriverCtx, so don't set it to NULL before. + * + * radeon->glCtx->DriverCtx = NULL; + */ + + + + /* free the option cache */ + driDestroyOptionCache(&radeon->optionCache); + + rcommonDestroyCmdBuf(radeon); + + if (radeon->state.scissor.pClipRects) { + FREE(radeon->state.scissor.pClipRects); + radeon->state.scissor.pClipRects = 0; + } + track = fopen("/tmp/tracklog", "w"); + if (track) { + radeon_tracker_print(&radeon->radeonScreen->bom->tracker, track); + fclose(track); + } +} + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate; + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, + radeon->glCtx); + + return GL_TRUE; +} + + +static void +radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, + GLframebuffer *draw) +{ + /* if radeon->fake */ + struct radeon_renderbuffer *rb; + + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->frontOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->backOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } +} + +static void +radeon_make_renderbuffer_current(radeonContextPtr radeon, + GLframebuffer *draw) +{ + int size = 4096*4096*4; + /* if radeon->fake */ + struct radeon_renderbuffer *rb; + + if (radeon->radeonScreen->kernel_mm) { + radeon_make_kernel_renderbuffer_current(radeon, draw); + return; + } + + + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->frontOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->backOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } + if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if (!rb->bo) { + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + radeon->radeonScreen->depthOffset + + radeon->radeonScreen->fbLocation, + size, + 4096, + RADEON_GEM_DOMAIN_VRAM, + 0); + } + rb->cpp = radeon->radeonScreen->cpp; + rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; + } +} + + +void +radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +{ + unsigned int attachments[10]; + __DRIbuffer *buffers; + __DRIscreen *screen; + struct radeon_renderbuffer *rb; + int i, count; + GLframebuffer *draw; + radeonContextPtr radeon; + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); + + draw = drawable->driverPrivate; + screen = context->driScreenPriv; + radeon = (radeonContextPtr) context->driverPrivate; + i = 0; + if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + } + if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + } + if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + attachments[i++] = __DRI_BUFFER_DEPTH; + } + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + if (buffers == NULL) + return; + + /* set one cliprect to cover the whole drawable */ + drawable->x = 0; + drawable->y = 0; + drawable->backX = 0; + drawable->backY = 0; + drawable->numClipRects = 1; + drawable->pClipRects[0].x1 = 0; + drawable->pClipRects[0].y1 = 0; + drawable->pClipRects[0].x2 = drawable->w; + drawable->pClipRects[0].y2 = drawable->h; + drawable->numBackClipRects = 1; + drawable->pBackClipRects[0].x1 = 0; + drawable->pBackClipRects[0].y1 = 0; + drawable->pBackClipRects[0].x2 = drawable->w; + drawable->pBackClipRects[0].y2 = drawable->h; + for (i = 0; i < count; i++) { + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->width = drawable->w; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + if (rb->bo == NULL) { + fprintf(stderr, "failled to attach front %d\n", + buffers[i].name); + } + break; + case __DRI_BUFFER_BACK_LEFT: + rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->width = drawable->w; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + break; + case __DRI_BUFFER_DEPTH: + rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; + if (rb->bo) { + radeon_bo_unref(rb->bo); + rb->bo = NULL; + } + rb->cpp = buffers[i].cpp; + rb->pitch = buffers[i].pitch; + rb->width = drawable->w; + rb->height = drawable->h; + rb->has_surface = 0; + rb->bo = radeon_bo_open(radeon->radeonScreen->bom, + buffers[i].name, + 0, + 0, + RADEON_GEM_DOMAIN_VRAM, + buffers[i].flags); + break; + case __DRI_BUFFER_STENCIL: + break; + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + "unhandled buffer attach event, attacment type %d\n", + buffers[i].attachment); + return; + } + } + radeon = (radeonContextPtr) context->driverPrivate; + driUpdateFramebufferSize(radeon->glCtx, drawable); +} + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + radeonContextPtr radeon; + GLframebuffer *dfb, *rfb; + + if (!driContextPriv) { + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx is null\n", __FUNCTION__); + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + radeon = (radeonContextPtr) driContextPriv->driverPrivate; + dfb = driDrawPriv->driverPrivate; + rfb = driReadPriv->driverPrivate; + + if (driContextPriv->driScreenPriv->dri2.enabled) { + radeon_update_renderbuffers(driContextPriv, driDrawPriv); + if (driDrawPriv != driReadPriv) + radeon_update_renderbuffers(driContextPriv, driReadPriv); + radeon->state.color.rrb = + (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + radeon->state.depth.rrb = + (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; + } else { + radeon_make_renderbuffer_current(radeon, dfb); + } + + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb); + + driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); + if (driReadPriv != driDrawPriv) + driUpdateFramebufferSize(radeon->glCtx, driReadPriv); + + + + _mesa_make_current(radeon->glCtx, dfb, rfb); + + if (radeon->dri.drawable != driDrawPriv) { + if (driDrawPriv->swap_interval == (unsigned)-1) { + driDrawPriv->vblFlags = + (radeon->radeonScreen->irq != 0) + ? driGetDefaultVBlankFlags(&radeon-> + optionCache) + : VBLANK_FLAG_NO_IRQ; + + driDrawableInitVBlank(driDrawPriv); + } + } + + radeon->dri.readable = driReadPriv; + + if (radeon->dri.drawable != driDrawPriv || + radeon->lastStamp != driDrawPriv->lastStamp) { + radeon->dri.drawable = driDrawPriv; + + radeonSetCliprects(radeon); + radeon->vtbl.update_viewport_offset(radeon->glCtx); + } + + _mesa_update_state(radeon->glCtx); + + if (!driContextPriv->driScreenPriv->dri2.enabled) { + radeonUpdatePageFlipping(radeon); + } + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "End %s\n", __FUNCTION__); + return GL_TRUE; +} + diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h new file mode 100644 index 0000000000..b88aeab051 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -0,0 +1,513 @@ + +#ifndef COMMON_CONTEXT_H +#define COMMON_CONTEXT_H + +#include "main/mm.h" +#include "math/m_vector.h" +#include "texmem.h" +#include "tnl/t_context.h" +#include "main/colormac.h" + +#include "radeon_screen.h" +#include "radeon_drm.h" +#include "dri_util.h" +#include "tnl/t_vertex.h" + +/* This union is used to avoid warnings/miscompilation + with float to uint32_t casts due to strict-aliasing */ +typedef union { GLfloat f; uint32_t ui32; } float_ui32_type; + +struct radeon_context; +typedef struct radeon_context radeonContextRec; +typedef struct radeon_context *radeonContextPtr; + + +#define TEX_0 0x1 +#define TEX_1 0x2 +#define TEX_2 0x4 +#define TEX_3 0x8 +#define TEX_4 0x10 +#define TEX_5 0x20 + +/* Rasterizing fallbacks */ +/* See correponding strings in r200_swtcl.c */ +#define RADEON_FALLBACK_TEXTURE 0x0001 +#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +#define RADEON_FALLBACK_STENCIL 0x0004 +#define RADEON_FALLBACK_RENDER_MODE 0x0008 +#define RADEON_FALLBACK_BLEND_EQ 0x0010 +#define RADEON_FALLBACK_BLEND_FUNC 0x0020 +#define RADEON_FALLBACK_DISABLE 0x0040 +#define RADEON_FALLBACK_BORDER_MODE 0x0080 + +#define R200_FALLBACK_TEXTURE 0x01 +#define R200_FALLBACK_DRAW_BUFFER 0x02 +#define R200_FALLBACK_STENCIL 0x04 +#define R200_FALLBACK_RENDER_MODE 0x08 +#define R200_FALLBACK_DISABLE 0x10 +#define R200_FALLBACK_BORDER_MODE 0x20 + +#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */ +#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */ +#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */ +#define RADEON_TCL_FALLBACK_MATERIAL 0x8 /* material in vb */ +#define RADEON_TCL_FALLBACK_TEXGEN_0 0x10 /* texgen, unit 0 */ +#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */ +#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */ +#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */ +#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */ + +/* The blit width for texture uploads + */ +#define BLIT_WIDTH_BYTES 1024 + +/* Use the templated vertex format: + */ +#define COLOR_IS_RGBA +#define TAG(x) radeon##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +struct radeon_colorbuffer_state { + GLuint clear; + int roundEnable; + struct radeon_renderbuffer *rrb; +}; + +struct radeon_depthbuffer_state { + GLuint clear; + GLfloat scale; + struct radeon_renderbuffer *rrb; +}; + +struct radeon_scissor_state { + drm_clip_rect_t rect; + GLboolean enabled; + + GLuint numClipRects; /* Cliprects active */ + GLuint numAllocedClipRects; /* Cliprects available */ + drm_clip_rect_t *pClipRects; +}; + +struct radeon_stencilbuffer_state { + GLboolean hwBuffer; + GLuint clear; /* rb3d_stencilrefmask value */ +}; + +struct radeon_stipple_state { + GLuint mask[32]; +}; + +struct radeon_state_atom { + struct radeon_state_atom *next, *prev; + const char *name; /* for debug */ + int cmd_size; /* size in bytes */ + GLuint idx; + GLuint is_tcl; + GLuint *cmd; /* one or more cmd's */ + GLuint *lastcmd; /* one or more cmd's */ + GLboolean dirty; /* dirty-mark in emit_state_list */ + int (*check) (GLcontext *, struct radeon_state_atom *atom); /* is this state active? */ + void (*emit) (GLcontext *, struct radeon_state_atom *atom); +}; + +struct radeon_hw_state { + /* Head of the linked list of state atoms. */ + struct radeon_state_atom atomlist; + int max_state_size; /* Number of bytes necessary for a full state emit. */ + GLboolean is_dirty, all_dirty; +}; + + +/* Texture related */ +typedef struct _radeon_texture_image radeon_texture_image; + +struct _radeon_texture_image { + struct gl_texture_image base; + + /** + * If mt != 0, the image is stored in hardware format in the + * given mipmap tree. In this case, base.Data may point into the + * mapping of the buffer object that contains the mipmap tree. + * + * If mt == 0, the image is stored in normal memory pointed to + * by base.Data. + */ + struct _radeon_mipmap_tree *mt; + struct radeon_bo *bo; + + int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ + int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ +}; + + +static INLINE radeon_texture_image *get_radeon_texture_image(struct gl_texture_image *image) +{ + return (radeon_texture_image*)image; +} + + +typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; + +#define RADEON_TXO_MICRO_TILE (1 << 3) + +/* Texture object in locally shared texture space. + */ +struct radeon_tex_obj { + // driTextureObject base; + struct gl_texture_object base; + struct _radeon_mipmap_tree *mt; + + /** + * This is true if we've verified that the mipmap tree above is complete + * and so on. + */ + GLboolean validated; + + GLuint override_offset; + GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ + GLuint tile_bits; /* hw texture tile bits used on this texture */ + struct radeon_bo *bo; + + GLuint bufAddr; /* Offset to start of locally + shared texture block */ + + GLuint dirty_state; /* Flags (1 per texunit) for + whether or not this texobj + has dirty hardware state + (pp_*) that needs to be + brought into the + texunit. */ + + drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; + /* Six, for the cube faces */ + + + + GLuint pp_txfilter; /* hardware register values */ + GLuint pp_txformat; + GLuint pp_txformat_x; + GLuint pp_txoffset; /* Image location in texmem. + All cube faces follow. */ + GLuint pp_txsize; /* npot only */ + GLuint pp_txpitch; /* npot only */ + GLuint pp_border_color; + GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ + + GLuint pp_txfilter_1; /* r300 */ + + GLboolean border_fallback; + + +}; + +static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) +{ + return (radeonTexObj*)texObj; +} + +/* Need refcounting on dma buffers: + */ +struct radeon_dma_buffer { + int refcount; /* the number of retained regions in buf */ + drmBufPtr buf; +}; + +struct radeon_aos { + struct radeon_bo *bo; /** Buffer object where vertex data is stored */ + int offset; /** Offset into buffer object, in bytes */ + int components; /** Number of components per vertex */ + int stride; /** Stride in dwords (may be 0 for repeating) */ + int count; /** Number of vertices */ +}; + +struct radeon_dma { + /* Active dma region. Allocations for vertices and retained + * regions come from here. Also used for emitting random vertices, + * these may be flushed by calling flush_current(); + */ + struct radeon_bo *current; /** Buffer that DMA memory is allocated from */ + int current_used; /** Number of bytes allocated and forgotten about */ + int current_vertexptr; /** End of active vertex region */ + + /** + * If current_vertexptr != current_used then flush must be non-zero. + * flush must be called before non-active vertex allocations can be + * performed. + */ + void (*flush) (GLcontext *); + + /* Number of "in-flight" DMA buffers, i.e. the number of buffers + * for which a DISCARD command is currently queued in the command buffer +. + */ + GLuint nr_released_bufs; +}; + +/* radeon_swtcl.c + */ +struct radeon_swtcl_info { + + GLuint RenderIndex; + GLuint vertex_size; + GLubyte *verts; + + /* Fallback rasterization functions + */ + GLuint hw_primitive; + GLenum render_primitive; + GLuint numverts; + + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + +}; + +struct radeon_ioctl { + GLuint vertex_offset; + struct radeon_bo *bo; + GLuint vertex_size; +}; + +#define RADEON_MAX_PRIMS 64 + +struct radeon_prim { + GLuint start; + GLuint end; + GLuint prim; +}; + +static INLINE GLuint radeonPackColor(GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (cpp) { + case 2: + return PACK_COLOR_565(r, g, b); + case 4: + return PACK_COLOR_8888(a, r, g, b); + default: + return 0; + } +} + +#define MAX_CMD_BUF_SZ (16*1024) + +#define MAX_DMA_BUF_SZ (64*1024) + +struct radeon_store { + GLuint statenr; + GLuint primnr; + char cmd_buf[MAX_CMD_BUF_SZ]; + int cmd_used; + int elts_start; +}; + +struct radeon_dri_mirror { + __DRIcontextPrivate *context; /* DRI context */ + __DRIscreenPrivate *screen; /* DRI screen */ + + /** + * DRI drawable bound to this context for drawing. + */ + __DRIdrawablePrivate *drawable; + + /** + * DRI drawable bound to this context for reading. + */ + __DRIdrawablePrivate *readable; + + drm_context_t hwContext; + drm_hw_lock_t *hwLock; + int fd; + int drmMinor; +}; + +#define DEBUG_TEXTURE 0x001 +#define DEBUG_STATE 0x002 +#define DEBUG_IOCTL 0x004 +#define DEBUG_PRIMS 0x008 +#define DEBUG_VERTS 0x010 +#define DEBUG_FALLBACKS 0x020 +#define DEBUG_VFMT 0x040 +#define DEBUG_CODEGEN 0x080 +#define DEBUG_VERBOSE 0x100 +#define DEBUG_DRI 0x200 +#define DEBUG_DMA 0x400 +#define DEBUG_SANITY 0x800 +#define DEBUG_SYNC 0x1000 +#define DEBUG_PIXEL 0x2000 +#define DEBUG_MEMORY 0x4000 + + + +typedef void (*radeon_tri_func) (radeonContextPtr, + radeonVertex *, + radeonVertex *, radeonVertex *); + +typedef void (*radeon_line_func) (radeonContextPtr, + radeonVertex *, radeonVertex *); + +typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *); + +struct radeon_state { + struct radeon_colorbuffer_state color; + struct radeon_depthbuffer_state depth; + struct radeon_scissor_state scissor; + struct radeon_stencilbuffer_state stencil; +}; + +/** + * This structure holds the command buffer while it is being constructed. + * + * The first batch of commands in the buffer is always the state that needs + * to be re-emitted when the context is lost. This batch can be skipped + * otherwise. + */ +struct radeon_cmdbuf { + struct radeon_cs_manager *csm; + struct radeon_cs *cs; + int size; /** # of dwords total */ + unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */ +}; + +struct radeon_context { + GLcontext *glCtx; + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + + /* Texture object bookkeeping + */ + unsigned nr_heaps; + driTexHeap * texture_heaps[ RADEON_NR_TEX_HEAPS ]; + driTextureObject swapped; + int texture_depth; + float initialMaxAnisotropy; + + struct radeon_dma dma; + struct radeon_hw_state hw; + /* Rasterization and vertex state: + */ + GLuint TclFallback; + GLuint Fallback; + GLuint NewGLState; + DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ + + /* Page flipping */ + GLuint doPageFlip; + + /* Drawable, cliprect and scissor information */ + GLuint numClipRects; /* Cliprects for the draw buffer */ + drm_clip_rect_t *pClipRects; + unsigned int lastStamp; + GLboolean lost_context; + drm_radeon_sarea_t *sarea; /* Private SAREA data */ + + /* Mirrors of some DRI state */ + struct radeon_dri_mirror dri; + + /* Busy waiting */ + GLuint do_usleeps; + GLuint do_irqs; + GLuint irqsEmitted; + drm_radeon_irq_wait_t iw; + + /* buffer swap */ + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + /* Derived state - for r300 only */ + struct radeon_state state; + + struct radeon_swtcl_info swtcl; + /* Configuration cache + */ + driOptionCache optionCache; + + struct radeon_cmdbuf cmdbuf; + + struct { + void (*get_lock)(radeonContextPtr radeon); + void (*update_viewport_offset)(GLcontext *ctx); + void (*update_draw_buffer)(GLcontext *ctx); + void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); + void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); + void (*pre_emit_atoms)(radeonContextPtr rmesa); + void (*pre_emit_state)(radeonContextPtr rmesa); + } vtbl; +}; + +#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx)) + +/** + * This function takes a float and packs it into a uint32_t + */ +static INLINE uint32_t radeonPackFloat32(float fl) +{ + union { + float fl; + uint32_t u; + } u; + + u.fl = fl; + return u.u; +} + +/* This is probably wrong for some values, I need to test this + * some more. Range checking would be a good idea also.. + * + * But it works for most things. I'll fix it later if someone + * else with a better clue doesn't + */ +static INLINE uint32_t radeonPackFloat24(float f) +{ + float mantissa; + int exponent; + uint32_t float24 = 0; + + if (f == 0.0) + return 0; + + mantissa = frexpf(f, &exponent); + + /* Handle -ve */ + if (mantissa < 0) { + float24 |= (1 << 23); + mantissa = mantissa * -1.0; + } + /* Handle exponent, bias of 63 */ + exponent += 62; + float24 |= (exponent << 16); + /* Kill 7 LSB of mantissa */ + float24 |= (radeonPackFloat32(mantissa) & 0x7FFFFF) >> 7; + + return float24; +} + +GLboolean radeonInitContext(radeonContextPtr radeon, + struct dd_function_table* functions, + const __GLcontextModes * glVisual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +void radeonCleanupContext(radeonContextPtr radeon); +GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv); +void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); +GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 + +#if DO_DEBUG +extern int RADEON_DEBUG; +#else +#define RADEON_DEBUG 0 +#endif + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index b25f036c44..0296cffc20 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -53,8 +53,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drivers/common/driverfuncs.h" +#include "radeon_common.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_span.h" @@ -77,36 +77,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ -/* Return various strings for glGetString(). - */ -static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - static char buffer[128]; - unsigned offset; - GLuint agp_mode = (rmesa->radeon.radeonScreen->card_type==RADEON_CARD_PCI) ? 0 : - rmesa->radeon.radeonScreen->AGPMode; - - switch ( name ) { - case GL_VENDOR: - return (GLubyte *)"Tungsten Graphics, Inc."; - - case GL_RENDERER: - offset = driGetRendererString( buffer, "Radeon", DRIVER_DATE, - agp_mode ); - - sprintf( & buffer[ offset ], " %sTCL", - !(rmesa->radeon.TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) - ? "" : "NO-" ); - - return (GLubyte *)buffer; - - default: - return NULL; - } -} - - /* Extension strings exported by the R100 driver. */ const struct dri_extension card_extensions[] = @@ -163,15 +133,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = { NULL, }; - - -/* Initialize the driver's misc functions. - */ -static void radeonInitDriverFuncs( struct dd_function_table *functions ) -{ - functions->GetString = radeonGetString; -} - static const struct dri_debug_control debug_control[] = { { "fall", DEBUG_FALLBACKS }, @@ -292,7 +253,6 @@ radeonCreateContext( const __GLcontextModes *glVisual, * (the texture functions are especially important) */ _mesa_init_driver_functions( &functions ); - radeonInitDriverFuncs( &functions ); radeonInitTextureFuncs( &functions ); if (!radeonInitContext(&rmesa->radeon, &functions, diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index d05e47f16e..2efabd1f55 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -53,8 +53,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "radeon_screen.h" -#include "common_context.h" -#include "common_misc.h" +#include "radeon_common.h" struct r100_context; diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index fbb93a8ba1..2db3f7a68d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -31,8 +31,6 @@ */ #include - -#include "common_context.h" #include "radeon_cs.h" #include "radeon_cs_legacy.h" #include "radeon_bo_legacy.h" @@ -234,7 +232,7 @@ static int cs_process_relocs(struct radeon_cs *cs) } cs->packets[relocs[i].indices[j]] += soffset; if (cs->packets[relocs[i].indices[j]] >= eoffset) { - radeon_bo_debug(relocs[i].base.bo, 12); + /* radeon_bo_debug(relocs[i].base.bo, 12); */ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n", relocs[i].base.bo, soffset, eoffset); fprintf(stderr, "above end: %p 0x%08X 0x%08X\n", diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h index 4da2479eee..19d904174f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h @@ -33,7 +33,7 @@ #define RADEON_CS_LEGACY_H #include "radeon_cs.h" -#include "common_context.h" +#include "radeon_common.h" struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx); void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm); diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c new file mode 100644 index 0000000000..393b12182d --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -0,0 +1,323 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "radeon_common.h" + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \ + : "0" (nr), \ + "D" ((long)dst), \ + "S" ((long)src) ); \ +} while (0) +#else +#define COPY_DWORDS( dst, src, nr ) \ +do { \ + int j; \ + for ( j = 0 ; j < nr ; j++ ) \ + dst[j] = ((int *)src)[j]; \ + dst += nr; \ +} while (0) +#endif + +static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 4) + COPY_DWORDS(out, data, count); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out++; + data += stride; + } +} + +void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 8) + COPY_DWORDS(out, data, count * 2); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out += 2; + data += stride; + } +} + +void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 12) { + COPY_DWORDS(out, data, count * 3); + } + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out[2] = *(int *)(data + 8); + out += 3; + data += stride; + } +} + +static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count) +{ + int i; + + if (RADEON_DEBUG & DEBUG_VERTS) + fprintf(stderr, "%s count %d stride %d out %p data %p\n", + __FUNCTION__, count, stride, (void *)out, (void *)data); + + if (stride == 16) + COPY_DWORDS(out, data, count * 4); + else + for (i = 0; i < count; i++) { + out[0] = *(int *)data; + out[1] = *(int *)(data + 4); + out[2] = *(int *)(data + 8); + out[3] = *(int *)(data + 12); + out += 4; + data += stride; + } +} + +void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, + GLvoid * data, int size, int stride, int count) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + uint32_t *out; + + if (stride == 0) { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32); + count = 1; + aos->stride = 0; + } else { + radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32); + aos->stride = size; + } + + aos->components = size; + aos->count = count; + + out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + switch (size) { + case 1: radeonEmitVec4(out, data, stride, count); break; + case 2: radeonEmitVec8(out, data, stride, count); break; + case 3: radeonEmitVec12(out, data, stride, count); break; + case 4: radeonEmitVec16(out, data, stride, count); break; + default: + assert(0); + break; + } +} + +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size) +{ + struct radeon_cs_space_check bos[1]; + int flushed = 0, ret; + + size = MAX2(size, MAX_DMA_BUF_SZ * 16); + + if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (rmesa->dma.flush) { + rmesa->dma.flush(rmesa->glCtx); + } + + if (rmesa->dma.nr_released_bufs > 4) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + rmesa->dma.nr_released_bufs = 0; + } + + if (rmesa->dma.current) { + radeon_bo_unmap(rmesa->dma.current); + radeon_bo_unref(rmesa->dma.current); + rmesa->dma.current = 0; + } + +again_alloc: + rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom, + 0, size, 4, RADEON_GEM_DOMAIN_GTT, + 0); + + if (!rmesa->dma.current) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + rmesa->dma.nr_released_bufs = 0; + goto again_alloc; + } + + rmesa->dma.current_used = 0; + rmesa->dma.current_vertexptr = 0; + + bos[0].bo = rmesa->dma.current; + bos[0].read_domains = RADEON_GEM_DOMAIN_GTT; + bos[0].write_domain =0 ; + bos[0].new_accounted = 0; + + ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) { + fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen"); + assert(0); + } else if (ret == RADEON_CS_SPACE_FLUSH) { + rcommonFlushCmdBuf(rmesa, __FUNCTION__); + if (flushed) { + fprintf(stderr,"flushed but still no space\n"); + assert(0); + } + flushed = 1; + goto again_alloc; + } + radeon_bo_map(rmesa->dma.current, 1); +} + +/* Allocates a region from rmesa->dma.current. If there isn't enough + * space in current, grab a new buffer (and discard what was left of current) + */ +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %d\n", __FUNCTION__, bytes); + + if (rmesa->dma.flush) + rmesa->dma.flush(rmesa->glCtx); + + assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr); + + alignment--; + rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment; + + if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size) + radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15); + + *poffset = rmesa->dma.current_used; + *pbo = rmesa->dma.current; + radeon_bo_ref(*pbo); + + /* Always align to at least 16 bytes */ + rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15; + rmesa->dma.current_vertexptr = rmesa->dma.current_used; + + assert(rmesa->dma.current_used <= rmesa->dma.current->size); +} + +void radeonReleaseDmaRegion(radeonContextPtr rmesa) +{ + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current); + if (rmesa->dma.current) { + rmesa->dma.nr_released_bufs++; + radeon_bo_unmap(rmesa->dma.current); + radeon_bo_unref(rmesa->dma.current); + } + rmesa->dma.current = NULL; +} + + +/* Flush vertices in the current dma region. + */ +void rcommon_flush_last_swtcl_prim( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_dma *dma = &rmesa->dma; + + + if (RADEON_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + dma->flush = NULL; + + if (dma->current) { + GLuint current_offset = dma->current_used; + + assert (dma->current_used + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + dma->current_vertexptr); + + if (dma->current_used != dma->current_vertexptr) { + dma->current_used = dma->current_vertexptr; + + rmesa->vtbl.swtcl_flush(ctx, current_offset); + } + rmesa->swtcl.numverts = 0; + } +} +/* Alloc space in the current dma region. + */ +void * +rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize ) +{ + GLuint bytes = vsize * nverts; + void *head; + + if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) { + radeonRefillCurrentDmaRegion(rmesa, bytes); + } + + if (!rmesa->dma.flush) { + rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + rmesa->dma.flush = rcommon_flush_last_swtcl_prim; + } + + ASSERT( vsize == rmesa->swtcl.vertex_size * 4 ); + ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim ); + ASSERT( rmesa->dma.current_used + + rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 == + rmesa->dma.current_vertexptr ); + + head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr); + rmesa->dma.current_vertexptr += bytes; + rmesa->swtcl.numverts += nverts; + return head; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.h b/src/mesa/drivers/dri/radeon/radeon_dma.h new file mode 100644 index 0000000000..cee3744fed --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_dma.h @@ -0,0 +1,51 @@ +/************************************************************************** + +Copyright (C) 2004 Nicolai Haehnle. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef RADEON_DMA_H +#define RADEON_DMA_H + +void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count); +void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count); + +void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos, + GLvoid * data, int size, int stride, int count); + +void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size); +void radeonAllocDmaRegion(radeonContextPtr rmesa, + struct radeon_bo **pbo, int *poffset, + int bytes, int alignment); +void radeonReleaseDmaRegion(radeonContextPtr rmesa); + +void rcommon_flush_last_swtcl_prim(GLcontext *ctx); + +void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize); +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index d0cd9ce7a6..99b1ef332f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "radeon_context.h" -#include "common_cmdbuf.h" +#include "radeon_common.h" #include "radeon_cs.h" #include "radeon_state.h" #include "radeon_ioctl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c new file mode 100644 index 0000000000..9a7e76b245 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -0,0 +1,124 @@ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. +Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + +The Weather Channel (TM) funded Tungsten Graphics to develop the +initial release of the Radeon 8500 driver under the XFree86 license. +This notice must be preserved. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Keith Whitwell + * Kevin E. Martin + */ + +#include "main/glheader.h" +#include "main/mtypes.h" +#include "main/colormac.h" +#include "dri_util.h" +#include "radeon_screen.h" +#include "radeon_common.h" +#include "radeon_lock.h" +#include "drirenderbuffer.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + +/* Turn on/off page flipping according to the flags in the sarea: + */ +void radeonUpdatePageFlipping(radeonContextPtr rmesa) +{ + int use_back; + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + GLframebuffer *fb = drawable->driverPrivate; + + rmesa->doPageFlip = rmesa->sarea->pfState; + if (rmesa->glCtx->WinSysDrawBuffer) { + rmesa->vtbl.update_draw_buffer(rmesa->glCtx); + } + + use_back = rmesa->glCtx->DrawBuffer ? + (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == + BUFFER_BACK_LEFT) : 1; + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if (use_back) + rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + else + rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + + rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; +} + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void radeonGetLock(radeonContextPtr rmesa, GLuint flags) +{ + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + __DRIscreenPrivate *sPriv = rmesa->dri.screen; + drm_radeon_sarea_t *sarea = rmesa->sarea; + + assert(drawable != NULL); + + drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); + } + + if (rmesa->lastStamp != drawable->lastStamp) { + radeonUpdatePageFlipping(rmesa); + radeonSetCliprects(rmesa); + rmesa->vtbl.update_viewport_offset(rmesa->glCtx); + driUpdateFramebufferSize(rmesa->glCtx, drawable); + } + + rmesa->vtbl.get_lock(rmesa); + + rmesa->lost_context = GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index f2d17a54d4..f5ebb8dd54 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -39,9 +39,82 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin */ -#ifndef __RADEON_LOCK_H__ -#define __RADEON_LOCK_H__ +#ifndef COMMON_LOCK_H +#define COMMON_LOCK_H -#include "common_lock.h" +#include "main/colormac.h" +#include "radeon_screen.h" +#include "radeon_common.h" -#endif /* __RADEON_LOCK_H__ */ +extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); + +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 + +#if DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if ( prevLockFile ) { \ + fprintf( stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ + exit( 1 ); \ + } \ + } while (0) + +#else + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + +#endif + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( rmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ + (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( (rmesa), 0 ); \ + } \ + DEBUG_LOCK(); \ + } while (0) + +#define UNLOCK_HARDWARE( rmesa ) \ + do { \ + if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ + DRM_UNLOCK( (rmesa)->dri.fd, \ + (rmesa)->dri.hwLock, \ + (rmesa)->dri.hwContext ); \ + DEBUG_RESET(); \ + } \ + } while (0) + +#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index 875e5e5aee..43dfa48aa7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -28,7 +28,7 @@ #ifndef __RADEON_MIPMAP_TREE_H_ #define __RADEON_MIPMAP_TREE_H_ -#include "common_context.h" +#include "radeon_common.h" typedef struct _radeon_mipmap_tree radeon_mipmap_tree; typedef struct _radeon_mipmap_level radeon_mipmap_level; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 7397218fb6..7f0d526ed2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -47,7 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_macros.h" #include "radeon_screen.h" #include "radeon_buffer.h" -#include "common_misc.h" +#include "radeon_common.h" #include "radeon_span.h" #if !RADEON_COMMON #include "radeon_context.h" @@ -362,7 +362,7 @@ static const __DRItexBufferExtension r300TexBufferExtension = { }; #endif -int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) +static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) { screen->chip_flags = 0; switch ( device_id ) { diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index bd613f4779..ebd18a1634 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -43,14 +43,154 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "swrast/swrast.h" -#include "common_context.h" -#include "common_misc.h" +#include "radeon_common.h" +#include "radeon_lock.h" #include "radeon_span.h" #include "radeon_buffer.h" #define DBG 0 +static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + const __DRIdrawablePrivate *dPriv = rrb->dPriv; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint nmacroblkpl; + GLint nmicroblkpl; + + x += dPriv->x; + y += dPriv->y; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + nmacroblkpl = rrb->pitch >> 5; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x >> 5) << 11; + offset += ((x & 31) >> 2) << 5; + offset += (x & 3) << 2; + } else { + nmacroblkpl = rrb->pitch >> 6; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x >> 6) << 11; + offset += ((x & 63) >> 3) << 5; + offset += (x & 7) << 2; + } + } else { + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x >> 3) << 5; + offset += (x & 7) << 2; + } + } + return &ptr[offset]; +} + +static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + const __DRIdrawablePrivate *dPriv = rrb->dPriv; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint nmacroblkpl; + GLint nmicroblkpl; + + x += dPriv->x; + y += dPriv->y; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + nmacroblkpl = rrb->pitch >> 6; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x >> 6) << 11; + offset += ((x & 63) >> 3) << 5; + offset += (x & 7) << 1; + } else { + nmacroblkpl = rrb->pitch >> 7; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x >> 7) << 11; + offset += ((x & 127) >> 4) << 5; + offset += (x & 15) << 2; + } + } else { + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x >> 4) << 5; + offset += (x & 15) << 2; + } + } + return &ptr[offset]; +} + +static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) +{ + GLubyte *ptr = rrb->bo->ptr; + const __DRIdrawablePrivate *dPriv = rrb->dPriv; + uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; + GLint offset; + GLint microblkxs; + GLint macroblkxs; + GLint nmacroblkpl; + GLint nmicroblkpl; + + x += dPriv->x; + y += dPriv->y; + + if (rrb->has_surface || !(rrb->bo->flags & mask)) { + offset = x * rrb->cpp + y * rrb->pitch; + } else { + offset = 0; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + microblkxs = 16 / rrb->cpp; + macroblkxs = 128 / rrb->cpp; + nmacroblkpl = rrb->pitch / macroblkxs; + offset += ((y >> 4) * nmacroblkpl) << 11; + offset += ((y & 15) >> 1) << 8; + offset += (y & 1) << 4; + offset += (x / macroblkxs) << 11; + offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } else { + microblkxs = 32 / rrb->cpp; + macroblkxs = 256 / rrb->cpp; + nmacroblkpl = rrb->pitch / macroblkxs; + offset += ((y >> 3) * nmacroblkpl) << 11; + offset += (y & 7) << 8; + offset += (x / macroblkxs) << 11; + offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } + } else { + microblkxs = 32 / rrb->cpp; + nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; + offset += (y * nmicroblkpl) << 5; + offset += (x / microblkxs) << 5; + offset += (x & (microblkxs - 1)) * rrb->cpp; + } + } + return &ptr[offset]; +} + + /* * Note that all information needed to access pixels in a renderbuffer * should be obtained through the gl_renderbuffer parameter, not per-context @@ -215,6 +355,88 @@ do { \ #define TAG(x) radeon##x##_z24_s8 #include "stenciltmp.h" + +static void map_buffer(struct gl_renderbuffer *rb, GLboolean write) +{ + struct radeon_renderbuffer *rrb = (void*)rb; + int r; + + if (rrb->bo) { + r = radeon_bo_map(rrb->bo, write); + if (r) { + fprintf(stderr, "(%s) error(%d) mapping buffer.\n", + __FUNCTION__, r); + } + } +} + +static void unmap_buffer(struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = (void*)rb; + + if (rrb->bo) { + radeon_bo_unmap(rrb->bo); + } +} + +static void radeonSpanRenderStart(GLcontext * ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int i; + + radeon_firevertices(rmesa); + + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); + } + + /* color draw buffers */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE); + } + + map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE); + + if (ctx->DrawBuffer->_DepthBuffer) { + map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE); + } + if (ctx->DrawBuffer->_StencilBuffer) + map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE); + + /* The locking and wait for idle should really only be needed in classic mode. + * In a future memory manager based implementation, this should become + * unnecessary due to the fact that mapping our buffers, textures, etc. + * should implicitly wait for any previous rendering commands that must + * be waited on. */ + LOCK_HARDWARE(rmesa); + radeonWaitForIdleLocked(rmesa); +} + +static void radeonSpanRenderFinish(GLcontext * ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int i; + _swrast_flush(ctx); + UNLOCK_HARDWARE(rmesa); + + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current); + } + + /* color draw buffers */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) + unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); + + unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer); + + if (ctx->DrawBuffer->_DepthBuffer) + unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); + if (ctx->DrawBuffer->_StencilBuffer) + unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); +} + void radeonInitSpanFuncs(GLcontext * ctx) { struct swrast_device_driver *swdd = diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 7f90bc8090..86d872030b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -47,7 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_tcl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 1cfb539e71..a397c0824f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -38,7 +38,6 @@ #include "swrast_setup/swrast_setup.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_cs.h" #include "radeon_mipmap_tree.h" #include "radeon_ioctl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index 995ab2099e..af933a35f2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_pipeline.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_ioctl.h" #include "radeon_state.h" #include "radeon_swtcl.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index 7281800ce2..5887ab355d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -42,8 +42,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" +#include "radeon_common.h" #include "radeon_context.h" -#include "common_cmdbuf.h" #include "radeon_state.h" #include "radeon_ioctl.h" #include "radeon_tex.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c new file mode 100644 index 0000000000..beb21e7b43 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -0,0 +1,849 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/mipmap.h" +#include "main/texformat.h" +#include "main/texstore.h" +#include "main/teximage.h" +#include "main/texobj.h" + +#include "xmlpool.h" /* for symbolic values of enum-type options */ + +#include "radeon_common.h" + +#include "radeon_mipmap_tree.h" + +/* textures */ +/** + * Allocate an empty texture image object. + */ +struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) +{ + return CALLOC(sizeof(radeon_texture_image)); +} + +/** + * Free memory associated with this texture image. + */ +void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) +{ + radeon_texture_image* image = get_radeon_texture_image(timage); + + if (image->mt) { + radeon_miptree_unreference(image->mt); + image->mt = 0; + assert(!image->base.Data); + } else { + _mesa_free_texture_image_data(ctx, timage); + } + if (image->bo) { + radeon_bo_unref(image->bo); + image->bo = NULL; + } + if (timage->Data) { + _mesa_free_texmemory(timage->Data); + timage->Data = NULL; + } +} + +/* Set Data pointer and additional data for mapped texture image */ +static void teximage_set_map_data(radeon_texture_image *image) +{ + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + + image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; + image->base.RowStride = lvl->rowstride / image->mt->bpp; +} + + +/** + * Map a single texture image for glTexImage and friends. + */ +void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) +{ + if (image->mt) { + assert(!image->base.Data); + + radeon_bo_map(image->mt->bo, write_enable); + teximage_set_map_data(image); + } +} + + +void radeon_teximage_unmap(radeon_texture_image *image) +{ + if (image->mt) { + assert(image->base.Data); + + image->base.Data = 0; + radeon_bo_unmap(image->mt->bo); + } +} + +/** + * Map a validated texture for reading during software rendering. + */ +void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) +{ + radeonTexObj* t = radeon_tex_obj(texObj); + int face, level; + + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) + return; + + radeon_bo_map(t->mt->bo, GL_FALSE); + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); + } +} + +void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) +{ + radeonTexObj* t = radeon_tex_obj(texObj); + int face, level; + + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) + return; + + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) + texObj->Image[face][level]->Data = 0; + } + radeon_bo_unmap(t->mt->bo); +} + +GLuint radeon_face_for_target(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + default: + return 0; + } +} + +/** + * Wraps Mesa's implementation to ensure that the base level image is mapped. + * + * This relies on internal details of _mesa_generate_mipmap, in particular + * the fact that the memory for recreated texture images is always freed. + */ +static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + radeonTexObj* t = radeon_tex_obj(texObj); + GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int i, face; + + + _mesa_generate_mipmap(ctx, target, texObj); + + for (face = 0; face < nr_faces; face++) { + for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { + radeon_texture_image *image; + + image = get_radeon_texture_image(texObj->Image[face][i]); + + if (image == NULL) + break; + + image->mtlevel = i; + image->mtface = face; + + radeon_miptree_unreference(image->mt); + image->mt = NULL; + } + } + +} + +void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) +{ + GLuint face = radeon_face_for_target(target); + radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); + + radeon_teximage_map(baseimage, GL_FALSE); + radeon_generate_mipmap(ctx, target, texObj); + radeon_teximage_unmap(baseimage); +} + + +/* try to find a format which will only need a memcopy */ +static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa, + GLenum srcFormat, + GLenum srcType) +{ + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *)&ui); + + /* r100 can only do this */ + if (IS_R100_CLASS(rmesa->radeonScreen)) + return _dri_texformat_argb8888; + + if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { + return &_mesa_texformat_rgba8888; + } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || + (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || + (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { + return &_mesa_texformat_rgba8888_rev; + } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || + srcType == GL_UNSIGNED_INT_8_8_8_8)) { + return &_mesa_texformat_argb8888_rev; + } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { + return &_mesa_texformat_argb8888; + } else + return _dri_texformat_argb8888; +} + +const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + const GLboolean do32bpt = + (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); + const GLboolean force16bpt = + (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); + (void)format; + +#if 0 + fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", + _mesa_lookup_enum_by_nr(internalFormat), internalFormat, + _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); + fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); +#endif + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + switch (type) { + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return do32bpt ? _dri_texformat_argb8888 : + _dri_texformat_argb1555; + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return _dri_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return _dri_texformat_argb1555; + default: + return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) : + _dri_texformat_argb4444; + } + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return _dri_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return _dri_texformat_argb1555; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return _dri_texformat_rgb565; + default: + return do32bpt ? _dri_texformat_argb8888 : + _dri_texformat_rgb565; + } + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return !force16bpt ? + radeonChoose8888TexFormat(rmesa, format,type) : + _dri_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return _dri_texformat_argb4444; + + case GL_RGB5_A1: + return _dri_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return !force16bpt ? _dri_texformat_argb8888 : + _dri_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return _dri_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return _dri_texformat_a8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return _dri_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return _dri_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return _dri_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + + case GL_ALPHA16F_ARB: + return &_mesa_texformat_alpha_float16; + case GL_ALPHA32F_ARB: + return &_mesa_texformat_alpha_float32; + case GL_LUMINANCE16F_ARB: + return &_mesa_texformat_luminance_float16; + case GL_LUMINANCE32F_ARB: + return &_mesa_texformat_luminance_float32; + case GL_LUMINANCE_ALPHA16F_ARB: + return &_mesa_texformat_luminance_alpha_float16; + case GL_LUMINANCE_ALPHA32F_ARB: + return &_mesa_texformat_luminance_alpha_float32; + case GL_INTENSITY16F_ARB: + return &_mesa_texformat_intensity_float16; + case GL_INTENSITY32F_ARB: + return &_mesa_texformat_intensity_float32; + case GL_RGB16F_ARB: + return &_mesa_texformat_rgba_float16; + case GL_RGB32F_ARB: + return &_mesa_texformat_rgba_float32; + case GL_RGBA16F_ARB: + return &_mesa_texformat_rgba_float16; + case GL_RGBA32F_ARB: + return &_mesa_texformat_rgba_float32; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: +#if 0 + switch (type) { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT: + return &_mesa_texformat_z16; + case GL_UNSIGNED_INT: + return &_mesa_texformat_z32; + case GL_UNSIGNED_INT_24_8_EXT: + default: + return &_mesa_texformat_z24_s8; + } +#else + return &_mesa_texformat_z16; +#endif + + default: + _mesa_problem(ctx, + "unexpected internalFormat 0x%x in r300ChooseTextureFormat", + (int)internalFormat); + return NULL; + } + + return NULL; /* never get here */ +} + +/** + * All glTexImage calls go through this function. + */ +static void radeon_teximage( + GLcontext *ctx, int dims, + GLint face, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLsizei imageSize, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + int compressed) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj* t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + radeon_firevertices(rmesa); + + t->validated = GL_FALSE; + + /* Choose and fill in the texture format for this image */ + texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type); + _mesa_set_fetch_functions(texImage, dims); + + if (texImage->TexFormat->TexelBytes == 0) { + texImage->IsCompressed = GL_TRUE; + texImage->CompressedSize = + ctx->Driver.CompressedTextureSize(ctx, texImage->Width, + texImage->Height, texImage->Depth, + texImage->TexFormat->MesaFormat); + } else { + texImage->IsCompressed = GL_FALSE; + texImage->CompressedSize = 0; + } + + /* Allocate memory for image */ + radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ + + if (!t->mt) + radeon_try_alloc_miptree(rmesa, t, texImage, face, level); + if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { + image->mt = t->mt; + image->mtlevel = level - t->mt->firstLevel; + image->mtface = face; + radeon_miptree_reference(t->mt); + } else { + int size; + if (texImage->IsCompressed) { + size = texImage->CompressedSize; + } else { + size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes; + } + texImage->Data = _mesa_alloc_texmemory(size); + } + + /* Upload texture image; note that the spec allows pixels to be NULL */ + if (compressed) { + pixels = _mesa_validate_pbo_compressed_teximage( + ctx, imageSize, pixels, packing, "glCompressedTexImage"); + } else { + pixels = _mesa_validate_pbo_teximage( + ctx, dims, width, height, depth, + format, type, pixels, packing, "glTexImage"); + } + + if (pixels) { + radeon_teximage_map(image, GL_TRUE); + + if (compressed) { + memcpy(texImage->Data, pixels, imageSize); + } else { + GLuint dstRowStride; + if (image->mt) { + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + dstRowStride = lvl->rowstride; + } else { + dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; + } + if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } + + } + + /* SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + radeon_generate_mipmap(ctx, texObj->Target, texObj); + } + + if (pixels) + radeon_teximage_unmap(image); + + _mesa_unmap_teximage_pbo(ctx, packing); + + +} + +void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, + 0, format, type, pixels, packing, texObj, texImage, 0); +} + +void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) + +{ + GLuint face = radeon_face_for_target(target); + + radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + 0, format, type, pixels, packing, texObj, texImage, 0); +} + +void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLuint face = radeon_face_for_target(target); + + radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + imageSize, 0, 0, data, 0, texObj, texImage, 1); +} + +void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, + 0, format, type, pixels, packing, texObj, texImage, 0); +} + +/** + * Update a subregion of the given texture image. + */ +static void radeon_texsubimage(GLcontext* ctx, int dims, int level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + int compressed) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj* t = radeon_tex_obj(texObj); + radeon_texture_image* image = get_radeon_texture_image(texImage); + + radeon_firevertices(rmesa); + + t->validated = GL_FALSE; + pixels = _mesa_validate_pbo_teximage(ctx, dims, + width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); + + if (pixels) { + GLint dstRowStride; + radeon_teximage_map(image, GL_TRUE); + + if (image->mt) { + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + dstRowStride = lvl->rowstride; + } else { + dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; + } + + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, texImage->Data, + xoffset, yoffset, zoffset, + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); + + + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + radeon_generate_mipmap(ctx, texObj->Target, texObj); + } + radeon_teximage_unmap(image); + + _mesa_unmap_teximage_pbo(ctx, packing); + + +} + +void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, + format, type, pixels, packing, texObj, texImage, 0); +} + +void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, + 1, format, type, pixels, packing, texObj, texImage, + 0); +} + +void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, + format, 0, data, 0, texObj, texImage, 1); +} + + +void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels, packing, texObj, texImage, 0); +} + +static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, + GLuint numrows, GLuint rowsize) +{ + assert(rowsize <= dststride); + assert(rowsize <= srcstride); + + if (rowsize == srcstride && rowsize == dststride) { + memcpy(dst, src, numrows*rowsize); + } else { + GLuint i; + for(i = 0; i < numrows; ++i) { + memcpy(dst, src, rowsize); + dst += dststride; + src += srcstride; + } + } +} + + +/** + * Ensure that the given image is stored in the given miptree from now on. + */ +static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) +{ + radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; + unsigned char *dest; + + assert(image->mt != mt); + assert(dstlvl->width == image->base.Width); + assert(dstlvl->height == image->base.Height); + assert(dstlvl->depth == image->base.Depth); + + + radeon_bo_map(mt->bo, GL_TRUE); + dest = mt->bo->ptr + dstlvl->faces[face].offset; + + if (image->mt) { + /* Format etc. should match, so we really just need a memcpy(). + * In fact, that memcpy() could be done by the hardware in many + * cases, provided that we have a proper memory manager. + */ + radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; + + assert(srclvl->size == dstlvl->size); + assert(srclvl->rowstride == dstlvl->rowstride); + + radeon_bo_map(image->mt->bo, GL_FALSE); + + memcpy(dest, + image->mt->bo->ptr + srclvl->faces[face].offset, + dstlvl->size); + radeon_bo_unmap(image->mt->bo); + + radeon_miptree_unreference(image->mt); + } else { + uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; + +// if (mt->tilebits) +// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); + + copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, + image->base.Height * image->base.Depth, srcrowstride); + + _mesa_free_texmemory(image->base.Data); + image->base.Data = 0; + } + + radeon_bo_unmap(mt->bo); + + image->mt = mt; + image->mtface = face; + image->mtlevel = level; + radeon_miptree_reference(image->mt); +} + +int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObj *t = radeon_tex_obj(texObj); + radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); + int face, level; + + if (t->validated || t->image_override) + return GL_TRUE; + + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); + + if (baseimage->base.Border > 0) + return GL_FALSE; + + /* Ensure a matching miptree exists. + * + * Differing mipmap trees can result when the app uses TexImage to + * change texture dimensions. + * + * Prefer to use base image's miptree if it + * exists, since that most likely contains more valid data (remember + * that the base level is usually significantly larger than the rest + * of the miptree, so cubemaps are the only possible exception). + */ + if (baseimage->mt && + baseimage->mt != t->mt && + radeon_miptree_matches_texture(baseimage->mt, &t->base)) { + radeon_miptree_unreference(t->mt); + t->mt = baseimage->mt; + radeon_miptree_reference(t->mt); + } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { + radeon_miptree_unreference(t->mt); + t->mt = 0; + } + + if (!t->mt) { + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, " Allocate new miptree\n"); + radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); + if (!t->mt) { + _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); + return GL_FALSE; + } + } + + /* Ensure all images are stored in the single main miptree */ + for(face = 0; face < t->mt->faces; ++face) { + for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { + radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); + if (t->mt == image->mt) { + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "OK\n"); + continue; + } + + if (RADEON_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "migrating\n"); + migrate_image_to_miptree(t->mt, image, face, level); + } + } + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h new file mode 100644 index 0000000000..ff0e1d061e --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_TEXTURE_H +#define RADEON_TEXTURE_H +struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx); +void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage); + +void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); +void radeon_teximage_unmap(radeon_texture_image *image); +void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); +void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); +void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); +int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); +GLuint radeon_face_for_target(GLenum target); +const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type); + +void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid * data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +#endif -- cgit v1.2.3 From 2b85fccae5ba33748846f74f90fe0f72c673a4b1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 Mar 2009 03:27:59 +1000 Subject: radeon: refactor framebuffer code like intel this is a step towards fbos and should fix pageflipping, but I think the first flip seems broken. --- src/mesa/drivers/dri/r200/r200_context.c | 2 +- src/mesa/drivers/dri/r200/r200_ioctl.c | 2 +- src/mesa/drivers/dri/r200/r200_state.c | 94 +---- src/mesa/drivers/dri/r300/r300_context.c | 39 +- src/mesa/drivers/dri/r300/r300_ioctl.c | 8 +- src/mesa/drivers/dri/r300/r300_render.c | 3 +- src/mesa/drivers/dri/r300/r300_state.c | 71 +--- src/mesa/drivers/dri/r300/r300_texstate.c | 10 +- src/mesa/drivers/dri/radeon/radeon_common.c | 470 ++++++++++++++++----- src/mesa/drivers/dri/radeon/radeon_common.h | 11 +- .../drivers/dri/radeon/radeon_common_context.c | 124 +++--- .../drivers/dri/radeon/radeon_common_context.h | 43 +- src/mesa/drivers/dri/radeon/radeon_context.c | 4 +- src/mesa/drivers/dri/radeon/radeon_lock.c | 78 ++-- src/mesa/drivers/dri/radeon/radeon_lock.h | 69 +-- src/mesa/drivers/dri/radeon/radeon_screen.c | 69 +-- src/mesa/drivers/dri/radeon/radeon_state.c | 80 +--- 17 files changed, 612 insertions(+), 565 deletions(-) (limited to 'src/mesa/drivers/dri/radeon/radeon_lock.h') diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index a744469b31..10a6362afd 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -261,9 +261,9 @@ static void r200_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r200_get_lock; radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset; - radeon->vtbl.update_draw_buffer = r200UpdateDrawBuffer; radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header; radeon->vtbl.swtcl_flush = r200_swtcl_flush; + radeon->vtbl.fallback = r200Fallback; } diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index c08968f7f8..6076b6d7ea 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -203,7 +203,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) GLint ret; if ( R200_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "r200Clear\n"); + fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); } { diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 126f78b39c..46baad33f5 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -1639,6 +1639,8 @@ static void r200Viewport( GLcontext *ctx, GLint x, GLint y, * values, or keep the originals hanging around. */ r200UpdateWindow( ctx ); + + radeon_viewport(ctx, x, y, width, height); } static void r200DepthRange( GLcontext *ctx, GLclampd nearval, @@ -1754,47 +1756,6 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode ) rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop]; } - -static void r200DrawBuffer( GLcontext *ctx, GLenum mode ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ - - if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { - /* 0 (GL_NONE) buffers or multiple color drawing buffers */ - FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { - case BUFFER_FRONT_LEFT: - case BUFFER_BACK_LEFT: - FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - radeonSetCliprects( &rmesa->radeon ); - radeonUpdatePageFlipping(&rmesa->radeon); - - /* We'll set the drawing engine's offset/pitch parameters later - * when we update other state. - */ -} - - -static void r200ReadBuffer( GLcontext *ctx, GLenum mode ) -{ - /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ -} - /* ============================================================= * State enable/disable */ @@ -2289,47 +2250,6 @@ static void update_texturematrix( GLcontext *ctx ) } } - - -/** - * Tell the card where to render (offset, pitch). - * Effected by glDrawBuffer, etc - */ -void -r200UpdateDrawBuffer(GLcontext *ctx) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct radeon_renderbuffer *rrb; - - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - /* draw to front */ - rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* draw to back */ - rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } else { - /* drawing to multiple buffers, or none */ - return; - } - - assert(rrb); - assert(rrb->pitch); - - R200_STATECHANGE( rmesa, ctx ); - -#if 0 - /* Note: we used the (possibly) page-flipped values */ - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] - = ((rrb->flippedOffset + rmesa->radeon.radeonScreen->fbLocation) - & R200_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; - if (rmesa->radeon.sarea->tiling_enabled) { - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; - } -#endif -} - static GLboolean r200ValidateBuffers(GLcontext *ctx) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -2395,7 +2315,11 @@ GLboolean r200ValidateState( GLcontext *ctx ) GLuint new_state = rmesa->radeon.NewGLState; if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - r200UpdateDrawBuffer(ctx); + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + + R200_STATECHANGE(rmesa, ctx); } if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) { @@ -2523,8 +2447,8 @@ void r200InitStateFuncs( struct dd_function_table *functions ) functions->UpdateState = r200InvalidateState; functions->LightingSpaceChange = r200LightingSpaceChange; - functions->DrawBuffer = r200DrawBuffer; - functions->ReadBuffer = r200ReadBuffer; + functions->DrawBuffer = radeonDrawBuffer; + functions->ReadBuffer = radeonReadBuffer; functions->AlphaFunc = r200AlphaFunc; functions->BlendColor = r200BlendColor; diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 5d497efc9c..488fd44740 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -235,26 +235,35 @@ static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon) { - r300ContextPtr r300 = (r300ContextPtr)radeon; - BATCH_LOCALS(radeon); - - r300->vap_flush_needed = GL_TRUE; + r300ContextPtr r300 = (r300ContextPtr)radeon; + BATCH_LOCALS(radeon); + + r300->vap_flush_needed = GL_TRUE; + + cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH); + END_BATCH(); + end_3d(radeon); +} - cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); - BEGIN_BATCH_NO_AUTOSTATE(2); - OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH); - END_BATCH(); - end_3d(radeon); +static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + if (mode) + r300->radeon.Fallback |= bit; + else + r300->radeon.Fallback &= ~bit; } static void r300_init_vtbl(radeonContextPtr radeon) { - radeon->vtbl.get_lock = r300_get_lock; - radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; - radeon->vtbl.update_draw_buffer = r300UpdateDrawBuffer; - radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header; - radeon->vtbl.swtcl_flush = r300_swtcl_flush; - radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms; + radeon->vtbl.get_lock = r300_get_lock; + radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; + radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header; + radeon->vtbl.swtcl_flush = r300_swtcl_flush; + radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms; + radeon->vtbl.fallback = r300_fallback; } diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 619d268f38..d1cf57959f 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -541,7 +541,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; - GLframebuffer *fb = dPriv->driverPrivate; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; struct radeon_renderbuffer *rrb; struct radeon_renderbuffer *rrbd; int flags = 0; @@ -594,16 +594,16 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); - rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (flags & BUFFER_BIT_FRONT_LEFT) { - rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); bits = 0; } if (flags & BUFFER_BIT_BACK_LEFT) { - rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); bits = 0; } diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index f46477f0f6..402d2d7638 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -427,7 +427,8 @@ static int r300Fallback(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); const unsigned back = ctx->Stencil._BackFace; - + + FALLBACK_IF(r300->radeon.Fallback); /* Do we need to use new-style shaders? * Also is there a better way to do this? */ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 59728a07e5..6bb0063bc1 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1083,20 +1083,13 @@ static void r300UpdateWindow(GLcontext * ctx) static void r300Viewport(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); - __DRIcontext *driContext = rmesa->radeon.dri.context; /* Don't pipeline viewport changes, conflict with window offset * setting below. Could apply deltas to rescue pipelined viewport * values, or keep the originals hanging around. */ - if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { - radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); - if (driContext->driDrawablePriv != driContext->driReadablePriv) { - radeon_update_renderbuffers(driContext, - driContext->driReadablePriv); - } - } r300UpdateWindow(ctx); + + radeon_viewport(ctx, x, y, width, height); } static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) @@ -1129,34 +1122,6 @@ void r300UpdateViewportOffset(GLcontext * ctx) radeonUpdateScissor(ctx); } -/** - * Tell the card where to render (offset, pitch). - * Effected by glDrawBuffer, etc - */ -void r300UpdateDrawBuffer(GLcontext * ctx) -{ - r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct radeon_renderbuffer *rrb; - - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - /* draw to front */ - rrb = - (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* draw to back */ - rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } else { - /* drawing to multiple buffers, or none */ - return; - } - - assert(rrb); - assert(rrb->pitch); - - R300_STATECHANGE(rmesa, cb); -} - static void r300FetchStateParameter(GLcontext * ctx, const gl_state_index state[STATE_LENGTH], @@ -2653,7 +2618,11 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _ae_invalidate_state(ctx, new_state); if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - r300UpdateDrawBuffer(ctx); + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + + R300_STATECHANGE(r300, cb); } r300UpdateStateParameters(ctx, new_state); @@ -2705,28 +2674,6 @@ void r300UpdateClipPlanes( GLcontext *ctx ) } } -static void r300DrawBuffer( GLcontext *ctx, GLenum mode ) -{ - r300ContextPtr rmesa = R300_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ - - radeonSetCliprects( &rmesa->radeon ); - if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) - radeonUpdatePageFlipping(&rmesa->radeon); -} - -static void r300ReadBuffer( GLcontext *ctx, GLenum mode ) -{ - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - -}; - /** * Initialize driver's state callback functions */ @@ -2770,6 +2717,6 @@ void r300InitStateFuncs(struct dd_function_table *functions) functions->ClipPlane = r300ClipPlane; functions->Scissor = radeonScissor; - functions->DrawBuffer = r300DrawBuffer; - functions->ReadBuffer = r300ReadBuffer; + functions->DrawBuffer = radeonDrawBuffer; + functions->ReadBuffer = radeonReadBuffer; } diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 8a90069a6d..2d7f392e7c 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -393,7 +393,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeon_texture_image *rImage; radeonContextPtr radeon; r300ContextPtr rmesa; - GLframebuffer *fb; + struct radeon_framebuffer *rfb; radeonTexObjPtr t; uint32_t pitch_val; @@ -402,7 +402,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeon = pDRICtx->driverPrivate; rmesa = pDRICtx->driverPrivate; - fb = dPriv->driverPrivate; + rfb = dPriv->driverPrivate; texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); @@ -415,17 +415,17 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeon_update_renderbuffers(pDRICtx, dPriv); /* back & depth buffer are useless free them right away */ - rb = (void*)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void*)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rb = (void*)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb->bo == NULL) { /* Failed to BO for the buffer */ return; diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index f7c0d7d64f..1021f9beec 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -51,7 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/light.h" #include "main/framebuffer.h" #include "main/simple_list.h" - +#include "main/renderbuffer.h" #include "swrast/swrast.h" #include "vbo/vbo.h" #include "tnl/tnl.h" @@ -132,6 +132,38 @@ void radeonRecalcScissorRects(radeonContextPtr radeon) } } +static void radeon_get_cliprects(radeonContextPtr radeon, + struct drm_clip_rect **cliprects, + unsigned int *num_cliprects, + int *x_off, int *y_off) +{ + __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; + + if (radeon->constant_cliprect) { + radeon->fboRect.x1 = 0; + radeon->fboRect.y1 = 0; + radeon->fboRect.x2 = radeon->glCtx->DrawBuffer->Width; + radeon->fboRect.y2 = radeon->glCtx->DrawBuffer->Height; + + *cliprects = &radeon->fboRect; + *num_cliprects = 1; + *x_off = 0; + *y_off = 0; + } else if (radeon->front_cliprects || + rfb->pf_active || dPriv->numBackClipRects == 0) { + *cliprects = dPriv->pClipRects; + *num_cliprects = dPriv->numClipRects; + *x_off = dPriv->x; + *y_off = dPriv->y; + } else { + *num_cliprects = dPriv->numBackClipRects; + *cliprects = dPriv->pBackClipRects; + *x_off = dPriv->backX; + *y_off = dPriv->backY; + } +} + /** * Update cliprects and scissors. */ @@ -139,49 +171,37 @@ void radeonSetCliprects(radeonContextPtr radeon) { __DRIdrawablePrivate *const drawable = radeon->dri.drawable; __DRIdrawablePrivate *const readable = radeon->dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate; + struct radeon_framebuffer *const read_rfb = readable->driverPrivate; + int x_off, y_off; - if (!radeon->radeonScreen->driScreen->dri2.enabled) { - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. */ - if (drawable->numBackClipRects == 0 || radeon->doPageFlip || - radeon->sarea->pfCurrentPage == 1) { - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } else { - radeon->numClipRects = drawable->numBackClipRects; - radeon->pClipRects = drawable->pBackClipRects; - } - } else { - /* front buffer (or none, or multiple buffers */ - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } - } + fprintf(stderr,"cliprects %d %d\n", radeon->front_cliprects, radeon->constant_cliprect); + radeon_get_cliprects(radeon, &radeon->pClipRects, + &radeon->numClipRects, &x_off, &y_off); - if ((draw_fb->Width != drawable->w) || - (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + if ((draw_rfb->base.Width != drawable->w) || + (draw_rfb->base.Height != drawable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, &draw_rfb->base, drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; + draw_rfb->base.Initialized = GL_TRUE; } if (drawable != readable) { - if ((read_fb->Width != readable->w) || - (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, read_fb, + if ((read_rfb->base.Width != readable->w) || + (read_rfb->base.Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, &read_rfb->base, readable->w, readable->h); - read_fb->Initialized = GL_TRUE; + read_rfb->base.Initialized = GL_TRUE; } } if (radeon->state.scissor.enabled) radeonRecalcScissorRects(radeon); - radeon->lastStamp = drawable->lastStamp; } + + void radeonUpdateScissor( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -348,6 +368,37 @@ static void radeonWaitForIdle(radeonContextPtr radeon) UNLOCK_HARDWARE(radeon); } +static void radeon_flip_renderbuffers(struct radeon_framebuffer *rfb) +{ + int current_page = rfb->pf_current_page; + int next_page = (current_page + 1) % rfb->pf_num_pages; + struct gl_renderbuffer *tmp_rb; + + /* Exchange renderbuffers if necessary but make sure their + * reference counts are preserved. + */ + if (rfb->color_rb[current_page] && + rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer != + &rfb->color_rb[current_page]->base) { + tmp_rb = NULL; + _mesa_reference_renderbuffer(&tmp_rb, + rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + tmp_rb = &rfb->color_rb[current_page]->base; + _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb); + _mesa_reference_renderbuffer(&tmp_rb, NULL); + } + + if (rfb->color_rb[next_page] && + rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer != + &rfb->color_rb[next_page]->base) { + tmp_rb = NULL; + _mesa_reference_renderbuffer(&tmp_rb, + rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + tmp_rb = &rfb->color_rb[next_page]->base; + _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb); + _mesa_reference_renderbuffer(&tmp_rb, NULL); + } +} /* Copy the back color buffer to the front color buffer. */ @@ -355,10 +406,8 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, const drm_clip_rect_t *rect) { radeonContextPtr rmesa; + struct radeon_framebuffer *rfb; GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp; assert(dPriv); assert(dPriv->driContextPriv); @@ -366,24 +415,12 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + rfb = dPriv->driverPrivate; + if ( RADEON_DEBUG & DEBUG_IOCTL ) { fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); } - radeon_firevertices(rmesa); - 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 ; ) { @@ -429,94 +466,76 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, } 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->hw.all_dirty = GL_TRUE; +static int radeonScheduleSwap(__DRIdrawablePrivate *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); + LOCK_HARDWARE(rmesa); + + return 0; } -void radeonPageFlip( __DRIdrawablePrivate *dPriv ) +static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv ) { - radeonContextPtr rmesa; + radeonContextPtr radeon; GLint ret; - GLboolean missed_target; __DRIscreenPrivate *psp; struct radeon_renderbuffer *rrb; - GLframebuffer *fb = dPriv->driverPrivate; - + struct radeon_framebuffer *rfb; + assert(dPriv); assert(dPriv->driContextPriv); assert(dPriv->driContextPriv->driverPrivate); - rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + rfb = dPriv->driverPrivate; + rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; psp = dPriv->driScreenPriv; if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - rmesa->sarea->pfCurrentPage); + fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__, + radeon->sarea->pfCurrentPage, radeon->sarea->pfState); } - - radeon_firevertices(rmesa); - - 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; + drm_clip_rect_t *b = radeon->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 ); + radeon->sarea->nbox = 1; - ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); + ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( radeon ); if ( ret ) { fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); - exit( 1 ); + return GL_FALSE; } - 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 (!rfb->pf_active) + return GL_FALSE; + + rfb->pf_current_page = radeon->sarea->pfCurrentPage; + radeon_flip_renderbuffers(rfb); + radeon_draw_buffer(radeon->glCtx, &rfb->base); - if (rmesa->vtbl.update_draw_buffer) - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); + return GL_TRUE; } @@ -525,6 +544,9 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv ) */ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) { + int64_t ust; + __DRIscreenPrivate *psp; + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { radeonContextPtr radeon; GLcontext *ctx; @@ -533,12 +555,29 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) ctx = radeon->glCtx; if (ctx->Visual.doubleBufferMode) { + GLboolean missed_target; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ - if (radeon->doPageFlip) { + + 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 */ @@ -573,7 +612,224 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, } } +void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL, + *rrbColor = NULL; + + + if (!fb) { + /* this can happen during the initial context initialization */ + return; + } + + /* radeons only handle 1 color draw so far */ + if (fb->_NumColorDrawBuffers != 1) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); + return; + } + + /* Do this here, note core Mesa, since this function is called from + * many places within the driver. + */ + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + } + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + /* this may occur when we're called by glBindFrameBuffer() during + * the process of someone setting up renderbuffers, etc. + */ + /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ + return; + } + + if (fb->Name) + ;/* do something depthy/stencily TODO */ + + + /* none */ + if (fb->Name == 0) { + if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + radeon->front_cliprects = GL_TRUE; + } else { + rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + radeon->front_cliprects = GL_FALSE; + } + } else { + /* user FBO in theory */ + struct radeon_renderbuffer *rrb; + rrb = (void *)fb->_ColorDrawBuffers[0]; + rrbColor = rrb; + radeon->constant_cliprect = GL_TRUE; + } + + if (rrbColor == NULL) + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); + else + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); + + + + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { + rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; + if (rrbDepth && rrbDepth->bo) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE); + } + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); + rrbDepth = NULL; + } + + /* TODO stencil things */ + if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { + rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; + if (rrbStencil && rrbStencil->bo) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + if (ctx->Driver.Enable != NULL) + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + else + ctx->NewState |= _NEW_STENCIL; + if (!rrbDepth) + rrbDepth = rrbStencil; + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); + if (ctx->Driver.Enable != NULL) + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + else + ctx->NewState |= _NEW_STENCIL; + } + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; + + /* + * Update depth test state + */ + if (ctx->Driver.Enable) { + if (ctx->Depth.Test && fb->Visual.depthBits > 0) { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); + } else { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); + } + } else { + ctx->NewState |= _NEW_DEPTH; + } + + radeon->state.depth.rrb = rrbDepth; + + radeon->state.color.rrb = rrbColor; + + /* update viewport since it depends on window size */ + if (ctx->Driver.Viewport) { + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + } else { + ctx->NewState |= _NEW_VIEWPORT; + } + + /* Set state we know depends on drawable parameters: + */ + if (ctx->Driver.Scissor) + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + radeon->NewGLState |= _NEW_SCISSOR; +} + +/** + * Called via glDrawBuffer. + */ +void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( mode )); + + radeon_firevertices(radeon); /* don't pipeline cliprect changes */ + + radeon_draw_buffer(ctx, ctx->DrawBuffer); +} + +void radeonReadBuffer( GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ + if (ctx->ReadBuffer == ctx->DrawBuffer) { + /* This will update FBO completeness status. + * A framebuffer will be incomplete if the GL_READ_BUFFER setting + * refers to a missing renderbuffer. Calling glReadBuffer can set + * that straight and can make the drawing buffer complete. + */ + radeon_draw_buffer(ctx, ctx->DrawBuffer); + } +} + +/* Turn on/off page flipping according to the flags in the sarea: + */ +void radeonUpdatePageFlipping(radeonContextPtr radeon) +{ + struct radeon_framebuffer *rfb = radeon->dri.drawable->driverPrivate; + + rfb->pf_active = radeon->sarea->pfState; + rfb->pf_current_page = radeon->sarea->pfCurrentPage; + rfb->pf_num_pages = 2; + radeon_flip_renderbuffers(rfb); + radeon_draw_buffer(radeon->glCtx, radeon->glCtx->DrawBuffer); +} + +void radeon_window_moved(radeonContextPtr radeon) +{ + GLcontext *ctx = radeon->glCtx; + __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + radeonUpdatePageFlipping(radeon); + } + radeonSetCliprects(radeon); +} + +void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + __DRIcontext *driContext = radeon->dri.context; + void (*old_viewport)(GLcontext *ctx, GLint x, GLint y, + GLsizei w, GLsizei h); + + if (!driContext->driScreenPriv->dri2.enabled) + return; + + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); + if (driContext->driDrawablePriv != driContext->driReadablePriv) + radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + + old_viewport = ctx->Driver.Viewport; + ctx->Driver.Viewport = NULL; + radeon->dri.drawable = driContext->driDrawablePriv; + radeon_window_moved(radeon); + radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer); + ctx->Driver.Viewport = old_viewport; + + +} static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state ) { int i; diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index ead0f5551b..95b718184b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -14,7 +14,6 @@ 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 radeonSwapBuffers(__DRIdrawablePrivate * dPriv); void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h ); @@ -25,6 +24,12 @@ void radeonFlush(GLcontext *ctx); void radeonFinish(GLcontext * ctx); void radeonEmitState(radeonContextPtr radeon); +void radeon_window_moved(radeonContextPtr radeon); +void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb); +void radeonDrawBuffer( GLcontext *ctx, GLenum mode ); +void radeonReadBuffer( GLcontext *ctx, GLenum mode ); +void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height); + static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) { struct radeon_renderbuffer *rrb; @@ -38,11 +43,11 @@ static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPt static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) { struct radeon_renderbuffer *rrb; - GLframebuffer *fb = rmesa->dri.drawable->driverPrivate; + struct radeon_framebuffer *rfb = rmesa->dri.drawable->driverPrivate; rrb = rmesa->state.color.rrb; if (rmesa->radeonScreen->driScreen->dri2.enabled) { - rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rrb = (struct radeon_renderbuffer *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; } if (!rrb) return NULL; diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 1b8a05d045..4da2055c13 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -35,7 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_common.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ #include "utils.h" -#include "drirenderbuffer.h" #include "vblank.h" #include "main/state.h" @@ -165,8 +164,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon, radeon->do_usleeps ? "usleeps" : "busy waits", fthrottle_mode, radeon->radeonScreen->irq); - (*sPriv->systemTime->getUST) (&radeon->swap_ust); - return GL_TRUE; } @@ -180,39 +177,39 @@ void radeonCleanupContext(radeonContextPtr radeon) FILE *track; #endif struct radeon_renderbuffer *rb; - GLframebuffer *fb; + struct radeon_framebuffer *rfb; /* free the Mesa context */ _mesa_destroy_context(radeon->glCtx); - fb = (void*)radeon->dri.drawable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rfb = (void*)radeon->dri.drawable->driverPrivate; + rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - fb = (void*)radeon->dri.readable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rfb = (void*)radeon->dri.readable->driverPrivate; + rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -260,12 +257,12 @@ GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) static void radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) + struct radeon_framebuffer *draw) { /* if radeon->fake */ struct radeon_renderbuffer *rb; - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->frontOffset, @@ -277,7 +274,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->backOffset, @@ -289,7 +286,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset, @@ -301,7 +298,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset, @@ -317,7 +314,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, static void radeon_make_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) + struct radeon_framebuffer *draw) { int size = 4096*4096*4; /* if radeon->fake */ @@ -329,7 +326,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, } - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->frontOffset + @@ -342,7 +339,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->backOffset + @@ -355,7 +352,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset + @@ -368,7 +365,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset + @@ -392,7 +389,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) __DRIscreen *screen; struct radeon_renderbuffer *rb; int i, count; - GLframebuffer *draw; + struct radeon_framebuffer *draw; radeonContextPtr radeon; if (RADEON_DEBUG & DEBUG_DRI) @@ -402,13 +399,13 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) screen = context->driScreenPriv; radeon = (radeonContextPtr) context->driverPrivate; i = 0; - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { attachments[i++] = __DRI_BUFFER_FRONT_LEFT; } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { attachments[i++] = __DRI_BUFFER_BACK_LEFT; } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { attachments[i++] = __DRI_BUFFER_DEPTH; } @@ -439,7 +436,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) for (i = 0; i < count; i++) { switch (buffers[i].attachment) { case __DRI_BUFFER_FRONT_LEFT: - rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -461,7 +458,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) } break; case __DRI_BUFFER_BACK_LEFT: - rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -479,7 +476,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) buffers[i].flags); break; case __DRI_BUFFER_DEPTH: - rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -518,7 +515,8 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driReadPriv) { radeonContextPtr radeon; - GLframebuffer *dfb, *rfb; + struct radeon_framebuffer *drfb; + struct gl_framebuffer *readfb; if (!driContextPriv) { if (RADEON_DEBUG & DEBUG_DRI) @@ -526,61 +524,65 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, _mesa_make_current(NULL, NULL, NULL); return GL_TRUE; } + radeon = (radeonContextPtr) driContextPriv->driverPrivate; - dfb = driDrawPriv->driverPrivate; - rfb = driReadPriv->driverPrivate; + drfb = driDrawPriv->driverPrivate; + readfb = driReadPriv->driverPrivate; if (driContextPriv->driScreenPriv->dri2.enabled) { radeon_update_renderbuffers(driContextPriv, driDrawPriv); if (driDrawPriv != driReadPriv) radeon_update_renderbuffers(driContextPriv, driReadPriv); radeon->state.color.rrb = - (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + (void *)drfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; radeon->state.depth.rrb = - (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; + (void *)drfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; } else { - radeon_make_renderbuffer_current(radeon, dfb); + radeon_make_renderbuffer_current(radeon, drfb); } if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb); + fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb); driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); if (driReadPriv != driDrawPriv) driUpdateFramebufferSize(radeon->glCtx, driReadPriv); + _mesa_make_current(radeon->glCtx, &drfb->base, readfb); - - _mesa_make_current(radeon->glCtx, dfb, rfb); - - if (radeon->dri.drawable != driDrawPriv) { - if (driDrawPriv->swap_interval == (unsigned)-1) { - driDrawPriv->vblFlags = - (radeon->radeonScreen->irq != 0) - ? driGetDefaultVBlankFlags(&radeon-> - optionCache) - : VBLANK_FLAG_NO_IRQ; - - driDrawableInitVBlank(driDrawPriv); - } - } + _mesa_update_state(radeon->glCtx); - radeon->dri.readable = driReadPriv; + if (radeon->glCtx->DrawBuffer == &drfb->base) { - if (radeon->dri.drawable != driDrawPriv || - radeon->lastStamp != driDrawPriv->lastStamp) { - radeon->dri.drawable = driDrawPriv; + if (radeon->dri.readable != driReadPriv) + radeon->dri.readable = driReadPriv; - radeonSetCliprects(radeon); - radeon->vtbl.update_viewport_offset(radeon->glCtx); + if (radeon->dri.drawable != driDrawPriv) { + if (driDrawPriv->swap_interval == (unsigned)-1) { + int i; + driDrawPriv->vblFlags = + (radeon->radeonScreen->irq != 0) + ? driGetDefaultVBlankFlags(&radeon-> + optionCache) + : VBLANK_FLAG_NO_IRQ; + + driDrawableInitVBlank(driDrawPriv); + drfb->vbl_waited = driDrawPriv->vblSeq; + + for (i = 0; i < 2; i++) { + if (drfb->color_rb[i]) + drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; + } + + } + radeon->dri.drawable = driDrawPriv; + +// radeonWindowMoved(radeon); + } + radeon_draw_buffer(radeon->glCtx, &drfb->base); } - _mesa_update_state(radeon->glCtx); - - if (!driContextPriv->driScreenPriv->dri2.enabled) { - radeonUpdatePageFlipping(radeon); - } if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "End %s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index a200e90221..4aeb50fe68 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -39,6 +39,8 @@ typedef struct radeon_context *radeonContextPtr; #define RADEON_FALLBACK_BLEND_FUNC 0x0020 #define RADEON_FALLBACK_DISABLE 0x0040 #define RADEON_FALLBACK_BORDER_MODE 0x0080 +#define RADEON_FALLBACK_DEPTH_BUFFER 0x0100 +#define RADEON_FALLBACK_STENCIL_BUFFER 0x0200 #define R200_FALLBACK_TEXTURE 0x01 #define R200_FALLBACK_DRAW_BUFFER 0x02 @@ -81,9 +83,34 @@ struct radeon_renderbuffer /* boo Xorg 6.8.2 compat */ int has_surface; + GLuint pf_pending; /**< sequence number of pending flip */ + GLuint vbl_pending; /**< vblank sequence number of pending flip */ __DRIdrawablePrivate *dPriv; }; +struct radeon_framebuffer +{ + struct gl_framebuffer base; + + struct radeon_renderbuffer *color_rb[2]; + + GLuint vbl_waited; + + /* buffer swap */ + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + /* Drawable page flipping state */ + GLboolean pf_active; + GLint pf_current_page; + GLint pf_num_pages; + +}; + + struct radeon_colorbuffer_state { GLuint clear; int roundEnable; @@ -387,9 +414,6 @@ struct radeon_context { GLuint NewGLState; DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ - /* Page flipping */ - GLuint doPageFlip; - /* Drawable, cliprect and scissor information */ GLuint numClipRects; /* Cliprects for the draw buffer */ drm_clip_rect_t *pClipRects; @@ -406,13 +430,6 @@ struct radeon_context { GLuint irqsEmitted; drm_radeon_irq_wait_t iw; - /* buffer swap */ - int64_t swap_ust; - int64_t swap_missed_ust; - - GLuint swap_count; - GLuint swap_missed_count; - /* Derived state - for r300 only */ struct radeon_state state; @@ -422,15 +439,19 @@ struct radeon_context { driOptionCache optionCache; struct radeon_cmdbuf cmdbuf; + + drm_clip_rect_t fboRect; + GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ + GLboolean front_cliprects; struct { void (*get_lock)(radeonContextPtr radeon); void (*update_viewport_offset)(GLcontext *ctx); - void (*update_draw_buffer)(GLcontext *ctx); void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); void (*pre_emit_atoms)(radeonContextPtr rmesa); void (*pre_emit_state)(radeonContextPtr rmesa); + void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode); } vtbl; }; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e4202c71fc..47ebe41c6d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -186,10 +186,10 @@ static void r100_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r100_get_lock; radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset; - radeon->vtbl.update_draw_buffer = radeonUpdateDrawBuffer; radeon->vtbl.emit_cs_header = r100_vtbl_emit_cs_header; radeon->vtbl.swtcl_flush = r100_swtcl_flush; radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state; + radeon->vtbl.fallback = radeonFallback; } /* Create the device specific context. @@ -369,8 +369,6 @@ radeonCreateContext( const __GLcontextModes *glVisual, rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - (*sPriv->systemTime->getUST)( & rmesa->radeon.swap_ust ); - #if DO_DEBUG RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ), diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 9a7e76b245..fb9e5e025e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -48,37 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_lock.h" #include "drirenderbuffer.h" -#if DEBUG_LOCKING -char *prevLockFile = NULL; -int prevLockLine = 0; -#endif - -/* Turn on/off page flipping according to the flags in the sarea: - */ -void radeonUpdatePageFlipping(radeonContextPtr rmesa) -{ - int use_back; - __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; - GLframebuffer *fb = drawable->driverPrivate; - - rmesa->doPageFlip = rmesa->sarea->pfState; - if (rmesa->glCtx->WinSysDrawBuffer) { - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); - } - - use_back = rmesa->glCtx->DrawBuffer ? - (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == - BUFFER_BACK_LEFT) : 1; - use_back ^= (rmesa->sarea->pfCurrentPage == 1); - - if (use_back) - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - else - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - - rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; -} - /* Update the hardware state. This is called if another context has * grabbed the hardware lock, which includes the X server. This * function also updates the driver's window state after the X server @@ -112,13 +81,52 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) } if (rmesa->lastStamp != drawable->lastStamp) { - radeonUpdatePageFlipping(rmesa); - radeonSetCliprects(rmesa); - rmesa->vtbl.update_viewport_offset(rmesa->glCtx); - driUpdateFramebufferSize(rmesa->glCtx, drawable); + radeon_window_moved(rmesa); + rmesa->lastStamp = drawable->lastStamp; } rmesa->vtbl.get_lock(rmesa); rmesa->lost_context = GL_TRUE; } + +static INLINE struct radeon_renderbuffer * +radeon_get_renderbuffer(struct gl_framebuffer *fb, int attIndex) +{ + if (attIndex >= 0) + return (struct radeon_renderbuffer *)fb->Attachment[attIndex].Renderbuffer; + else + return NULL; +} + +void radeon_lock_hardware(radeonContextPtr radeon) +{ + __DRIdrawable *dPriv = radeon->dri.drawable; + char ret = 0; + struct radeon_framebuffer *rfb = NULL; + struct radeon_renderbuffer *rrb = NULL; + + if (radeon->dri.drawable) { + rfb = radeon->dri.drawable->driverPrivate; + + if (rfb) + rrb = radeon_get_renderbuffer(&rfb->base, + rfb->base._ColorDrawBufferIndexes[0]); + } + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext, + (DRM_LOCK_HELD | radeon->dri.hwContext), ret ); + if (ret) + radeonGetLock(radeon, 0); + } +} + +void radeon_unlock_hardware(radeonContextPtr radeon) +{ + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + DRM_UNLOCK( radeon->dri.fd, + radeon->dri.hwLock, + radeon->dri.hwContext ); + } +} diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index f5ebb8dd54..2817709eed 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -48,73 +48,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( prevLockFile ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - exit( 1 ); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ +void radeon_lock_hardware(radeonContextPtr rmesa); +void radeon_unlock_hardware(radeonContextPtr rmesa); /* Lock the hardware and validate our state. */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ - if ( __ret ) \ - radeonGetLock( (rmesa), 0 ); \ - } \ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_UNLOCK( (rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext ); \ - DEBUG_RESET(); \ - } \ - } while (0) +#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa) +#define UNLOCK_HARDWARE( rmesa ) radeon_unlock_hardware(rmesa) #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 78f0bc2514..bf5f5c98bd 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1262,7 +1262,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { - radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; + radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; const GLboolean swDepth = GL_FALSE; const GLboolean swAlpha = GL_FALSE; @@ -1271,7 +1271,16 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, mesaVis->depthBits != 24; GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); GLenum depthFormat = GL_NONE; - struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + struct radeon_framebuffer *rfb; + + if (isPixmap) + return GL_FALSE; /* not implemented */ + + rfb = CALLOC_STRUCT(radeon_framebuffer); + if (!rfb) + return GL_FALSE; + + _mesa_initialize_framebuffer(&rfb->base, mesaVis); if (mesaVis->depthBits == 16) depthFormat = GL_DEPTH_COMPONENT16; @@ -1279,26 +1288,22 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, depthFormat = GL_DEPTH_COMPONENT24; /* front color renderbuffer */ - { - struct radeon_renderbuffer *front = - radeon_create_renderbuffer(rgbFormat, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base); - front->has_surface = 1; - } + rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base); + rfb->color_rb[0]->has_surface = 1; /* back color renderbuffer */ if (mesaVis->doubleBufferMode) { - struct radeon_renderbuffer *back = - radeon_create_renderbuffer(rgbFormat, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base); - back->has_surface = 1; + rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base); + rfb->color_rb[1]->has_surface = 1; } /* depth renderbuffer */ if (depthFormat != GL_NONE) { struct radeon_renderbuffer *depth = radeon_create_renderbuffer(depthFormat, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base); + _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); depth->has_surface = screen->depthHasSurface; } @@ -1306,18 +1311,18 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, if (mesaVis->stencilBits > 0 && !swStencil) { struct radeon_renderbuffer *stencil = radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base); + _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base); stencil->has_surface = screen->depthHasSurface; } - _mesa_add_soft_renderbuffers(fb, + _mesa_add_soft_renderbuffers(&rfb->base, GL_FALSE, /* color */ swDepth, swStencil, swAccum, swAlpha, GL_FALSE /* aux */); - driDrawPriv->driverPrivate = (void *) fb; + driDrawPriv->driverPrivate = (void *) rfb; return (driDrawPriv->driverPrivate != NULL); } @@ -1325,21 +1330,21 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - struct radeon_renderbuffer *rb; - GLframebuffer *fb; + struct radeon_renderbuffer *rb; + struct radeon_framebuffer *rfb; - fb = (void*)driDrawPriv->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rfb = (void*)driDrawPriv->driverPrivate; + rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -1541,21 +1546,21 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) { - radeonContextPtr rmesa; + struct radeon_framebuffer *rfb; - if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) - || (dPriv->driContextPriv->driverPrivate == NULL) - || (sInfo == NULL) ) { - return -1; + if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) + || (dPriv->driContextPriv->driverPrivate == NULL) + || (sInfo == NULL) ) { + return -1; } - rmesa = dPriv->driContextPriv->driverPrivate; - sInfo->swap_count = rmesa->swap_count; - sInfo->swap_ust = rmesa->swap_ust; - sInfo->swap_missed_count = rmesa->swap_missed_count; + rfb = dPriv->driverPrivate; + sInfo->swap_count = rfb->swap_count; + sInfo->swap_ust = rfb->swap_ust; + sInfo->swap_missed_count = rfb->swap_missed_count; sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) - ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust ) + ? driCalculateSwapUsage( dPriv, 0, rfb->swap_missed_ust ) : 0.0; return 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 5fffa286fe..0c92a6ff08 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -1418,6 +1418,8 @@ static void radeonViewport( GLcontext *ctx, GLint x, GLint y, * values, or keep the originals hanging around. */ radeonUpdateWindow( ctx ); + + radeon_viewport(ctx, x, y, width, height); } static void radeonDepthRange( GLcontext *ctx, GLclampd nearval, @@ -1532,50 +1534,6 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop]; } - -/** - * Called via glDrawBuffer. - */ -static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ - - if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { - /* 0 (GL_NONE) buffers or multiple color drawing buffers */ - FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { - case BUFFER_FRONT_LEFT: - case BUFFER_BACK_LEFT: - FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - radeonSetCliprects( &rmesa->radeon ); - if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) - radeonUpdatePageFlipping(&rmesa->radeon); - /* We'll set the drawing engine's offset/pitch parameters later - * when we update other state. - */ -} - -static void radeonReadBuffer( GLcontext *ctx, GLenum mode ) -{ - /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ -} - - /* ============================================================= * State enable/disable */ @@ -2066,42 +2024,16 @@ static void update_texturematrix( GLcontext *ctx ) } -/** - * Tell the card where to render (offset, pitch). - * Effected by glDrawBuffer, etc - */ -void -radeonUpdateDrawBuffer(GLcontext *ctx) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct radeon_renderbuffer *rrb; - - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - /* draw to front */ - rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* draw to back */ - rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } else { - /* drawing to multiple buffers, or none */ - return; - } - - assert(rrb); - assert(rrb->pitch); - - RADEON_STATECHANGE( rmesa, ctx ); -} - - void radeonValidateState( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); GLuint new_state = rmesa->radeon.NewGLState; if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - radeonUpdateDrawBuffer(ctx); + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + RADEON_STATECHANGE(rmesa, ctx); } if (new_state & _NEW_TEXTURE) { -- cgit v1.2.3