diff options
Diffstat (limited to 'xc/lib/GL/mesa')
61 files changed, 13083 insertions, 3125 deletions
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index 88b259502..0f0dcebf5 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -23,7 +23,10 @@ DRIVER += common mga DRIVER += common i810 #endif #if GlxBuiltInR128 -DRIVER += r128 +DRIVER += common r128 +#endif +#if GlxBuiltInRadeon +DRIVER += common radeon #endif #if GlxBuiltInFfb DRIVER += ffb @@ -43,17 +46,19 @@ SUBDIRS += gamma SUBDIRS += mga SUBDIRS += i810 SUBDIRS += r128 +SUBDIRS += radeon SUBDIRS += sis #if HasGlide3 SUBDIRS += tdfx #endif -#elif defined(AlphaArchitecture) +#elif defined(AlphaArchitecture) SUBDIRS += common SUBDIRS += gamma SUBDIRS += mga SUBDIRS += r128 +SUBDIRS += radeon #if HasGlide3 SUBDIRS += tdfx #endif @@ -64,7 +69,7 @@ SUBDIRS += ffb #else -SUBDIRS = +SUBDIRS = #endif /* architecture */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c index e11a47a47..03b871538 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -60,188 +60,176 @@ int R128_DEBUG = (0 ); #endif -/* Create the device specific context */ -GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, - __DRIcontextPrivate *driContextPriv) +/* Create the device specific context. + */ +GLboolean r128CreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ) { - r128ContextPtr r128ctx; - r128ScreenPtr r128scrn; - GLcontext *ctx = driContextPriv->mesaContext; - int i; - char *v; - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - - r128ctx = (r128ContextPtr)Xcalloc(1, sizeof(*r128ctx)); - if (!r128ctx) return GL_FALSE; - - /* Initialize r128Context */ - r128ctx->glCtx = ctx; - r128ctx->display = dpy; - - r128ctx->driContext = driContextPriv; - r128ctx->driScreen = sPriv; - r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */ - - r128ctx->hHWContext = driContextPriv->hHWContext; - r128ctx->driFd = sPriv->fd; - r128ctx->driHwLock = &sPriv->pSAREA->lock; + GLcontext *ctx = driContextPriv->mesaContext; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + r128ContextPtr rmesa; + r128ScreenPtr r128scrn; + int i; + + rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) return GL_FALSE; + + rmesa->glCtx = ctx; + rmesa->display = dpy; + + rmesa->driContext = driContextPriv; + rmesa->driScreen = sPriv; + rmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + + rmesa->hHWContext = driContextPriv->hHWContext; + rmesa->driHwLock = &sPriv->pSAREA->lock; + rmesa->driFd = sPriv->fd; + + r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private); + + rmesa->sarea = (R128SAREAPrivPtr)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); + + rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + if ( !rmesa->tmp_matrix ) { + FREE( rmesa ); + return GL_FALSE; + } + + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; + + make_empty_list( &rmesa->SwappedOut ); + + for ( i = 0 ; i < r128scrn->numTexHeaps ; i++ ) { + make_empty_list( &rmesa->TexObjList[i] ); + rmesa->texHeap[i] = mmInit( 0, r128scrn->texSize[i] ); + rmesa->lastTexAge[i] = -1; + } + rmesa->lastTexHeap = r128scrn->numTexHeaps; + + rmesa->RenderIndex = -1; /* Impossible value */ + rmesa->OnFastPath = 0; + + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + rmesa->elt_buf = NULL; + rmesa->retained_buf = NULL; + rmesa->vert_heap = r128scrn->buffers->list->address; + + /* KW: Set the maximum texture size small enough that we can + * guarentee that both texture units can bind a maximal texture + * and have them both in on-card memory at once. (Kevin or + * Gareth: Please check these numbers are OK) + */ + if ( r128scrn->texSize[0] < 2*1024*1024 ) { + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = (1 << 8); + } else if ( r128scrn->texSize[0] < 8*1024*1024 ) { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = (1 << 9); + } else { + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = (1 << 10); + } + + ctx->Const.MaxTextureUnits = 2; - r128scrn = r128ctx->r128Screen = (r128ScreenPtr)(sPriv->private); - - r128ctx->sarea = (R128SAREAPriv *)((char *)sPriv->pSAREA + - sizeof(XF86DRISAREARec)); - - r128ctx->CurrentTexObj[0] = NULL; - r128ctx->CurrentTexObj[1] = NULL; - make_empty_list(&r128ctx->SwappedOut); - for (i = 0; i < r128scrn->NRTexHeaps; i++) { - make_empty_list(&r128ctx->TexObjList[i]); - r128ctx->texHeap[i] = mmInit(0, r128scrn->texSize[i]); - r128ctx->lastTexAge[i] = -1; - } - r128ctx->lastTexHeap = r128scrn->NRTexHeaps; - - r128ctx->DepthSize = glVisual->DepthBits; - r128ctx->StencilSize = glVisual->StencilBits; - - r128ctx->useFastPath = GL_FALSE; - r128ctx->lod_bias = 0x3f; +#if ENABLE_PERF_BOXES + if ( getenv( "LIBGL_PERFORMANCE_BOXES" ) ) { + rmesa->boxes = 1; + } else { + rmesa->boxes = 0; + } +#endif - r128ctx->num_verts = 0; - r128ctx->vert_buf = NULL; + ctx->DriverCtx = (void *)rmesa; - r128ctx->elt_buf = NULL; - r128ctx->retained_buf = NULL; - r128ctx->vert_heap = r128ctx->r128Screen->buffers->list->address; + r128DDInitExtensions( ctx ); -#if 0 - r128ctx->CCEbuf= (CARD32 *)MALLOC(sizeof(*r128ctx->CCEbuf) * - r128scrn->ringEntries); - r128ctx->CCEcount = 0; -#endif + r128DDInitDriverFuncs( ctx ); + r128DDInitIoctlFuncs( ctx ); + r128DDInitStateFuncs( ctx ); + r128DDInitSpanFuncs( ctx ); + r128DDInitTextureFuncs( ctx ); - if ((v = getenv("LIBGL_CCE_TIMEOUT"))) - r128ctx->CCEtimeout = strtoul(v, NULL, 10); - else - r128ctx->CCEtimeout = (R128_DEFAULT_TOTAL_CCE_TIMEOUT / - R128_DEFAULT_CCE_TIMEOUT); - if (r128ctx->CCEtimeout <= 0) r128ctx->CCEtimeout = 1; - - /* Initialize GLcontext */ - ctx->DriverCtx = (void *)r128ctx; - - r128DDInitExtensions(ctx); - - r128DDInitDriverFuncs(ctx); - r128DDInitIoctlFuncs(ctx); - r128DDInitStateFuncs(ctx); - r128DDInitSpanFuncs(ctx); - r128DDInitTextureFuncs(ctx); - - ctx->Driver.TriangleCaps = (DD_TRI_CULL - | DD_TRI_LIGHT_TWOSIDE - | DD_TRI_OFFSET); - - /* Ask Mesa to clip fog coordinates for us - */ - ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - - /* Reset Mesa's current 2D texture pointers to the driver's textures */ - ctx->Shared->DefaultD[2][0].DriverData = NULL; - ctx->Shared->DefaultD[2][1].DriverData = NULL; - - /* KW: Set the maximum texture size small enough that we can - * guarentee that both texture units can bind a maximal texture - * and have them both in on-card memory at once. (Kevin or - * Gareth: Please check these numbers are OK) - */ - if (r128scrn->texSize[0] < 2*1024*1024) { - ctx->Const.MaxTextureLevels = 9; - ctx->Const.MaxTextureSize = 1<<8; - } else if (r128scrn->texSize[0] < 8*1024*1024) { - ctx->Const.MaxTextureLevels = 10; - ctx->Const.MaxTextureSize = 1<<9; - } else { - ctx->Const.MaxTextureLevels = 11; - ctx->Const.MaxTextureSize = 1<<10; - } - - ctx->Const.MaxTextureUnits = 2; + ctx->Driver.TriangleCaps = (DD_TRI_CULL | + DD_TRI_LIGHT_TWOSIDE | + DD_TRI_STIPPLE | + DD_TRI_OFFSET); -#if ENABLE_PERF_BOXES - if (getenv("LIBGL_PERFORMANCE_BOXES")) - r128ctx->boxes = 1; - else - r128ctx->boxes = 0; -#endif + /* Ask Mesa to clip fog coordinates for us. + */ + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - /* If Mesa has current a vertex buffer, make sure the driver's VB - data is up to date */ - if (ctx->VB) r128DDRegisterVB(ctx->VB); + if ( ctx->VB ) + r128DDRegisterVB( ctx->VB ); - /* Register the fast path */ - if (ctx->NrPipelineStages) - ctx->NrPipelineStages = - r128DDRegisterPipelineStages(ctx->PipelineStage, - ctx->PipelineStage, - ctx->NrPipelineStages); + if ( ctx->NrPipelineStages ) { + ctx->NrPipelineStages = + r128DDRegisterPipelineStages( ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages ); + } - r128DDInitState(r128ctx); + r128DDInitState( rmesa ); - driContextPriv->driverPrivate = (void *)r128ctx; + driContextPriv->driverPrivate = (void *)rmesa; - return GL_TRUE; + return GL_TRUE; } -/* Destroy the device specific context */ -void r128DestroyContext(r128ContextPtr r128ctx) +/* Destroy the device specific context. + */ +void r128DestroyContext( r128ContextPtr rmesa ) { - if (r128ctx) { - r128TexObjPtr t, next_t; - int i; + if ( rmesa ) { + r128TexObjPtr t, next_t; + int i; -#if 0 - FREE( r128ctx->CCEbuf ); -#endif + for ( i = 0 ; i < rmesa->r128Screen->numTexHeaps ; i++ ) { + foreach_s ( t, next_t, &rmesa->TexObjList[i] ) { + r128DestroyTexObj( rmesa, t ); + } + mmDestroy( rmesa->texHeap[i] ); + } - for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) { - foreach_s (t, next_t, &r128ctx->TexObjList[i]) - r128DestroyTexObj(r128ctx, t); - } + foreach_s ( t, next_t, &rmesa->SwappedOut ) { + r128DestroyTexObj( rmesa, t ); + } - foreach_s (t, next_t, &r128ctx->SwappedOut) - r128DestroyTexObj(r128ctx, t); - - Xfree(r128ctx); - } + ALIGN_FREE( rmesa->tmp_matrix ); + FREE( rmesa ); + } #if 0 - glx_fini_prof(); + /* Use this to force shared object profiling. */ + glx_fini_prof(); #endif } /* Load the device specific context into the hardware. The actual - setting of the hardware state is done in the r128UpdateHWState(). */ -r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, - r128ContextPtr newCtx, - __DRIdrawablePrivate *dPriv) + * setting of the hardware state is done in the r128UpdateHWState(). + */ +r128ContextPtr r128MakeCurrent( r128ContextPtr oldCtx, + r128ContextPtr newCtx, + __DRIdrawablePrivate *dPriv ) { - if (oldCtx) { - if (!R128CCE_USE_RING_BUFFER(newCtx->r128Screen->CCEMode)) - newCtx->dirty |= R128_REQUIRE_QUIESCENCE; - if (oldCtx != newCtx) { - newCtx->new_state |= R128_NEW_CONTEXT; - newCtx->dirty = R128_UPLOAD_ALL; - } - if (oldCtx->driDrawable != dPriv) { - newCtx->new_state |= R128_NEW_WINDOW; - } - } else { - newCtx->new_state |= R128_NEW_CONTEXT; - newCtx->dirty = R128_UPLOAD_ALL; - } - - newCtx->driDrawable = dPriv; - - return newCtx; + if ( oldCtx ) { + if ( oldCtx != newCtx ) { + newCtx->new_state |= R128_NEW_CONTEXT; + newCtx->dirty = R128_UPLOAD_ALL; + } + if ( oldCtx->driDrawable != dPriv ) { + newCtx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; + } + } else { + newCtx->new_state |= R128_NEW_CONTEXT; + newCtx->dirty = R128_UPLOAD_ALL; + } + + newCtx->driDrawable = dPriv; + + return newCtx; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h index a6f5b31ae..46ddcff3b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -33,8 +33,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#ifndef _R128_CONTEXT_H_ -#define _R128_CONTEXT_H_ +#ifndef __R128_CONTEXT_H__ +#define __R128_CONTEXT_H__ #ifdef GLX_DIRECT_RENDERING @@ -67,7 +67,7 @@ typedef struct r128_context *r128ContextPtr; #define R128_NEW_CLIP 0x0008 #define R128_NEW_CULL 0x0010 #define R128_NEW_MASKS 0x0020 -#define R128_NEW_RENDER 0x0040 +#define R128_NEW_RENDER_NOT 0x0040 #define R128_NEW_WINDOW 0x0080 #define R128_NEW_TEXTURE 0x0100 #define R128_NEW_CONTEXT 0x0200 @@ -101,168 +101,155 @@ typedef void (*r128_interp_func)( GLfloat t, struct r128_elt_tab { void (*emit_unclipped_verts)( struct vertex_buffer *VB ); - void (*build_tri_verts)( r128ContextPtr r128ctx, + void (*build_tri_verts)( r128ContextPtr rmesa, struct vertex_buffer *VB, GLfloat *O, GLuint *elt ); void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); - void (*project_and_emit_verts)( r128ContextPtr r128ctx, + void (*project_and_emit_verts)( r128ContextPtr rmesa, const GLfloat *verts, GLuint *elts, - int nr ); + GLuint nr ); }; struct r128_context { - GLcontext *glCtx; /* Mesa context */ + GLcontext *glCtx; /* Mesa context */ /* Driver and hardware state management */ - GLuint new_state; - GLuint dirty; /* Hardware state to be updated */ - r128_context_regs_t setup; + GLuint new_state; + GLuint dirty; /* Hardware state to be updated */ + r128_context_regs_t setup; - GLuint vertsize; - CARD32 vc_format; - GLfloat depth_scale; + GLuint vertsize; + GLuint vc_format; + GLfloat depth_scale; - CARD32 Color; /* Current draw color */ - CARD32 ClearColor; /* Color used to clear color buffer */ - CARD32 ClearDepth; /* Value used to clear depth buffer */ - CARD32 ClearStencil; /* Value used to clear stencil */ + CARD32 Color; /* Current draw color */ + CARD32 ClearColor; /* Color used to clear color buffer */ + CARD32 ClearDepth; /* Value used to clear depth buffer */ + CARD32 ClearStencil; /* Value used to clear stencil */ /* Map GL texture units onto hardware */ - GLint multitex; - GLint tmu_source[2]; - GLint tex_dest[2]; - GLuint blend_flags; - CARD32 env_color; - GLint lod_bias; + GLint multitex; + GLint tmu_source[2]; + GLint tex_dest[2]; + GLuint tex_combine[2]; + GLuint blend_flags; + GLuint env_color; /* Texture object bookkeeping */ - r128TexObjPtr CurrentTexObj[2]; - r128TexObj TexObjList[R128_NR_TEX_HEAPS]; - r128TexObj SwappedOut; - memHeap_t *texHeap[R128_NR_TEX_HEAPS]; - GLint lastTexAge[R128_NR_TEX_HEAPS]; - GLint lastTexHeap; + r128TexObjPtr CurrentTexObj[2]; + r128TexObj TexObjList[R128_NR_TEX_HEAPS]; + r128TexObj SwappedOut; + memHeap_t *texHeap[R128_NR_TEX_HEAPS]; + GLint lastTexAge[R128_NR_TEX_HEAPS]; + GLint lastTexHeap; /* Current rendering state, fallbacks */ - points_func PointsFunc; - line_func LineFunc; - triangle_func TriangleFunc; - quad_func QuadFunc; + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; - CARD32 IndirectTriangles; - CARD32 Fallback; + GLuint IndirectTriangles; + GLuint Fallback; /* Fast path */ - GLuint useFastPath; - GLuint SetupIndex; - GLuint SetupDone; - GLuint RenderIndex; - r128_interp_func interp; + GLuint SetupIndex; + GLuint SetupDone; + GLuint RenderIndex; + GLuint OnFastPath; + r128_interp_func interp; + GLfloat *tmp_matrix; /* Vertex buffers */ - drmBufPtr vert_buf; - GLuint num_verts; + drmBufPtr vert_buf; + GLuint num_verts; /* Elt path */ - drmBufPtr elt_buf, retained_buf; - GLushort *first_elt, *next_elt; - GLfloat *next_vert, *vert_heap; - GLushort next_vert_index; - GLushort first_vert_index; - GLuint elt_vertsize; - struct r128_elt_tab *elt_tab; - GLfloat device_matrix[16]; - - /* CCE command packets + drmBufPtr elt_buf, retained_buf; + GLushort *first_elt, *next_elt; + GLfloat *next_vert, *vert_heap; + GLushort next_vert_index; + GLushort first_vert_index; + GLuint elt_vertsize; + struct r128_elt_tab *elt_tab; + GLfloat device_matrix[16]; + + /* Page flipping */ -#if 0 - CARD32 *CCEbuf; /* buffer to submit to CCE */ - GLuint CCEcount; /* number of dwords in CCEbuf */ -#endif - GLint CCEtimeout; /* number of times to loop - before exiting */ + GLuint doPageFlip; + GLuint currentPage; - /* Visual, drawable, cliprect and scissor information + /* Drawable, cliprect and scissor information */ - GLint DepthSize; /* Bits in depth buffer */ - GLint StencilSize; /* Bits in stencil buffer */ - - GLenum DrawBuffer; /* Optimize draw buffer update */ - GLint drawOffset, drawPitch; - GLint drawX, drawY; - GLint readOffset, readPitch; - GLint readX, readY; + GLenum DrawBuffer; /* Optimize draw buffer update */ + GLint drawOffset, drawPitch; + GLint readOffset, readPitch; - GLuint numClipRects; /* Cliprects for the draw buffer */ - XF86DRIClipRectPtr pClipRects; + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; - GLuint scissor; - XF86DRIClipRectRec ScissorRect; /* Current software scissor */ + GLuint scissor; + XF86DRIClipRectRec ScissorRect; /* Current software scissor */ /* Mirrors of some DRI state */ - Display *display; /* X server display */ + Display *display; /* X server display */ __DRIcontextPrivate *driContext; /* DRI context */ __DRIscreenPrivate *driScreen; /* DRI screen */ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ - drmContext hHWContext; - drmLock *driHwLock; - int driFd; + drmContext hHWContext; + drmLock *driHwLock; + int driFd; - r128ScreenPtr r128Screen; /* Screen private DRI data */ - R128SAREAPriv *sarea; /* Private SAREA data */ + r128ScreenPtr r128Screen; /* Screen private DRI data */ + R128SAREAPrivPtr sarea; /* Private SAREA data */ /* Performance counters - */ - GLuint boxes; /* Draw performance boxes */ - GLuint hardwareWentIdle; - GLuint c_clears; - GLuint c_drawWaits; - GLuint c_textureSwaps; - GLuint c_textureBytes; - GLuint c_vertexBuffers; + */ + GLuint boxes; /* Draw performance boxes */ + GLuint hardwareWentIdle; + GLuint c_clears; + GLuint c_drawWaits; + GLuint c_textureSwaps; + GLuint c_textureBytes; + GLuint c_vertexBuffers; }; #define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) -#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx) -#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable) -#define R128_DRISCREEN(r128ctx) ((r128ctx)->r128Screen->driScreen) - -#define R128_IS_PLAIN( r128ctx ) \ - (r128ctx->r128Screen->chipset == R128_CARD_TYPE_R128) -#define R128_IS_PRO( r128ctx ) \ - (r128ctx->r128Screen->chipset == R128_CARD_TYPE_R128_PRO) -#define R128_IS_MOBILITY( r128ctx ) \ - (r128ctx->r128Screen->chipset == R128_CARD_TYPE_R128_MOBILITY) +#define R128_IS_PLAIN( rmesa ) \ + (rmesa->r128Screen->chipset == R128_CARD_TYPE_R128) +#define R128_IS_PRO( rmesa ) \ + (rmesa->r128Screen->chipset == R128_CARD_TYPE_R128_PRO) +#define R128_IS_MOBILITY( rmesa ) \ + (rmesa->r128Screen->chipset == R128_CARD_TYPE_R128_MOBILITY) -extern GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, - __DRIcontextPrivate *driContextPriv); -extern void r128DestroyContext(r128ContextPtr r128ctx); -extern r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, - r128ContextPtr newCtx, - __DRIdrawablePrivate *dPriv); +extern GLboolean r128CreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ); +extern void r128DestroyContext( r128ContextPtr rmesa ); +extern r128ContextPtr r128MakeCurrent( r128ContextPtr oldCtx, + r128ContextPtr newCtx, + __DRIdrawablePrivate *dPriv ); /* ================================================================ * Debugging: */ #define DEBUG 0 -#define DEBUG_LOCKING 0 #define ENABLE_PERF_BOXES 0 #if DEBUG @@ -280,4 +267,4 @@ extern int R128_DEBUG; #define DEBUG_VERBOSE_2D 0x40 #endif -#endif /* _R128_CONTEXT_H_ */ +#endif /* __R128_CONTEXT_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c index a16b04276..67a548339 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -45,43 +45,48 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "X86/common_x86_asm.h" #endif -#define R128_DATE "20001215" +#define R128_DATE "20010101" -/* Return the current color buffer size */ + +/* Return the width and height of the current color buffer. + */ static void r128DDGetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - *width = r128ctx->driDrawable->w; - *height = r128ctx->driDrawable->h; + LOCK_HARDWARE( rmesa ); + *width = rmesa->driDrawable->w; + *height = rmesa->driDrawable->h; + UNLOCK_HARDWARE( rmesa ); } -/* Return various strings for glGetString() */ +/* Return various strings for glGetString(). + */ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); static GLubyte buffer[128]; switch ( name ) { case GL_VENDOR: - return (const GLubyte *)"VA Linux Systems, Inc."; + return "VA Linux Systems, Inc."; case GL_RENDERER: sprintf((void *)buffer, "Mesa DRI Rage128 " R128_DATE ); /* Append any chipset-specific information. */ - if ( R128_IS_PRO( r128ctx ) ) { + if ( R128_IS_PRO( rmesa ) ) { strncat( buffer, " Pro", 4 ); } - if ( R128_IS_MOBILITY( r128ctx ) ) { + if ( R128_IS_MOBILITY( rmesa ) ) { strncat( buffer, " M3", 3 ); } /* Append any AGP-specific information. */ - switch ( r128ctx->r128Screen->AGPMode ) { + switch ( rmesa->r128Screen->AGPMode ) { case 1: strncat( buffer, " AGP 1x", 7 ); break; @@ -124,19 +129,19 @@ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) */ static void r128DDFlush( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); #if ENABLE_PERF_BOXES - if ( r128ctx->boxes ) { - LOCK_HARDWARE( r128ctx ); - r128PerformanceBoxesLocked( r128ctx ); - UNLOCK_HARDWARE( r128ctx ); + if ( rmesa->boxes ) { + LOCK_HARDWARE( rmesa ); + r128PerformanceBoxesLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); } /* Log the performance counters if necessary */ - r128PerformanceCounters( r128ctx ); + r128PerformanceCounters( rmesa ); #endif } @@ -145,21 +150,22 @@ static void r128DDFlush( GLcontext *ctx ) */ static void r128DDFinish( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); #if ENABLE_PERF_BOXES /* Bump the performance counter */ - r128ctx->c_drawWaits++; + rmesa->c_drawWaits++; #endif r128DDFlush( ctx ); - r128WaitForIdle( r128ctx ); + r128WaitForIdle( rmesa ); } -/* Return various parameters requested by Mesa (this is deprecated) */ +/* Return various parameters requested by Mesa (this is deprecated). + */ static GLint r128DDGetParameteri( const GLcontext *ctx, GLint param ) { - switch (param) { + switch ( param ) { case DD_HAVE_HARDWARE_FOG: return 1; default: @@ -167,45 +173,49 @@ static GLint r128DDGetParameteri( const GLcontext *ctx, GLint param ) } } -/* Initialize the extensions supported by this driver */ +/* Initialize the extensions supported by this driver. + */ void r128DDInitExtensions( GLcontext *ctx ) { - /* FIXME: Are there other extensions to enable/disable??? */ - gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); - gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); - gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); - gl_extensions_disable( ctx, "ARB_imaging" ); - gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); + gl_extensions_disable( ctx, "GL_ARB_imaging" ); + gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); + gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); + + gl_extensions_disable( ctx, "GL_EXT_blend_color" ); gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); - gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + gl_extensions_disable( ctx, "GL_EXT_convolution" ); + gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); + gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); + gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); + gl_extensions_disable( ctx, "GL_EXT_texture_env_combine" ); - if ( getenv( "LIBGL_NO_MULTITEXTURE" ) ) - gl_extensions_disable( ctx, "GL_ARB_multitexture" ); + gl_extensions_disable( ctx, "GL_HP_occlusion_test" ); + + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); gl_extensions_disable( ctx, "GL_SGI_color_table" ); gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); - gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); - gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); - gl_extensions_disable( ctx, "GL_EXT_convolution" ); } -/* Initialize the driver's misc functions */ +/* Initialize the driver's misc functions. + */ void r128DDInitDriverFuncs( GLcontext *ctx ) { - ctx->Driver.GetBufferSize = r128DDGetBufferSize; - ctx->Driver.GetString = r128DDGetString; - ctx->Driver.Finish = r128DDFinish; - ctx->Driver.Flush = r128DDFlush; + ctx->Driver.GetBufferSize = r128DDGetBufferSize; + ctx->Driver.GetString = r128DDGetString; + ctx->Driver.Finish = r128DDFinish; + ctx->Driver.Flush = r128DDFlush; - ctx->Driver.Error = NULL; - ctx->Driver.GetParameteri = r128DDGetParameteri; + ctx->Driver.Error = NULL; + ctx->Driver.GetParameteri = r128DDGetParameteri; - ctx->Driver.DrawPixels = NULL; - ctx->Driver.Bitmap = NULL; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; - ctx->Driver.RegisterVB = r128DDRegisterVB; - ctx->Driver.UnregisterVB = r128DDUnregisterVB; - ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline; + ctx->Driver.RegisterVB = r128DDRegisterVB; + ctx->Driver.UnregisterVB = r128DDUnregisterVB; + ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h index 447745c43..005949053 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h @@ -28,18 +28,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_DD_H_ -#define _R128_DD_H_ +#ifndef __R128_DD_H__ +#define __R128_DD_H__ #ifdef GLX_DIRECT_RENDERING -extern void r128DDInitExtensions(GLcontext *ctx); -extern void r128DDInitDriverFuncs(GLcontext *ctx); +extern void r128DDInitExtensions( GLcontext *ctx ); +extern void r128DDInitDriverFuncs( GLcontext *ctx ); #endif -#endif /* _R128_DD_H_ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c index 02085932a..74c29812f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c @@ -1,25 +1,35 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c,v 1.2 2000/12/07 20:26:08 dawes Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + Cedar Park, Texas. +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, PRECISION INSIGHT 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. + +**************************************************************************/ + /* - * GLX Hardware Device Driver for Matrox G400 - * Copyright (C) 1999 Keith Whitwell - * - * 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 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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 <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> * */ @@ -39,193 +49,168 @@ #include "mmath.h" #include "xform.h" -#define DEBUG_ELTPATH 0 /* Always use a full-sized stride for vertices. [FIXME] * Stride in the buffers must be a quadword multiple. */ #define CLIP_STRIDE 10 -static void fire_elts( r128ContextPtr r128ctx ) +static void fire_elts( r128ContextPtr rmesa ) { - int vertsize = r128ctx->vertsize; + GLuint vertsize = rmesa->vertsize; - LOCK_HARDWARE( r128ctx ); - - if ( DEBUG_ELTPATH ) - fprintf( stderr, "\n%s: elt=%p ret=%p vs=%d\n", - __FUNCTION__, r128ctx->elt_buf, - r128ctx->retained_buf, vertsize ); + LOCK_HARDWARE( rmesa ); /* Fire queued elements and discard that buffer if its contents * won't be referenced by future elements. */ - if ( r128ctx->elt_buf ) + if ( rmesa->elt_buf ) { - GLuint retain = (r128ctx->elt_buf == r128ctx->retained_buf); - - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FireEltsLocked( r128ctx, - ((GLuint)r128ctx->first_elt - - (GLuint)r128ctx->elt_buf->address), - ((GLuint)r128ctx->next_elt - - (GLuint)r128ctx->elt_buf->address), + GLuint retain = (rmesa->elt_buf == rmesa->retained_buf); + + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), !retain ); } else if ( !retain ) { - r128ReleaseBufLocked( r128ctx, r128ctx->elt_buf ); + r128ReleaseBufLocked( rmesa, rmesa->elt_buf ); } - r128ctx->elt_buf = 0; + rmesa->elt_buf = 0; } - else if ( r128ctx->vert_buf ) + else if ( rmesa->vert_buf ) { - r128FlushVerticesLocked( r128ctx ); + r128FlushVerticesLocked( rmesa ); } - r128GetEltBufLocked( r128ctx ); + r128GetEltBufLocked( rmesa ); - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); /* Give the compiler a chance to optimize the divisions. */ switch ( vertsize ) { case 8: - r128ctx->next_vert_index = (GLushort) - (((r128ctx->elt_buf->idx + 1) * + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * R128_BUFFER_SIZE / (8 * sizeof(GLuint))) - 1); - r128ctx->next_vert = (GLfloat *) - ((GLuint)r128ctx->vert_heap + - r128ctx->next_vert_index * 8 * sizeof(GLfloat)); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 8 * sizeof(GLfloat)); break; case 10: - r128ctx->next_vert_index = (GLushort) - (((r128ctx->elt_buf->idx + 1) * + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * R128_BUFFER_SIZE / (10 * sizeof(GLuint))) - 1); - r128ctx->next_vert = (GLfloat *) - ((GLuint)r128ctx->vert_heap + - r128ctx->next_vert_index * 10 * sizeof(GLfloat)); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 10 * sizeof(GLfloat)); break; } - r128ctx->first_elt = r128ctx->next_elt = (GLushort *) - ((GLubyte *)r128ctx->elt_buf->address + R128_INDEX_PRIM_OFFSET); - - r128ctx->elt_vertsize = vertsize; + rmesa->first_elt = rmesa->next_elt = (GLushort *) + ((GLubyte *)rmesa->elt_buf->address + R128_INDEX_PRIM_OFFSET); - if ( DEBUG_ELTPATH ) - fprintf( stderr, "new elt=%p idx=%d tot=%d next=%p idx=%d\n\n", - r128ctx->elt_buf, r128ctx->elt_buf->idx, - r128ctx->elt_buf->total, - r128ctx->next_vert, r128ctx->next_vert_index ); - - { - GLint space = (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt); - if ( DEBUG_ELTPATH ) - fprintf( stderr, " new nv=%p ne=%p space=%d\n", - r128ctx->next_vert, r128ctx->next_elt, space ); - } + rmesa->elt_vertsize = vertsize; } -static void release_bufs( r128ContextPtr r128ctx ) +static void release_bufs( r128ContextPtr rmesa ) { - if ( DEBUG_ELTPATH ) - fprintf( stderr, "%s: %d idx=%d\n", - __FUNCTION__, - r128ctx->retained_buf && - r128ctx->retained_buf != r128ctx->elt_buf, - r128ctx->retained_buf ? r128ctx->retained_buf->idx : -1 ); - - if ( r128ctx->retained_buf && r128ctx->retained_buf != r128ctx->elt_buf ) + if ( rmesa->retained_buf && rmesa->retained_buf != rmesa->elt_buf ) { - LOCK_HARDWARE( r128ctx ); - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FireEltsLocked( r128ctx, - ((GLuint)r128ctx->first_elt - - (GLuint)r128ctx->elt_buf->address), - ((GLuint)r128ctx->next_elt - - (GLuint)r128ctx->elt_buf->address), + LOCK_HARDWARE( rmesa ); + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), 0 ); - ALIGN_NEXT_ELT( r128ctx ); - r128ctx->first_elt = r128ctx->next_elt; + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; } - r128ReleaseBufLocked( r128ctx, r128ctx->retained_buf ); - UNLOCK_HARDWARE( r128ctx ); + r128ReleaseBufLocked( rmesa, rmesa->retained_buf ); + UNLOCK_HARDWARE( rmesa ); } - r128ctx->retained_buf = 0; + rmesa->retained_buf = 0; } -#define NEGATIVE(f) (f < 0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) -#define INTERP_RGBA(t, out, a, b) { \ - int i; \ - for (i = 0; i < 4; i++) { \ - GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \ - GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \ - GLfloat fo = LINTERP(t, fa, fb); \ - FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \ - } \ +#define INTERP_RGBA( t, out, a, b ) { \ + GLuint i; \ + for ( i = 0 ; i < 4 ; i++ ) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ + GLfloat fo = LINTERP( t, fa, fb ); \ + FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ + } \ } -#define CLIP(SGN,V,PLANE) \ -if (mask & PLANE) { \ - GLuint *indata = inlist[in]; \ - GLuint *outdata = inlist[in ^= 1]; \ - GLuint nr = n; \ - GLfloat *J = verts[indata[nr-1]]; \ - GLfloat dpJ = (SGN J[V]) + J[3]; \ - \ - for (i = n = 0 ; i < nr ; i++) { \ - GLuint elt_i = indata[i]; \ - GLfloat *I = verts[elt_i]; \ - GLfloat dpI = (SGN I[V]) + I[3]; \ - \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ - GLfloat *O = verts[next_vert]; \ - outdata[n++] = next_vert++; \ - \ - if (NEGATIVE(dpI)) { \ - GLfloat t = dpI / (dpI - dpJ); \ - interp(t, O, I, J); \ - } \ - else \ - { \ - GLfloat t = dpJ / (dpJ - dpI); \ - interp(t, O, J, I); \ - } \ - } \ - \ - if (!NEGATIVE(dpI)) \ - outdata[n++] = elt_i; \ - \ - J = I; \ - dpJ = dpI; \ - } \ - \ - if (n < 3) return; \ -} +#define CLIP( SGN, V, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]]; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + for ( i = n = 0 ; i < nr ; i++ ) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i]; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert]; \ + outdata[n++] = next_vert++; \ + \ + if ( NEGATIVE( dpI ) ) { \ + GLfloat t = dpI / (dpI - dpJ); \ + interp( t, O, I, J ); \ + } \ + else \ + { \ + GLfloat t = dpJ / (dpJ - dpI); \ + interp( t, O, J, I ); \ + } \ + } \ + \ + if ( !NEGATIVE( dpI ) ) \ + outdata[n++] = elt_i; \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if ( n < 3 ) return; \ + } \ +} while (0) -static void r128_tri_clip( r128ContextPtr r128ctx, +static void r128_tri_clip( r128ContextPtr rmesa, struct vertex_buffer *VB, GLuint *elt, GLubyte mask ) { - struct r128_elt_tab *tab = r128ctx->elt_tab; + struct r128_elt_tab *tab = rmesa->elt_tab; r128_interp_func interp = tab->interp; - GLint vertsize = r128ctx->vertsize; + GLuint vertsize = rmesa->vertsize; GLuint inlist[2][VB_MAX_CLIPPED_VERTS]; GLuint in = 0; GLuint n = 3, next_vert = 3; @@ -235,55 +220,44 @@ static void r128_tri_clip( r128ContextPtr r128ctx, /* Build temporary vertices in clipspace. This is the potential * downside to this path. */ - tab->build_tri_verts( r128ctx, VB, (GLfloat *)verts, elt ); + tab->build_tri_verts( rmesa, VB, (GLfloat *)verts, elt ); inlist[0][0] = 0; inlist[0][1] = 1; inlist[0][2] = 2; - CLIP(-,0,CLIP_RIGHT_BIT); - CLIP(+,0,CLIP_LEFT_BIT); - CLIP(-,1,CLIP_TOP_BIT); - CLIP(+,1,CLIP_BOTTOM_BIT); - CLIP(-,2,CLIP_FAR_BIT); - CLIP(+,2,CLIP_NEAR_BIT); + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); { GLuint *out = inlist[in]; - GLint space = (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt); + GLint space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); - if ( DEBUG_ELTPATH ) - fprintf( stderr, " clip nv=%p ne=%p space=%d thresh=%d %d\n", - r128ctx->next_vert, r128ctx->next_elt, - space, (GLint)n * (vertsize + 2) * (GLint)sizeof(GLuint), - space < (GLint)n * (vertsize + 2) * (GLint)sizeof(GLuint) ); - - /* GH: Why the hell do we explicitly have to test the sign of the - * available space here? - */ - if ( space < (GLint)n * (vertsize + 2) * (GLint)sizeof(GLuint) ) { - fire_elts( r128ctx ); + if ( space < (GLint)(n * (vertsize + 2) * sizeof(GLuint)) ) { + fire_elts( rmesa ); } /* Project the new vertices and emit to dma buffers. Translate * out values to physical addresses for setup dma. */ - tab->project_and_emit_verts( r128ctx, (GLfloat *)verts, out, n ); + tab->project_and_emit_verts( rmesa, (GLfloat *)verts, out, n ); /* Convert the planar polygon to a list of triangles and emit to * elt buffers. */ - for (i = 2 ; i < n ; i++) { - r128ctx->next_elt[0] = (GLushort) out[0]; - r128ctx->next_elt[1] = (GLushort) out[i-1]; - r128ctx->next_elt[2] = (GLushort) out[i]; - r128ctx->next_elt += 3; + for ( i = 2 ; i < n ; i++ ) { + rmesa->next_elt[0] = (GLushort) out[0]; + rmesa->next_elt[1] = (GLushort) out[i-1]; + rmesa->next_elt[2] = (GLushort) out[i]; + rmesa->next_elt += 3; } } - if ( DEBUG_ELTPATH ) - fflush( stderr ); } @@ -295,37 +269,22 @@ static void r128_tri_clip( r128ContextPtr r128ctx, * unclipped primitives from the original list. */ -#define INIT(x) +#define INIT( x ) #define TRI_THRESHOLD (GLint)(2 * sizeof(GLuint)) -#define UNCLIPPED_VERT(x) (GLushort)(r128ctx->first_vert_index - x) +#define UNCLIPPED_VERT( x ) (GLushort)(rmesa->first_vert_index - x) #define TRIANGLE( e2, e1, e0 ) \ do { \ - if ( DEBUG_ELTPATH ) \ - fprintf( stderr, " tri nv=%p ne=%p space=%d thresh=%d %d\n", \ - r128ctx->next_vert, r128ctx->next_elt, \ - (GLint)((GLuint)r128ctx->next_vert - \ - (GLuint)r128ctx->next_elt), TRI_THRESHOLD, \ - ( (GLint)((GLuint)r128ctx->next_vert - \ - (GLuint)r128ctx->next_elt) < TRI_THRESHOLD ) );\ - if ( (GLint)((GLuint)r128ctx->next_vert - \ - (GLuint)r128ctx->next_elt) < TRI_THRESHOLD ) { \ - if ( DEBUG_ELTPATH ) \ - fprintf( stderr, " firing elts...\n" ); \ - fire_elts( r128ctx ); \ + if ( (GLint)((GLuint)rmesa->next_vert - \ + (GLuint)rmesa->next_elt) < TRI_THRESHOLD ) { \ + fire_elts( rmesa ); \ } \ - r128ctx->next_elt[0] = UNCLIPPED_VERT( e2 ); \ - r128ctx->next_elt[1] = UNCLIPPED_VERT( e1 ); \ - r128ctx->next_elt[2] = UNCLIPPED_VERT( e0 ); \ - if ( 0 ) \ - fprintf( stderr, " tri %d,%d,%d -> %hd,%hd,%hd\n", \ - e2, e1, e0, r128ctx->next_elt[0], \ - r128ctx->next_elt[1], r128ctx->next_elt[2]); \ - r128ctx->next_elt += 3; \ - if ( DEBUG_ELTPATH ) \ - fflush( stderr ); \ + rmesa->next_elt[0] = UNCLIPPED_VERT( e2 ); \ + rmesa->next_elt[1] = UNCLIPPED_VERT( e1 ); \ + rmesa->next_elt[2] = UNCLIPPED_VERT( e0 ); \ + rmesa->next_elt += 3; \ } while (0) #define CLIP_TRIANGLE( e2, e1, e0 ) \ @@ -337,16 +296,16 @@ do { \ out[0] = e2; \ out[1] = e1; \ out[2] = e0; \ - r128_tri_clip( r128ctx, VB, out, ormask ); \ + r128_tri_clip( rmesa, VB, out, ormask ); \ } \ } while (0) #define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ GLuint *elt = VB->EltPtr->data; \ GLuint out[VB_MAX_CLIPPED_VERTS]; \ GLubyte *mask = VB->ClipMask; \ - (void) mask; (void) out; (void) elt; (void) r128ctx; + (void) mask; (void) out; (void) elt; (void) rmesa; @@ -355,7 +314,7 @@ do { \ #define RENDER_TRI( i2, i1, i0, pv, parity ) \ do { \ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if (parity) e2 = elt[i1], e1 = elt[i2]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ CLIP_TRIANGLE( e2, e1, e0 ); \ } while (0) @@ -369,20 +328,20 @@ do { \ #define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ GLuint *elt = VB->EltPtr->data; \ - (void) elt; (void) r128ctx; + (void) elt; (void) rmesa; #define RENDER_POINTS( start, count ) #define RENDER_LINE( i1, i0 ) #define RENDER_TRI( i2, i1, i0, pv, parity ) \ do { \ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if (parity) e2 = elt[i1], e1 = elt[i2]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ TRIANGLE( e2, e1, e0 ); \ } while (0) -#define RENDER_QUAD(i3, i2, i1, i0, pv ) \ +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ TRIANGLE( elt[i2], elt[i1], elt[i0] ) @@ -394,16 +353,16 @@ do { \ static void refresh_projection_matrix( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLmatrix *mat = &ctx->Viewport.WindowMap; - GLfloat *m = r128ctx->device_matrix; + GLfloat *m = rmesa->device_matrix; m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX]; m[MAT_SY] = -mat->m[MAT_SY]; - m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; - m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale; + m[MAT_TY] = -mat->m[MAT_TY] + rmesa->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * rmesa->depth_scale; } #define CLIP_UBYTE_B 0 @@ -439,7 +398,7 @@ static void refresh_projection_matrix( GLcontext *ctx ) /* Very sparsely popluated array - fix the indices. */ -static struct r128_elt_tab r128EltTab[0x80]; +static struct r128_elt_tab r128EltTab[R128_MAX_SETUPFUNC]; void r128DDEltPathInit( void ) { @@ -451,7 +410,9 @@ void r128DDEltPathInit( void ) r128_init_eltpath_TEX0( &r128EltTab[R128_TEX0_BIT] ); r128_init_eltpath_RGBA_TEX0( &r128EltTab[R128_RGBA_BIT|R128_TEX0_BIT] ); r128_init_eltpath_TEX0_TEX1( &r128EltTab[R128_TEX0_BIT|R128_TEX1_BIT] ); - r128_init_eltpath_RGBA_TEX0_TEX1( &r128EltTab[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] ); + r128_init_eltpath_RGBA_TEX0_TEX1( &r128EltTab[(R128_RGBA_BIT | + R128_TEX0_BIT | + R128_TEX1_BIT)] ); } #define VALID_SETUP (R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT) @@ -473,17 +434,11 @@ void r128DDEltPath( struct vertex_buffer *VB ) { GLcontext *ctx = VB->ctx; GLenum prim = ctx->CVA.elt_mode; - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - struct r128_elt_tab *tab = &r128EltTab[r128ctx->SetupIndex & VALID_SETUP]; - GLint vertsize = r128ctx->vertsize; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct r128_elt_tab *tab = &r128EltTab[rmesa->SetupIndex & VALID_SETUP]; + GLuint vertsize = rmesa->vertsize; GLint space; - if ( DEBUG_ELTPATH ) - fprintf( stderr, "\n\n\n%s: count=%d space=%d\n", - __FUNCTION__, VB->Count, - (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt) ); - VB->ClipPtr = TransformRaw( &VB->Clip, &ctx->ModelProjectMatrix, VB->ObjPtr ); @@ -498,40 +453,27 @@ void r128DDEltPath( struct vertex_buffer *VB ) &VB->ClipOrMask, &VB->ClipAndMask ); - if ( VB->ClipAndMask ) { - if ( DEBUG_ELTPATH ) - fprintf( stderr, " clipped, returning...\n" ); + if ( VB->ClipAndMask ) return; - } - if ( r128ctx->vert_buf ) { - r128FlushVertices( r128ctx ); - } - if ( r128ctx->new_state ) { + + if ( rmesa->vert_buf ) + r128FlushVertices( rmesa ); + + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); - } - space = (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt); + space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); /* Allocate a single buffer to hold unclipped vertices. All * unclipped vertices must be contiguous. */ - if ( DEBUG_ELTPATH ) - fprintf( stderr, " top nv=%p ne=%p space=%d reqd=%d count=%d clip=0x%x\n\n", - r128ctx->next_vert, r128ctx->next_elt, space, - (GLint)VB->Count * vertsize * sizeof(GLuint), - VB->Count, VB->ClipOrMask ); - - /* Because we need to adjust the next_elt pointer to accomodate the - * CCE packet header, we can sometimes go past the next_vert pointer - * and thus have negative space. - */ - if ( space < (GLint)VB->Count * vertsize * (GLint)sizeof(GLuint) || - r128ctx->vertsize != r128ctx->elt_vertsize ) { - fire_elts( r128ctx ); + if ( space < (GLint)(VB->Count * vertsize * sizeof(GLuint)) || + rmesa->vertsize != rmesa->elt_vertsize ) { + fire_elts( rmesa ); } - r128ctx->retained_buf = r128ctx->elt_buf; + rmesa->retained_buf = rmesa->elt_buf; /* Emit unclipped vertices to the buffer. */ @@ -540,7 +482,7 @@ void r128DDEltPath( struct vertex_buffer *VB ) /* Emit indices and clipped vertices to one or more buffers. */ if ( VB->ClipOrMask ) { - r128ctx->elt_tab = tab; + rmesa->elt_tab = tab; r128_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 ); } else { r128_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 ); @@ -548,20 +490,10 @@ void r128DDEltPath( struct vertex_buffer *VB ) /* Send to hardware and release the elt buffer. */ - release_bufs( r128ctx ); + release_bufs( rmesa ); /* This indicates that there is no cached data to reuse. */ VB->pipeline->data_valid = 0; VB->pipeline->new_state = 0; - - if ( DEBUG_ELTPATH ) { - FLUSH_BATCH( r128ctx ); - - LOCK_HARDWARE( r128ctx ); - drmR128WaitForIdleCCE( r128ctx->driFd ); - UNLOCK_HARDWARE( r128ctx ); - - __asm__ __volatile__ ( "int $3" ); - } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h index ba82a261f..e477bd7b9 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h @@ -1,25 +1,35 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h,v 1.1 2000/12/04 19:21:46 dawes Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + Cedar Park, Texas. +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, PRECISION INSIGHT 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. + +**************************************************************************/ + /* - * DRI Hardware Device Driver for G200/G400 - * Copyright (C) 1999 Keith Whitwell - * - * 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 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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 <keithw@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -34,8 +44,7 @@ */ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) { - GLuint i; - r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); GLfloat *dev = VB->Projected->start; GLubyte *color = VB->ColorPtr->start; GLfloat *tex0_data = VB->TexCoordPtr[0]->start; @@ -43,45 +52,38 @@ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) GLuint color_stride = VB->ColorPtr->stride; GLuint tex0_stride = VB->TexCoordPtr[0]->stride; GLuint tex1_stride = VB->TexCoordPtr[1]->stride; - GLuint buffer_stride = r128ctx->vertsize; + GLuint buffer_stride = rmesa->vertsize; - GLfloat *f = r128ctx->next_vert; + GLfloat *f = rmesa->next_vert; GLuint count = VB->Count; GLubyte *clipmask = VB->ClipMask; - const GLfloat *m = r128ctx->device_matrix; + const GLfloat *m = rmesa->device_matrix; const GLfloat sx = m[0], sy = m[5], sz = m[10]; const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; - if ( 0 ) - fprintf( stderr, "%s: stride=%d\n", __FUNCTION__, buffer_stride ); - - r128ctx->retained_buf = r128ctx->elt_buf; - r128ctx->first_vert_index = r128ctx->next_vert_index; + rmesa->retained_buf = rmesa->elt_buf; + rmesa->first_vert_index = rmesa->next_vert_index; for ( i = 0 ; i < count ; f -= buffer_stride, i++ ) { if ( !clipmask[i] ) { - if ( 0 ) - fprintf( stderr, "vert=%d addr=%p space=0x%x\n", - i, f, (GLuint)f - (GLuint)r128ctx->elt_buf->address ); - f[0] = sx * dev[0] + tx; f[1] = sy * dev[1] + ty; f[2] = sz * dev[2] + tz; f[3] = dev[3]; - if (TYPE & R128_RGBA_BIT) { + if ( TYPE & R128_RGBA_BIT ) { #if 0 /*defined(USE_X86_ASM)*/ - __asm__ ( - "movl (%%edx),%%eax \n" - "bswap %%eax \n" - "rorl $8,%%eax \n" - "movl %%eax,16(%%edi) \n" - : - : "d" (color), "D" (f) - : "%eax" ); + __asm__ ( "movl (%%edx),%%eax \n" + "bswap %%eax \n" + "rorl $8,%%eax \n" + "movl %%eax,16(%%edi) \n" + : + : "d" (color), "D" (f) + : "%eax" ); #else GLubyte *b = (GLubyte *)&f[4]; b[CLIP_UBYTE_B] = color[2]; @@ -91,25 +93,25 @@ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) #endif } - if (TYPE & R128_TEX0_BIT) { - *(int*)&f[6] = *(int*)&tex0_data[0]; - *(int*)&f[7] = *(int*)&tex0_data[1]; + if ( TYPE & R128_TEX0_BIT ) { + *(GLuint *)&f[6] = *(GLuint *)&tex0_data[0]; + *(GLuint *)&f[7] = *(GLuint *)&tex0_data[1]; } - if (TYPE & R128_TEX1_BIT) { - *(int*)&f[8] = *(int*)&tex1_data[0]; - *(int*)&f[9] = *(int*)&tex1_data[1]; + if ( TYPE & R128_TEX1_BIT ) { + *(GLuint *)&f[8] = *(GLuint *)&tex1_data[0]; + *(GLuint *)&f[9] = *(GLuint *)&tex1_data[1]; } } - STRIDE_F(dev, 16); - if (TYPE & R128_RGBA_BIT) color += color_stride; - if (TYPE & R128_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); - if (TYPE & R128_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); + STRIDE_F( dev, 16 ); + if ( TYPE & R128_RGBA_BIT ) color += color_stride; + if ( TYPE & R128_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & R128_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); } - r128ctx->next_vert = f; - r128ctx->next_vert_index -= count; + rmesa->next_vert = f; + rmesa->next_vert_index -= count; } @@ -117,12 +119,12 @@ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) * Recreate from the VB data rather than trying to read back from * uncached memory. */ -static void TAG(build_tri_verts)( r128ContextPtr r128ctx, +static void TAG(build_tri_verts)( r128ContextPtr rmesa, struct vertex_buffer *VB, GLfloat *O, GLuint *elt ) { - int i; + GLint i; for ( i = 0 ; i < 3 ; i++, O += CLIP_STRIDE ) { GLfloat *clip = VB->Clip.start + elt[i]*4; @@ -132,8 +134,8 @@ static void TAG(build_tri_verts)( r128ContextPtr r128ctx, O[2] = clip[2]; O[3] = clip[3]; - if (TYPE & R128_RGBA_BIT) { - GLubyte *col = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]); + if ( TYPE & R128_RGBA_BIT ) { + GLubyte *col = VEC_ELT( VB->ColorPtr, GLubyte, elt[i] ); GLubyte *b = (GLubyte *)&O[4]; b[CLIP_UBYTE_R] = col[0]; b[CLIP_UBYTE_G] = col[1]; @@ -141,22 +143,16 @@ static void TAG(build_tri_verts)( r128ContextPtr r128ctx, b[CLIP_UBYTE_A] = col[3]; } - if ( 0 ) - fprintf(stderr, - "build_tri_vert elt[%d]=%d index=0x%x (first_index=0x%x)\n", - i, elt[i], (GLuint)UNCLIPPED_VERT(elt[i]), - (GLuint)r128ctx->first_vert_index); - *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]); - if (TYPE & R128_TEX0_BIT) { - GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]); + if ( TYPE & R128_TEX0_BIT ) { + GLfloat *tex0_data = VEC_ELT( VB->TexCoordPtr[0], GLfloat, elt[i] ); *(int*)&O[6] = *(int*)&tex0_data[0]; *(int*)&O[7] = *(int*)&tex0_data[1]; } - if (TYPE & R128_TEX1_BIT) { - GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]); + if ( TYPE & R128_TEX1_BIT ) { + GLfloat *tex1_data = VEC_ELT( VB->TexCoordPtr[1], GLfloat, elt[i] ); *(int*)&O[8] = *(int*)&tex1_data[0]; *(int*)&O[9] = *(int*)&tex1_data[1]; } @@ -171,30 +167,28 @@ static void TAG(interp)( GLfloat t, const GLfloat *I, const GLfloat *J ) { - O[0] = LINTERP(t, I[0], J[0]); - O[1] = LINTERP(t, I[1], J[1]); - O[2] = LINTERP(t, I[2], J[2]); - O[3] = LINTERP(t, I[3], J[3]); - - if (TYPE & R128_RGBA_BIT) { - INTERP_RGBA(t, - ((GLubyte *)&(O[4])), - ((GLubyte *)&(I[4])), - ((GLubyte *)&(J[4]))); + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & R128_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); } - if (0) fprintf(stderr, "setting 0x%x to ~0\n", (GLuint)&O[5]); - *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */ - if (TYPE & R128_TEX0_BIT) { - O[6] = LINTERP(t, I[6], J[6]); - O[7] = LINTERP(t, I[7], J[7]); + if ( TYPE & R128_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); } - if (TYPE & R128_TEX1_BIT) { - O[8] = LINTERP(t, I[8], J[8]); - O[9] = LINTERP(t, I[9], J[9]); + if ( TYPE & R128_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); } } @@ -204,30 +198,26 @@ static void TAG(interp)( GLfloat t, * new ones to dma buffers. Update the element list to a format * suitable for sending to hardware. */ -static void TAG(project_and_emit_verts)( r128ContextPtr r128ctx, +static void TAG(project_and_emit_verts)( r128ContextPtr rmesa, const GLfloat *verts, GLuint *elt, - int nr) + GLuint nr) { - GLfloat *O = r128ctx->next_vert; - GLushort index = r128ctx->next_vert_index; - GLuint buffer_stride = r128ctx->vertsize; + GLfloat *O = rmesa->next_vert; + GLushort index = rmesa->next_vert_index; + GLuint buffer_stride = rmesa->vertsize; - const GLfloat *m = r128ctx->device_matrix; + const GLfloat *m = rmesa->device_matrix; const GLfloat sx = m[0], sy = m[5], sz = m[10]; const GLfloat tx = m[12], ty = m[13], tz = m[14]; GLuint i; - for (i = 0 ; i < nr ; i++) { + for ( i = 0 ; i < nr ; i++ ) { const GLfloat *I = &verts[elt[i] * CLIP_STRIDE]; GLuint tmp = *(GLuint *)&I[5]; - if (0) fprintf(stderr, "elt[%d] (tmp 0x%x %d) %d --> ", - i, (GLuint)&I[5], tmp, elt[i]); - - if ((elt[i] = tmp) == ~0) - { - GLfloat oow = 1.0/I[3]; + if ( (elt[i] = tmp) == ~0 ) { + GLfloat oow = 1.0 / I[3]; elt[i] = index--; @@ -236,37 +226,36 @@ static void TAG(project_and_emit_verts)( r128ContextPtr r128ctx, O[2] = sz * I[2] * oow + tz; O[3] = oow; - if (TYPE & R128_RGBA_BIT) { - *(int*)&O[4] = *(int*)&I[4]; + if ( TYPE & R128_RGBA_BIT ) { + *(GLuint *)&O[4] = *(GLuint *)&I[4]; } - if (TYPE & R128_TEX0_BIT) { - *(int*)&O[6] = *(int*)&I[6]; - *(int*)&O[7] = *(int*)&I[7]; + if ( TYPE & R128_TEX0_BIT ) { + *(GLuint *)&O[6] = *(GLuint *)&I[6]; + *(GLuint *)&O[7] = *(GLuint *)&I[7]; } - if (TYPE & R128_TEX1_BIT) { - *(int*)&O[8] = *(int*)&I[8]; - *(int*)&O[9] = *(int*)&I[9]; + if ( TYPE & R128_TEX1_BIT ) { + *(GLuint *)&O[8] = *(GLuint *)&I[8]; + *(GLuint *)&O[9] = *(GLuint *)&I[9]; } O -= buffer_stride; } - if (0) fprintf(stderr, "0x%x\n", elt[i]); } - r128ctx->next_vert = O; - r128ctx->next_vert_index = index; + rmesa->next_vert = O; + rmesa->next_vert_index = index; } static void TAG(r128_init_eltpath)( struct r128_elt_tab *tab ) { - tab->emit_unclipped_verts = TAG(emit_unclipped_verts); - tab->build_tri_verts = TAG(build_tri_verts); - tab->interp = TAG(interp); - tab->project_and_emit_verts = TAG(project_and_emit_verts); + tab->emit_unclipped_verts = TAG(emit_unclipped_verts); + tab->build_tri_verts = TAG(build_tri_verts); + tab->interp = TAG(interp); + tab->project_and_emit_verts = TAG(project_and_emit_verts); } #undef TYPE diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c index 57dab53a9..df382c641 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c @@ -29,8 +29,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Keith Whitwell <keithw@valinux.com> - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -44,67 +44,58 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "cva.h" #include "vertices.h" -/* HACK: Declare this global for now */ -static GLfloat m[16] __attribute__ ((aligned (16))); - -/* FIXME: These routines were copied from the i810 driver, and were only - slightly modified for the Rage 128. They still need to be optmizied - and cleaned up. Also, support for USE_RHW2 needs to be added. - - KW: The fastpath never does projective texturing, so RHW2 support - isn't necesary here. -*/ struct r128_fast_tab { void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); }; -#define POINT(x) r128_draw_point( r128ctx, &vert[x], psize ) -#define LINE(x,y) r128_draw_line( r128ctx, &vert[x], &vert[y], lwidth ) -#define TRI(x,y,z) r128_draw_triangle( r128ctx, &vert[x], &vert[y], &vert[z] ) +#define POINT(x) r128_draw_point( rmesa, &vert[x], psize ) +#define LINE(x,y) r128_draw_line( rmesa, &vert[x], &vert[y], lwidth ) +#define TRI(x,y,z) r128_draw_triangle( rmesa, &vert[x], &vert[y], &vert[z] ) /* Direct, and no clipping required. The clip funcs have not been - written yet, so this is only useful for the fast path. */ -#define RENDER_POINTS(start, count) \ + * written yet, so this is only useful for the fast path. + */ +#define RENDER_POINTS( start, count ) \ do { \ GLuint e; \ - for (e = start; e < count; e++) \ - POINT(elt[e]); \ + for ( e = start ; e < count ; e++ ) \ + POINT( elt[e] ); \ } while (0) -#define RENDER_LINE(i1, i) \ +#define RENDER_LINE( i1, i ) \ do { \ GLuint e1 = elt[i1], e = elt[i]; \ - LINE(e1, e); \ + LINE( e1, e ); \ } while (0) -#define RENDER_TRI(i2, i1, i, pv, parity) \ +#define RENDER_TRI( i2, i1, i, pv, parity ) \ do { \ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - if (parity) { \ + if ( parity ) { \ GLuint tmp = e2; \ e2 = e1; \ e1 = tmp; \ } \ - TRI(e2, e1, e); \ + TRI( e2, e1, e ); \ } while (0) -#define RENDER_QUAD(i3, i2, i1, i, pv) \ +#define RENDER_QUAD( i3, i2, i1, i, pv ) \ do { \ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - TRI(e3, e2, e); \ - TRI(e2, e1, e); \ + TRI( e3, e2, e ); \ + TRI( e2, e1, e ); \ } while (0) #define LOCAL_VARS \ - r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \ - const GLuint *elt = VB->EltPtr->data; \ - GLcontext *ctx = VB->ctx; \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - const GLfloat lwidth = ctx->Line.Width; \ - const GLfloat psize = ctx->Point.Size; \ + r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + GLcontext *ctx = VB->ctx; \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + const GLfloat lwidth = ctx->Line.Width; \ + const GLfloat psize = ctx->Point.Size; \ (void) lwidth; (void) psize; (void) vert; #define TAG(x) r128_##x##_smooth_indirect @@ -112,12 +103,12 @@ do { \ -#define NEGATIVE(f) (f < 0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A))) +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) -#define INTERP_RGBA(t, out, a, b) \ +#define INTERP_RGBA( t, out, a, b ) \ do { \ int i; \ for (i = 0; i < 4; i++) { \ @@ -129,9 +120,9 @@ do { \ } while (0) -#define CLIP(SGN, V, PLANE) \ +#define CLIP( SGN, V, PLANE ) \ do { \ - if (mask & PLANE) { \ + if ( mask & PLANE ) { \ GLuint *indata = inlist[in]; \ GLuint *outdata = inlist[in ^= 1]; \ GLuint nr = n; \ @@ -139,16 +130,16 @@ do { \ GLfloat dpJ = (SGN J[V]) + J[3]; \ \ inlist[0] = vlist1; \ - for (i = n = 0 ; i < nr ; i++) { \ + for ( i = n = 0 ; i < nr ; i++ ) { \ GLuint elt_i = indata[i]; \ GLfloat *I = verts[elt_i].f; \ GLfloat dpI = (SGN I[V]) + I[3]; \ \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ GLfloat *O = verts[next_vert].f; \ GLfloat t, *in, *out; \ \ - if (NEGATIVE(dpI)) { \ + if ( NEGATIVE( dpI ) ) { \ t = dpI / (dpI - dpJ); \ in = I; \ out = J; \ @@ -158,7 +149,7 @@ do { \ out = I; \ } \ \ - interp(t, O, in, out); \ + interp( t, O, in, out ); \ \ clipmask[next_vert] = 0; \ outdata[n++] = next_vert++; \ @@ -166,7 +157,7 @@ do { \ \ clipmask[elt_i] |= PLANE; /* don't set up */ \ \ - if (!NEGATIVE(dpI)) { \ + if ( !NEGATIVE( dpI ) ) { \ outdata[n++] = elt_i; \ clipmask[elt_i] &= ~PLANE; /* set up after all */ \ } \ @@ -175,25 +166,25 @@ do { \ dpJ = dpI; \ } \ \ - if (n < 3) return; \ + if ( n < 3 ) return; \ } \ } while (0) -#define LINE_CLIP(x,y,z,w,PLANE) \ +#define LINE_CLIP( x, y, z, w, PLANE ) \ do { \ - if (mask & PLANE) { \ - GLfloat dpI = DOT4V(I,x,y,z,w); \ - GLfloat dpJ = DOT4V(J,x,y,z,w); \ + if ( mask & PLANE ) { \ + GLfloat dpI = DOT4V( I, x, y, z, w ); \ + GLfloat dpJ = DOT4V( J, x, y, z, w ); \ \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ GLfloat *O = verts[next_vert].f; \ GLfloat t = dpI / (dpI - dpJ); \ \ - interp(t, O, I, J); \ + interp( t, O, I, J ); \ \ clipmask[next_vert] = 0; \ \ - if (NEGATIVE(dpI)) { \ + if ( NEGATIVE( dpI ) ) { \ clipmask[elts[0]] |= PLANE; \ I = O; \ elts[0] = next_vert++; \ @@ -202,13 +193,13 @@ do { \ J = O; \ elts[1] = next_vert++; \ } \ - } else if (NEGATIVE(dpI)) return; \ + } else if ( NEGATIVE( dpI ) ) return; \ } \ } while (0) static __inline void r128_tri_clip( GLuint **p_elts, - r128Vertex *verts, + r128VertexPtr verts, GLubyte *clipmask, GLuint *p_next_vert, GLubyte mask, @@ -237,7 +228,7 @@ static __inline void r128_tri_clip( GLuint **p_elts, /* Convert the planar polygon to a list of triangles */ out = inlist[in]; - for (i = 2 ; i < n ; i++) { + for ( i = 2 ; i < n ; i++ ) { elts[0] = out[0]; elts[1] = out[i-1]; elts[2] = out[i]; @@ -250,7 +241,7 @@ static __inline void r128_tri_clip( GLuint **p_elts, static __inline void r128_line_clip( GLuint **p_elts, - r128Vertex *verts, + r128VertexPtr verts, GLubyte *clipmask, GLuint *p_next_vert, GLubyte mask, @@ -274,26 +265,27 @@ static __inline void r128_line_clip( GLuint **p_elts, -#define CLIP_POINT(e) \ +#define CLIP_POINT( e ) \ do { \ if (mask[e]) *out++ = e; \ } while (0) -#define CLIP_LINE(e1, e0) \ +#define CLIP_LINE( e1, e0 ) \ do { \ GLubyte ormask = mask[e0] | mask[e1]; \ out[0] = e1; \ out[1] = e0; \ out += 2; \ - if (ormask) { \ + if ( ormask ) { \ out-=2; \ - if (!(mask[e0] & mask[e1])) { \ - r128_line_clip(&out, verts, mask, &next_vert, ormask, interp); \ + if ( !(mask[e0] & mask[e1]) ) { \ + r128_line_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ } \ } \ } while (0) -#define CLIP_TRIANGLE(e2, e1, e0) \ +#define CLIP_TRIANGLE( e2, e1, e0 ) \ do { \ GLubyte ormask; \ out[0] = e2; \ @@ -301,10 +293,11 @@ do { \ out[2] = e0; \ out += 3; \ ormask = mask[e2] | mask[e1] | mask[e0]; \ - if (ormask) { \ + if ( ormask ) { \ out -= 3; \ - if (!(mask[e2] & mask[e1] & mask[e0])) { \ - r128_tri_clip(&out, verts, mask, &next_vert, ormask, interp); \ + if ( !(mask[e2] & mask[e1] & mask[e0]) ) { \ + r128_tri_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ } \ } \ } while (0) @@ -316,47 +309,47 @@ do { \ * ie (points, lines, triangles) containing all the clipped and * unclipped primitives from the original list. */ -#define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \ - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \ - GLuint *elt = VB->EltPtr->data; \ - r128Vertex *verts = r128VB->verts; \ - GLuint next_vert = r128VB->last_vert; \ - GLuint *out = r128VB->clipped_elements.data; \ - GLubyte *mask = VB->ClipMask; \ - r128_interp_func interp = r128ctx->interp; \ +#define LOCAL_VARS \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \ + GLuint *elt = VB->EltPtr->data; \ + r128VertexPtr verts = r128VB->verts; \ + GLuint next_vert = r128VB->last_vert; \ + GLuint *out = r128VB->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + r128_interp_func interp = rmesa->interp; \ (void) interp; (void) verts; -#define POSTFIX \ - r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \ +#define POSTFIX \ + r128VB->clipped_elements.count = out - r128VB->clipped_elements.data;\ r128VB->last_vert = next_vert; -#define INIT(x) +#define INIT( x ) -#define RENDER_POINTS(start, count) \ -do { \ - GLuint i; \ - for (i = start; i < count; i++) \ - CLIP_POINT(elt[i]); \ +#define RENDER_POINTS( start, count ) \ +do { \ + GLuint i; \ + for ( i = start ; i < count ; i++ ) \ + CLIP_POINT( elt[i] ); \ } while (0) -#define RENDER_LINE(i1, i0) \ -do { \ - CLIP_LINE(elt[i1], elt[i0]); \ +#define RENDER_LINE( i1, i0 ) \ +do { \ + CLIP_LINE( elt[i1], elt[i0] ); \ } while (0) -#define RENDER_TRI(i2, i1, i0, pv, parity) \ -do { \ - GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if (parity) e2 = elt[i1], e1 = elt[i2]; \ - CLIP_TRIANGLE(e2, e1, e0); \ +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ } while (0) -#define RENDER_QUAD(i3, i2, i1, i0, pv) \ -do { \ - CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ - CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]); \ +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ +do { \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ); \ } while (0) #define TAG(x) r128_##x##_clip_elt @@ -406,17 +399,16 @@ do { \ -/* Render elements directly from original list of vertices. */ static void r128_render_elements_direct( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = r128_render_tab_smooth_indirect[prim]; - GLuint p = 0; - - if ( r128ctx->new_state ) + GLcontext *ctx = VB->ctx; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = r128_render_tab_smooth_indirect[prim]; + GLuint p = 0; + + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); do { @@ -425,20 +417,20 @@ static void r128_render_elements_direct( struct vertex_buffer *VB ) ctx->Driver.MultipassFunc( VB, ++p ) ); } -/* Project vertices from clip to device space */ static void r128_project_vertices( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - GLmatrix *mat = &ctx->Viewport.WindowMap; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX]; m[MAT_SY] = -mat->m[MAT_SY]; - m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; - m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale; + m[MAT_TY] = -mat->m[MAT_TY] + rmesa->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * rmesa->depth_scale; gl_project_v16( r128VB->verts[VB->CopyStart].f, r128VB->verts[r128VB->last_vert].f, @@ -446,20 +438,20 @@ static void r128_project_vertices( struct vertex_buffer *VB ) 16 * 4 ); } -/* Project clipped vertices from clip to device space */ static void r128_project_clipped_vertices( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - GLmatrix *mat = &ctx->Viewport.WindowMap; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX]; m[MAT_SY] = -mat->m[MAT_SY]; - m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; - m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale; + m[MAT_TY] = -mat->m[MAT_TY] + rmesa->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * rmesa->depth_scale; gl_project_clipped_v16( r128VB->verts[VB->CopyStart].f, r128VB->verts[r128VB->last_vert].f, @@ -468,9 +460,8 @@ static void r128_project_clipped_vertices( struct vertex_buffer *VB ) VB->ClipMask + VB->CopyStart ); } -static struct r128_fast_tab r128FastTab[0x80]; +static struct r128_fast_tab r128FastTab[R128_MAX_SETUPFUNC]; -/* Initialize the table of fast path support functions */ void r128DDFastPathInit( void ) { r128_render_init_clip_elt(); @@ -481,25 +472,26 @@ void r128DDFastPathInit( void ) r128_init_fastpath_TEX0( &r128FastTab[R128_TEX0_BIT] ); r128_init_fastpath_RGBA_TEX0( &r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT] ); r128_init_fastpath_TEX0_TEX1( &r128FastTab[R128_TEX0_BIT|R128_TEX1_BIT] ); - r128_init_fastpath_RGBA_TEX0_TEX1( &r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT| - R128_TEX1_BIT] ); + r128_init_fastpath_RGBA_TEX0_TEX1( &r128FastTab[(R128_RGBA_BIT | + R128_TEX0_BIT | + R128_TEX1_BIT)] ); } #define VALID_SETUP (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT) void r128DDFastPath( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; + GLcontext *ctx = VB->ctx; GLenum prim = ctx->CVA.elt_mode; - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - struct r128_fast_tab *tab = &r128FastTab[r128ctx->SetupIndex & VALID_SETUP]; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct r128_fast_tab *tab = &r128FastTab[rmesa->SetupIndex & VALID_SETUP]; GLuint do_cliptest = 1; gl_prepare_arrays_cva( VB ); /* still need this */ if ( ( gl_reduce_prim[prim] == GL_TRIANGLES ) && ( VB->Count < (R128_BUFFER_SIZE / (10 * sizeof(GLuint))) ) && - ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL| + ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL | MAT_FLAG_PERSPECTIVE) ) ) { r128DDEltPath( VB ); @@ -514,14 +506,14 @@ void r128DDFastPath( struct vertex_buffer *VB ) tab->build_vertices( VB, do_cliptest ); /* object->clip space */ - if ( r128ctx->new_state ) + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); if ( VB->ClipOrMask ) { if ( !VB->ClipAndMask ) { render_func *clip = r128_render_tab_clip_elt; - r128ctx->interp = tab->interp; + rmesa->interp = tab->interp; clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h index 8f51fe74c..8a7cef504 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h @@ -33,12 +33,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* FIXME: These routines were copied from the i810 driver, and were only - slightly modified for the Rage 128. They still need to be optmizied - and cleaned up. Also, support for USE_RHW2 needs to be added. */ - /* The first part of setup is applied to all vertices, clipped or - * unclipped. This data w!ill be used for clipping, and then all + * unclipped. This data will be used for clipping, and then all * vertices with a zero clipmask will be projected to device space. * * This could be split into several loops, but - it seems that the @@ -46,106 +42,107 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * performance factor, and that multiple loops mean multiple cache * misses.... */ -static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest) +static void TAG(r128_setup_full)( struct vertex_buffer *VB, + GLuint do_cliptest ) { - GLcontext *ctx = VB->ctx; - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); - const GLfloat *m = ctx->ModelProjectMatrix.m; - GLuint start = VB->CopyStart; - GLuint count = VB->Count; + GLcontext *ctx = VB->ctx; + r128VertexBufferPtr rvb = R128_DRIVER_DATA(VB); + const GLfloat *m = ctx->ModelProjectMatrix.m; + GLuint start = VB->CopyStart; + GLuint count = VB->Count; - gl_xform_points3_v16_general(r128VB->verts[start].f, + gl_xform_points3_v16_general( rvb->verts[start].f, m, VB->ObjPtr->start, VB->ObjPtr->stride, - count - start); - - if (do_cliptest) { - VB->ClipAndMask = ~0; - VB->ClipOrMask = 0; - gl_cliptest_points4_v16(r128VB->verts[start].f, - r128VB->verts[count].f, - &(VB->ClipOrMask), - &(VB->ClipAndMask), - VB->ClipMask + start); - } - - /* These branches are all resolved at compile time. Hopefully all - * the pointers are valid addresses even when not enabled. - */ - if (TYPE) { - GLubyte *color = VB->ColorPtr->start; - GLfloat *tex0_data = VB->TexCoordPtr[0]->start; - GLfloat *tex1_data = VB->TexCoordPtr[1]->start; - - GLuint color_stride = VB->ColorPtr->stride; - GLuint tex0_stride = VB->TexCoordPtr[0]->stride; - GLuint tex1_stride = VB->TexCoordPtr[1]->stride; - - GLfloat *f = r128VB->verts[start].f; - GLfloat *end = f + (16 * (count - start)); - - while (f != end) { - if (TYPE & R128_RGBA_BIT) { + count - start ); + + if ( do_cliptest ) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16( rvb->verts[start].f, + rvb->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), + VB->ClipMask + start ); + } + + /* These branches are all resolved at compile time. Hopefully all + * the pointers are valid addresses even when not enabled. + */ + if ( TYPE ) { + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = rvb->verts[start].f; + GLfloat *end = f + (16 * (count - start)); + + while ( f != end ) { + if ( TYPE & R128_RGBA_BIT ) { #if defined(USE_X86_ASM) - /* GTH: I'd like to get some accurate timing data on the - * bswap instruction, but it gives a nice speedup anyway. - */ - __asm__ ("movl (%%edx),%%eax \n" + /* GH: I'd like to get some accurate timing data on the + * bswap instruction, but it gives a nice speedup anyway. + */ + __asm__ ( "movl (%%edx),%%eax \n" "bswap %%eax \n" "rorl $8,%%eax \n" "movl %%eax,16(%%edi) \n" : : "d" (color), "D" (f) - : "%eax"); + : "%eax" ); #else - GLubyte *col = color; - GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; - b[CLIP_UBYTE_B] = col[2]; - b[CLIP_UBYTE_G] = col[1]; - b[CLIP_UBYTE_R] = col[0]; - b[CLIP_UBYTE_A] = col[3]; + GLubyte *col = color; + GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; + b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_R] = col[0]; + b[CLIP_UBYTE_A] = col[3]; #endif - } - if (TYPE & R128_TEX0_BIT) { + } + if ( TYPE & R128_TEX0_BIT ) { #if defined (USE_X86_ASM) - __asm__ ("movl (%%ecx), %%eax \n" + __asm__ ( "movl (%%ecx), %%eax \n" "movl %%eax, 24(%%edi) \n" "movl 4(%%ecx), %%eax \n" "movl %%eax, 28(%%edi)" : : "c" (tex0_data), "D" (f) - : "%eax"); + : "%eax" ); #else - *(unsigned int *)(f+CLIP_S0) = *(unsigned int *)tex0_data; - *(unsigned int *)(f+CLIP_T0) = *(unsigned int *)(tex0_data+1); + *(GLuint *)(f+CLIP_S0) = *(GLuint *)tex0_data; + *(GLuint *)(f+CLIP_T0) = *(GLuint *)(tex0_data+1); #endif - } - if (TYPE & R128_TEX1_BIT) { - /* Hits a second cache line. - */ + } + if ( TYPE & R128_TEX1_BIT ) { + /* Hits a second cache line. + */ #if defined (USE_X86_ASM) - __asm__ ("movl (%%esi), %%eax \n" + __asm__ ( "movl (%%esi), %%eax \n" "movl %%eax, 32(%%edi) \n" "movl 4(%%esi), %%eax \n" "movl %%eax, 36(%%edi)" : : "S" (tex1_data), "D" (f) - : "%eax"); + : "%eax" ); #else - *(unsigned int *)(f+CLIP_S1) = *(unsigned int *)tex1_data; - *(unsigned int *)(f+CLIP_T1) = *(unsigned int *)(tex1_data+1); + *(GLuint *)(f+CLIP_S1) = *(GLuint *)tex1_data; + *(GLuint *)(f+CLIP_T1) = *(GLuint *)(tex1_data+1); #endif - } - if (TYPE & R128_RGBA_BIT) color += color_stride; - if (TYPE & R128_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); - if (TYPE & R128_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); - f += 16; - } - } - - r128VB->clipped_elements.count = start; - r128VB->last_vert = count; + } + if ( TYPE & R128_RGBA_BIT ) color += color_stride; + if ( TYPE & R128_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & R128_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); + f += 16; + } + } + + rvb->clipped_elements.count = start; + rvb->last_vert = count; } @@ -153,39 +150,39 @@ static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest) * routine into the header. Less code and better chance of doing some * of this stuff in assembly. */ -static void TAG(r128_interp_vert)(GLfloat t, - GLfloat *O, - const GLfloat *I, - const GLfloat *J) +static void TAG(r128_interp_vert)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) { - O[0] = LINTERP(t, I[0], J[0]); - O[1] = LINTERP(t, I[1], J[1]); - O[2] = LINTERP(t, I[2], J[2]); - O[3] = LINTERP(t, I[3], J[3]); - - if (TYPE & R128_RGBA_BIT) { - INTERP_RGBA(t, - ((GLubyte *)&(O[4])), - ((GLubyte *)&(I[4])), - ((GLubyte *)&(J[4]))); - } - - if (TYPE & R128_TEX0_BIT) { - O[6] = LINTERP(t, I[6], J[6]); - O[7] = LINTERP(t, I[7], J[7]); - } - - if (TYPE & R128_TEX1_BIT) { - O[8] = LINTERP(t, I[8], J[8]); - O[9] = LINTERP(t, I[9], J[9]); - } + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & R128_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); + } + + if ( TYPE & R128_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); + } + + if ( TYPE & R128_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); + } } static void TAG(r128_init_fastpath)(struct r128_fast_tab *tab) { - tab->build_vertices = TAG(r128_setup_full); - tab->interp = TAG(r128_interp_vert); + tab->build_vertices = TAG(r128_setup_full); + tab->interp = TAG(r128_interp_vert); } #undef TYPE diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c index 2ae7fe4b5..713edcd32 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c @@ -38,7 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mem.h" -#define R128_TIMEOUT 2000000 +#define R128_TIMEOUT 2048 /* ============================================================= @@ -47,9 +47,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Get a new VB from the pool of vertex buffers in AGP space. */ -drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) +drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ) { - int fd = r128ctx->r128Screen->driScreen->fd; + int fd = rmesa->r128Screen->driScreen->fd; int index = 0; int size = 0; drmDMAReq dma; @@ -57,7 +57,7 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) int to = 0; int ret; - dma.context = r128ctx->hHWContext; + dma.context = rmesa->hHWContext; dma.send_count = 0; dma.send_list = NULL; dma.send_sizes = NULL; @@ -68,15 +68,15 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) dma.request_sizes = &size; dma.granted_count = 0; - while ( !buf && ( to++ < r128ctx->CCEtimeout ) ) { + while ( !buf && ( to++ < R128_TIMEOUT ) ) { ret = drmDMA( fd, &dma ); if ( ret == 0 ) { - buf = &r128ctx->r128Screen->buffers->list[index]; + buf = &rmesa->r128Screen->buffers->list[index]; buf->used = 0; #if ENABLE_PERF_BOXES /* Bump the performance counter */ - r128ctx->c_vertexBuffers++; + rmesa->c_vertexBuffers++; #endif return buf; } @@ -84,6 +84,7 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) if ( !buf ) { drmR128EngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "Error: Could not get new VB... exiting\n" ); exit( -1 ); } @@ -91,57 +92,50 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) return buf; } -void r128FlushVerticesLocked( r128ContextPtr r128ctx ) +void r128FlushVerticesLocked( r128ContextPtr rmesa ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - drmBufPtr buffer = r128ctx->vert_buf; - int count = r128ctx->num_verts; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->vert_buf; + int count = rmesa->num_verts; int prim = R128_TRIANGLES; - int fd = r128ctx->driScreen->fd; + int fd = rmesa->driScreen->fd; int i; - if ( 0 ) - fprintf( stderr, "%s: buf=%d count=%d\n", - __FUNCTION__, buffer ? buffer->idx : -1, count ); + rmesa->num_verts = 0; + rmesa->vert_buf = NULL; - r128ctx->num_verts = 0; - r128ctx->vert_buf = NULL; - - if ( !buffer ) { + if ( !buffer ) return; - } - if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128EmitHwStateLocked( r128ctx ); - } + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) + r128EmitHwStateLocked( rmesa ); - if ( !nbox ) { + if ( !nbox ) count = 0; - } - if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; - } - if ( !count || !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + + if ( !count || !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); } else { - for (i = 0 ; i < nbox ; ) { + for ( i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; int discard = 0; - r128ctx->sarea->nbox = nr - i; - for ( ; i < nr ; i++) { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++ ) { *b++ = pbox[i]; } @@ -151,12 +145,12 @@ void r128FlushVerticesLocked( r128ContextPtr r128ctx ) discard = 1; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, discard ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } @@ -165,60 +159,53 @@ void r128FlushVerticesLocked( r128ContextPtr r128ctx ) * Indexed vertex buffer handling */ -void r128GetEltBufLocked( r128ContextPtr r128ctx ) +void r128GetEltBufLocked( r128ContextPtr rmesa ) { - r128ctx->elt_buf = r128GetBufferLocked( r128ctx ); + rmesa->elt_buf = r128GetBufferLocked( rmesa ); } -void r128FireEltsLocked( r128ContextPtr r128ctx, +void r128FireEltsLocked( r128ContextPtr rmesa, GLuint start, GLuint end, GLuint discard ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - drmBufPtr buffer = r128ctx->elt_buf; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->elt_buf; int prim = R128_TRIANGLES; - int fd = r128ctx->driScreen->fd; + int fd = rmesa->driScreen->fd; int i; - if ( 0 ) - fprintf( stderr, "%s: start=%d end=%d discard=%d\n", - __FUNCTION__, start, end, discard ); - - if ( !buffer ) { + if ( !buffer ) return; - } - if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128EmitHwStateLocked( r128ctx ); - } + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) + r128EmitHwStateLocked( rmesa ); - if ( !nbox ) { + if ( !nbox ) end = start; - } - if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; - } - if ( start == end || !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + + if ( start == end || !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128FlushIndices( fd, prim, buffer->idx, start, end, discard ); } else { - for (i = 0 ; i < nbox ; ) { + for ( i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; int d = 0; - r128ctx->sarea->nbox = nr - i; - for ( ; i < nr ; i++) { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++ ) { *b++ = pbox[i]; } @@ -228,44 +215,40 @@ void r128FireEltsLocked( r128ContextPtr r128ctx, d = discard; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128FlushIndices( fd, prim, buffer->idx, start, end, discard ); } } if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { - drmR128WaitForIdleCCE( r128ctx->driFd ); + drmR128WaitForIdleCCE( rmesa->driFd ); } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128FlushEltsLocked( r128ContextPtr r128ctx ) +void r128FlushEltsLocked( r128ContextPtr rmesa ) { - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FireEltsLocked( r128ctx, - ((GLuint)r128ctx->first_elt - - (GLuint)r128ctx->elt_buf->address), - ((GLuint)r128ctx->next_elt - - (GLuint)r128ctx->elt_buf->address), + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), 0 ); - ALIGN_NEXT_ELT( r128ctx ); - r128ctx->first_elt = r128ctx->next_elt; + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; } } -void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ) +void r128ReleaseBufLocked( r128ContextPtr rmesa, drmBufPtr buffer ) { - int fd = r128ctx->driScreen->fd; - - if ( 0 ) - fprintf( stderr, "%s: buffer=%p\n", - __FUNCTION__, buffer ); + int fd = rmesa->driScreen->fd; - if ( !buffer ) { + if ( !buffer ) return; - } + drmR128FlushVertexBuffer( fd, R128_TRIANGLES, buffer->idx, 0, 1 ); } @@ -273,28 +256,28 @@ void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ) /* Allocate some space in the current vertex buffer. If the current * buffer is full, flush it and grab another one. */ -CARD32 *r128AllocVertices( r128ContextPtr r128ctx, int count ) +CARD32 *r128AllocVertices( r128ContextPtr rmesa, int count ) { - return r128AllocVerticesInline( r128ctx, count ); + return r128AllocVerticesInline( rmesa, count ); } - /* ================================================================ * Texture uploads */ -void r128FireBlitLocked( r128ContextPtr r128ctx, drmBufPtr buffer, +void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ) { GLint ret; - ret = drmR128TextureBlit( r128ctx->driFd, buffer->idx, + ret = drmR128TextureBlit( rmesa->driFd, buffer->idx, offset, pitch, format, x, y, width, height ); if ( ret ) { + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "drmR128TextureBlit: return = %d\n", ret ); exit( 1 ); } @@ -317,16 +300,16 @@ static void delay( void ) { * long as we want for a frame to complete. If it never does, then * the card has locked. */ -static int r128WaitForFrameCompletion( r128ContextPtr r128ctx ) +static int r128WaitForFrameCompletion( r128ContextPtr rmesa ) { - unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + unsigned char *R128MMIO = rmesa->r128Screen->mmio.map; CARD32 frame; int i; int wait = 0; while ( 1 ) { frame = INREG( R128_LAST_FRAME_REG ); - if ( r128ctx->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) { + if ( rmesa->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) { break; } @@ -340,68 +323,129 @@ static int r128WaitForFrameCompletion( r128ContextPtr r128ctx ) return wait; } -/* Copy the back color buffer to the front color buffer */ -void r128SwapBuffers( r128ContextPtr r128ctx ) +/* Copy the back color buffer to the front color buffer. + */ +void r128SwapBuffers( r128ContextPtr rmesa ) { - GLint nbox = r128ctx->numClipRects; + GLint nbox = rmesa->numClipRects; GLint i; GLint ret; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "\n********************************\n" ); fprintf( stderr, "\n%s( %p )\n\n", - __FUNCTION__, r128ctx->glCtx ); + __FUNCTION__, rmesa->glCtx ); fflush( stderr ); } - /* Flush any outstanding vertex buffers */ - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - LOCK_HARDWARE( r128ctx ); + LOCK_HARDWARE( rmesa ); /* Throttle the frame rate -- only allow one pending swap buffers * request at a time. */ - if ( !r128WaitForFrameCompletion( r128ctx ) ) { - r128ctx->hardwareWentIdle = 1; + if ( !r128WaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; } else { - r128ctx->hardwareWentIdle = 0; + rmesa->hardwareWentIdle = 0; } for ( i = 0 ; i < nbox ; ) { GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , nbox ); - XF86DRIClipRectPtr box = r128ctx->pClipRects; - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; GLint n = 0; for ( ; i < nr ; i++ ) { *b++ = *(XF86DRIClipRectRec *)&box[i]; n++; } - r128ctx->sarea->nbox = n; + rmesa->sarea->nbox = n; - ret = drmR128SwapBuffers( r128ctx->driFd ); + ret = drmR128SwapBuffers( rmesa->driFd ); if ( ret ) { + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); exit( 1 ); } } if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { - drmR128WaitForIdleCCE( r128ctx->driFd ); + drmR128WaitForIdleCCE( rmesa->driFd ); } - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_MASKS | - R128_UPLOAD_CLIPRECTS); + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS | + R128_UPLOAD_CLIPRECTS); #if ENABLE_PERF_BOXES /* Log the performance counters if necessary */ - r128PerformanceCounters( r128ctx ); + r128PerformanceCounters( rmesa ); +#endif +} + +void r128PageFlip( r128ContextPtr rmesa ) +{ + GLint ret; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p ): page=%d\n\n", + __FUNCTION__, rmesa->glCtx, rmesa->currentPage ); + } + + FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !r128WaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; + } else { + rmesa->hardwareWentIdle = 0; + } + + /* The kernel will have been initialized to perform page flipping + * on a swapbuffers ioctl. + */ + ret = drmR128SwapBuffers( rmesa->driFd ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); + exit( 1 ); + } + + if ( rmesa->currentPage == 0 ) { + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; + rmesa->currentPage = 1; + } else { + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; + rmesa->currentPage = 0; + } + + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; + + /* FIXME: Do we need this anymore? */ + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS | + R128_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + r128PerformanceCounters( rmesa ); #endif } @@ -413,8 +457,8 @@ void r128SwapBuffers( r128ContextPtr r128ctx ) static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; GLuint flags = 0; GLint i; GLint ret; @@ -423,13 +467,13 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, fprintf( stderr, "%s:\n", __FUNCTION__ ); } - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); /* Update and emit any new state. We need to do this here to catch * changes to the masks. * FIXME: Just update the masks? */ - if ( r128ctx->new_state ) + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); if ( mask & DD_FRONT_LEFT_BIT ) { @@ -454,24 +498,23 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } #endif - if ( !flags ) { + if ( !flags ) return mask; - } /* Flip top to bottom */ cx += dPriv->x; cy = dPriv->y + dPriv->h - cy - ch; - LOCK_HARDWARE( r128ctx ); + LOCK_HARDWARE( rmesa ); - if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128EmitHwStateLocked( r128ctx ); + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128EmitHwStateLocked( rmesa ); } - for ( i = 0 ; i < r128ctx->numClipRects ; ) { - GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , r128ctx->numClipRects ); - XF86DRIClipRectPtr box = r128ctx->pClipRects; - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + for ( i = 0 ; i < rmesa->numClipRects ; ) { + GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , rmesa->numClipRects ); + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; GLint n = 0; if ( !all ) { @@ -502,30 +545,31 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } } - r128ctx->sarea->nbox = n; + rmesa->sarea->nbox = n; if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) { fprintf( stderr, "drmR128Clear: flag 0x%x color %x depth %x nbox %d\n", flags, - (GLuint)r128ctx->ClearColor, - (GLuint)r128ctx->ClearDepth, - r128ctx->sarea->nbox ); + (GLuint)rmesa->ClearColor, + (GLuint)rmesa->ClearDepth, + rmesa->sarea->nbox ); } - ret = drmR128Clear( r128ctx->driFd, flags, + ret = drmR128Clear( rmesa->driFd, flags, cx, cy, cw, ch, - r128ctx->ClearColor, r128ctx->ClearDepth ); + rmesa->ClearColor, rmesa->ClearDepth ); if ( ret ) { + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "drmR128Clear: return = %d\n", ret ); exit( 1 ); } } - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; return mask; } @@ -535,29 +579,29 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, * Depth spans, pixels */ -void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, +void r128WriteDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y, const GLdepth depth[], const GLubyte mask[] ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); @@ -566,44 +610,44 @@ void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[], const GLdepth depth[], const GLubyte mask[] ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); @@ -612,42 +656,42 @@ void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, +void r128ReadDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128ReadDepthSpan( fd, n, x, y ); @@ -656,42 +700,42 @@ void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128ReadDepthSpan( fd, n, x, y ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128ReadDepthPixels( fd, n, x, y ); @@ -700,60 +744,35 @@ void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128ReadDepthPixels( fd, n, x, y ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -/* ================================================================ - * Deprecated function... - */ -void r128SubmitPacketLocked( r128ContextPtr r128ctx, - CARD32 *buf, GLuint count ) -{ - CARD32 *b; - int c = count; - int fd = r128ctx->r128Screen->driScreen->fd; - int to = 0; - int ret; - - do { - b = buf + (count - c); - ret = drmR128SubmitPacket( fd, b, &c, 0 ); - } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) ); - - if ( ret < 0 ) { - drmR128EngineReset( fd ); - fprintf( stderr, "Error: Could not submit packet... exiting\n" ); - exit( -1 ); - } -} - - - -void r128WaitForIdleLocked( r128ContextPtr r128ctx ) +void r128WaitForIdleLocked( r128ContextPtr rmesa ) { - int fd = r128ctx->r128Screen->driScreen->fd; + int fd = rmesa->r128Screen->driScreen->fd; int to = 0; int ret; do { ret = drmR128WaitForIdleCCE( fd ); - } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) ); + } while ( ( ret == -EBUSY ) && ( to++ < R128_TIMEOUT ) ); if ( ret < 0 ) { drmR128EngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "Error: Rage 128 timed out... exiting\n" ); exit( -1 ); } @@ -762,5 +781,5 @@ void r128WaitForIdleLocked( r128ContextPtr r128ctx ) void r128DDInitIoctlFuncs( GLcontext *ctx ) { - ctx->Driver.Clear = r128DDClear; + ctx->Driver.Clear = r128DDClear; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h index 43b77659b..aafd0859b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h @@ -44,174 +44,128 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86drm.h" #include "xf86drmR128.h" -#define R128_DEFAULT_TOTAL_CCE_TIMEOUT 1000000 /* usecs */ - #define R128_BUFFER_MAX_DWORDS (R128_BUFFER_SIZE / sizeof(CARD32)) -#define FLUSH_BATCH( r128ctx ) \ -do { \ - if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) \ - fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ - if ( r128ctx->vert_buf ) { \ - r128FlushVertices( r128ctx ); \ - } else if ( r128ctx->next_elt != r128ctx->first_elt ) { \ - r128FlushElts( r128ctx ); \ - } \ -} while (0) - -#define r128FlushVertices( r128ctx ) \ -do { \ - LOCK_HARDWARE( r128ctx ); \ - r128FlushVerticesLocked( r128ctx ); \ - UNLOCK_HARDWARE( r128ctx ); \ -} while (0) - - -extern drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ); -extern void r128FlushVerticesLocked( r128ContextPtr r128ctx ); +extern drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ); +extern void r128FlushVerticesLocked( r128ContextPtr rmesa ); - -#define r128FlushElts( r128ctx ) \ -do { \ - LOCK_HARDWARE( r128ctx ); \ - r128FlushEltsLocked( r128ctx ); \ - UNLOCK_HARDWARE( r128ctx ); \ -} while (0) - -extern void r128GetEltBufLocked( r128ContextPtr r128ctx ); -extern void r128FlushEltsLocked( r128ContextPtr r128ctx ); -extern void r128FireEltsLocked( r128ContextPtr r128ctx, +extern void r128GetEltBufLocked( r128ContextPtr rmesa ); +extern void r128FlushEltsLocked( r128ContextPtr rmesa ); +extern void r128FireEltsLocked( r128ContextPtr rmesa, GLuint start, GLuint end, GLuint discard ); -extern void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ); - - -/* 64-bit align the next element address, and then make room for the - * next indexed prim packet header. - */ -#define ALIGN_NEXT_ELT( r128ctx ) \ -do { \ - r128ctx->next_elt = (GLushort *) \ - (((GLuint)r128ctx->next_elt + 7) & ~0x7); \ - r128ctx->next_elt = (GLushort *) \ - ((GLubyte *)r128ctx->next_elt + R128_INDEX_PRIM_OFFSET); \ -} while (0) - +extern void r128ReleaseBufLocked( r128ContextPtr rmesa, drmBufPtr buffer ); /* Make this available as both a regular and an inline function. */ -extern CARD32 *r128AllocVertices( r128ContextPtr r128ctx, int count ); +extern CARD32 *r128AllocVertices( r128ContextPtr rmesa, int count ); -static __inline CARD32 *r128AllocVerticesInline( r128ContextPtr r128ctx, +static __inline CARD32 *r128AllocVerticesInline( r128ContextPtr rmesa, int count ) { - int bytes = count * r128ctx->vertsize * sizeof(CARD32); - CARD32 *head; + int bytes = count * rmesa->vertsize * sizeof(CARD32); + CARD32 *head; - if ( !r128ctx->vert_buf ) { - LOCK_HARDWARE( r128ctx ); + if ( !rmesa->vert_buf ) { + LOCK_HARDWARE( rmesa ); - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FlushEltsLocked( r128ctx ); - } + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FlushEltsLocked( rmesa ); + } - r128ctx->vert_buf = r128GetBufferLocked( r128ctx ); + rmesa->vert_buf = r128GetBufferLocked( rmesa ); - UNLOCK_HARDWARE( r128ctx ); - } else if ( r128ctx->vert_buf->used + bytes > r128ctx->vert_buf->total ) { - LOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); + } else if ( rmesa->vert_buf->used + bytes > rmesa->vert_buf->total ) { + LOCK_HARDWARE( rmesa ); - r128FlushVerticesLocked( r128ctx ); - r128ctx->vert_buf = r128GetBufferLocked( r128ctx ); + r128FlushVerticesLocked( rmesa ); + rmesa->vert_buf = r128GetBufferLocked( rmesa ); - UNLOCK_HARDWARE( r128ctx ); - } + UNLOCK_HARDWARE( rmesa ); + } - head = (CARD32 *)((char *)r128ctx->vert_buf->address + - r128ctx->vert_buf->used); + head = (CARD32 *)((char *)rmesa->vert_buf->address + + rmesa->vert_buf->used); - r128ctx->num_verts += count; - r128ctx->vert_buf->used += bytes; - return head; + rmesa->num_verts += count; + rmesa->vert_buf->used += bytes; + return head; } - -extern void r128FireBlitLocked( r128ContextPtr r128ctx, drmBufPtr buffer, +extern void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ); - -extern void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, +extern void r128WriteDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y, const GLdepth depth[], const GLubyte mask[] ); -extern void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +extern void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[], const GLdepth depth[], const GLubyte mask[] ); -extern void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, +extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y ); -extern void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ); +extern void r128SwapBuffers( r128ContextPtr rmesa ); +extern void r128PageFlip( r128ContextPtr rmesa ); -extern void r128SwapBuffers( r128ContextPtr r128ctx ); - - -#define r128WaitForIdle( r128ctx ) \ -do { \ - LOCK_HARDWARE( r128ctx ); \ - r128WaitForIdleLocked( r128ctx ); \ - UNLOCK_HARDWARE( r128ctx ); \ -} while (0) - -extern void r128WaitForIdleLocked( r128ContextPtr r128ctx ); +extern void r128WaitForIdleLocked( r128ContextPtr rmesa ); extern void r128DDInitIoctlFuncs( GLcontext *ctx ); - /* ================================================================ - * Deprecated functions: + * Helper macros: */ -typedef union { - float f; - int i; -} floatTOint; - -/* Insert an integer value into the CCE ring buffer. */ -#define R128CCE(v) \ -do { \ - r128ctx->CCEbuf[r128ctx->CCEcount] = (v); \ - r128ctx->CCEcount++; \ +#define FLUSH_BATCH( rmesa ) \ +do { \ + if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) \ + fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ + if ( rmesa->vert_buf ) { \ + r128FlushVertices( rmesa ); \ + } else if ( rmesa->next_elt != rmesa->first_elt ) { \ + r128FlushElts( rmesa ); \ + } \ } while (0) -/* Insert an floating point value into the CCE ring buffer. */ -#define R128CCEF(v) \ -do { \ - floatTOint fTi; \ - fTi.f = (v); \ - r128ctx->CCEbuf[r128ctx->CCEcount] = fTi.i; \ - r128ctx->CCEcount++; \ +/* 64-bit align the next element address, and then make room for the + * next indexed prim packet header. + */ +#define ALIGN_NEXT_ELT( rmesa ) \ +do { \ + rmesa->next_elt = (GLushort *) \ + (((GLuint)rmesa->next_elt + 7) & ~0x7); \ + rmesa->next_elt = (GLushort *) \ + ((GLubyte *)rmesa->next_elt + R128_INDEX_PRIM_OFFSET); \ } while (0) -/* Insert a type-[0123] packet header into the ring buffer */ -#define R128CCE0(p,r,n) R128CCE((p) | ((n) << 16) | ((r) >> 2)) -#define R128CCE1(p,r1,r2) R128CCE((p) | (((r2) >> 2) << 11) | ((r1) >> 2)) -#define R128CCE2(p) R128CCE((p)) -#define R128CCE3(p,n) R128CCE((p) | ((n) << 16)) +#define r128FlushVertices( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + r128FlushVerticesLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) -#define R128CCE_SUBMIT_PACKET() \ -do { \ - r128SubmitPacketLocked( r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount ); \ - r128ctx->CCEcount = 0; \ +#define r128FlushElts( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + r128FlushEltsLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ } while (0) -extern void r128SubmitPacketLocked( r128ContextPtr r128ctx, - CARD32 *buf, GLuint count ); +#define r128WaitForIdle( rmesa ) \ + do { \ + LOCK_HARDWARE( rmesa ); \ + r128WaitForIdleLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ + } while (0) #endif #endif /* __R128_IOCTL_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c index 6c9331c74..8fdef0d95 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c @@ -38,7 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #if DEBUG_LOCKING char *prevLockFile = NULL; -int prevLockLine = 0; +int prevLockLine = 0; #endif @@ -50,15 +50,15 @@ int prevLockLine = 0; * the hardware lock when it changes the window state, this routine will * automatically be called after such a change. */ -void r128GetLock( r128ContextPtr r128ctx, GLuint flags ) +void r128GetLock( r128ContextPtr rmesa, GLuint flags ) { - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; - __DRIscreenPrivate *sPriv = r128ctx->driScreen; - R128SAREAPriv *sarea = r128ctx->sarea; + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + __DRIscreenPrivate *sPriv = rmesa->driScreen; + R128SAREAPrivPtr sarea = rmesa->sarea; int stamp = dPriv->lastStamp; int i; - drmGetLock( r128ctx->driFd, r128ctx->hHWContext, flags ); + drmGetLock( rmesa->driFd, rmesa->hHWContext, flags ); /* The window might have moved, so we might need to get new clip * rects. @@ -68,26 +68,26 @@ void r128GetLock( r128ContextPtr r128ctx, GLuint flags ) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - XMESA_VALIDATE_DRAWABLE_INFO( r128ctx->display, sPriv, dPriv ); + XMESA_VALIDATE_DRAWABLE_INFO( rmesa->display, sPriv, dPriv ); if ( stamp != dPriv->lastStamp ) { - r128ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; - r128ctx->SetupDone = 0; + rmesa->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; + rmesa->SetupDone = 0; } - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS; - r128ctx->numClipRects = dPriv->numClipRects; - r128ctx->pClipRects = dPriv->pClipRects; + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = dPriv->pClipRects; - if ( sarea->ctxOwner != r128ctx->hHWContext ) { - sarea->ctxOwner = r128ctx->hHWContext; - r128ctx->dirty = R128_UPLOAD_ALL; + if ( sarea->ctxOwner != rmesa->hHWContext ) { + sarea->ctxOwner = rmesa->hHWContext; + rmesa->dirty = R128_UPLOAD_ALL; } - for ( i = 0 ; i < r128ctx->lastTexHeap ; i++ ) { - if ( sarea->texAge[i] != r128ctx->lastTexAge[i] ) { - r128AgeTextures( r128ctx, i ); + for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != rmesa->lastTexAge[i] ) { + r128AgeTextures( rmesa, i ); } } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h index 7ae5b639a..2da57bb44 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h @@ -33,40 +33,42 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#ifndef _R128_LOCK_H_ -#define _R128_LOCK_H_ +#ifndef __R128_LOCK_H__ +#define __R128_LOCK_H__ #ifdef GLX_DIRECT_RENDERING -extern void r128GetLock( r128ContextPtr r128ctx, GLuint flags ); +extern void r128GetLock( r128ContextPtr rmesa, GLuint flags ); +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 -/* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */ -#ifdef DEBUG_LOCKING +#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) +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 @@ -84,26 +86,26 @@ extern int prevLockLine; /* Lock the hardware and validate our state. */ -#define LOCK_HARDWARE( r128ctx ) \ +#define LOCK_HARDWARE( rmesa ) \ do { \ char __ret = 0; \ DEBUG_CHECK_LOCK(); \ - DRM_CAS( r128ctx->driHwLock, r128ctx->hHWContext, \ - (DRM_LOCK_HELD | r128ctx->hHWContext), __ret ); \ + DRM_CAS( rmesa->driHwLock, rmesa->hHWContext, \ + (DRM_LOCK_HELD | rmesa->hHWContext), __ret ); \ if ( __ret ) \ - r128GetLock( r128ctx, 0 ); \ + r128GetLock( rmesa, 0 ); \ DEBUG_LOCK(); \ } while (0) /* Unlock the hardware. */ -#define UNLOCK_HARDWARE( r128ctx ) \ +#define UNLOCK_HARDWARE( rmesa ) \ do { \ - DRM_UNLOCK( r128ctx->driFd, \ - r128ctx->driHwLock, \ - r128ctx->hHWContext ); \ + DRM_UNLOCK( rmesa->driFd, \ + rmesa->driHwLock, \ + rmesa->hHWContext ); \ DEBUG_RESET(); \ } while (0) #endif -#endif /* _R128_LOCK_H_ */ +#endif /* __R128_LOCK_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c index 4b17e5636..e42fa4075 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c @@ -41,7 +41,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "fog.h" static struct gl_pipeline_stage r128_fast_stage = { - "R128 Fast Path", + "r128 Fast Path", (PIPE_OP_VERT_XFORM | PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1 | @@ -66,10 +66,10 @@ static struct gl_pipeline_stage r128_fast_stage = { */ GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct gl_pipeline *pipe = &ctx->CVA.pre; - if ( r128ctx->RenderIndex == 0 && + if ( rmesa->RenderIndex == 0 && (ctx->Enabled & ILLEGAL_ENABLES) == 0 && (ctx->Array.Flags & (VERT_OBJ_234 | VERT_TEX0_4 | @@ -81,15 +81,15 @@ GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ) pipe->new_inputs = ctx->RenderFlags & VERT_DATA; pipe->ops = pipe->stages[0]->ops; - r128ctx->useFastPath = GL_TRUE; + rmesa->OnFastPath = GL_TRUE; return GL_TRUE; } - if ( r128ctx->useFastPath ) { - r128ctx->useFastPath = GL_FALSE; + if ( rmesa->OnFastPath ) { + rmesa->OnFastPath = GL_FALSE; - ctx->CVA.VB->ClipOrMask = 0; - ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; ctx->Array.NewArrayState |= ctx->Array.Summary; } @@ -123,7 +123,6 @@ static void r128DDCheckRasterSetup( GLcontext *ctx, } -/* Register the pipeline with our stages included */ GLuint r128DDRegisterPipelineStages( struct gl_pipeline_stage *out, const struct gl_pipeline_stage *in, GLuint nr ) diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h index 84c667240..5e40bd6f6 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h @@ -28,13 +28,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_PIPELINE_H_ -#define _R128_PIPELINE_H_ +#ifndef __R128_PIPELINE_H__ +#define __R128_PIPELINE_H__ + +#ifdef GLX_DIRECT_RENDERING extern GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ); extern GLuint r128DDRegisterPipelineStages( struct gl_pipeline_stage *out, @@ -47,4 +49,5 @@ extern void r128DDFastPath( struct vertex_buffer *VB ); extern void r128DDEltPathInit( void ); extern void r128DDEltPath( struct vertex_buffer *VB ); -#endif /* _R128_PIPELINE_H_ */ +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c index 139e7fbc3..029ccd4ca 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -41,7 +41,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_vb.h" #include "r128_pipeline.h" -#include <sys/mman.h> +#include "mem.h" #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... @@ -57,208 +57,157 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #endif -/* Create the device specific screen private data struct */ -r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) +/* Create the device specific screen private data struct. + */ +r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ) { - r128ScreenPtr r128Screen; - R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; - int cpp; - - /* Allocate the private area */ - r128Screen = (r128ScreenPtr)Xmalloc(sizeof(*r128Screen)); - if (!r128Screen) return NULL; - - /* This is first since which regions we map depends on whether or - not we are using a PCI card */ - r128Screen->IsPCI = r128DRIPriv->IsPCI; - - r128Screen->mmioRgn.handle = r128DRIPriv->registerHandle; - r128Screen->mmioRgn.size = r128DRIPriv->registerSize; - if (drmMap(sPriv->fd, - r128Screen->mmioRgn.handle, - r128Screen->mmioRgn.size, - (drmAddressPtr)&r128Screen->mmio)) { - Xfree(r128Screen); - return NULL; - } - - if (!r128Screen->IsPCI) { - r128Screen->ringRgn.handle = r128DRIPriv->ringHandle; - r128Screen->ringRgn.size = r128DRIPriv->ringMapSize; - if (drmMap(sPriv->fd, - r128Screen->ringRgn.handle, - r128Screen->ringRgn.size, - (drmAddressPtr)&r128Screen->ring)) { - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - - r128Screen->ringReadRgn.handle = r128DRIPriv->ringReadPtrHandle; - r128Screen->ringReadRgn.size = r128DRIPriv->ringReadMapSize; - if (drmMap(sPriv->fd, - r128Screen->ringReadRgn.handle, - r128Screen->ringReadRgn.size, - (drmAddressPtr)&r128Screen->ringReadPtr)) { - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - - r128Screen->bufRgn.handle = r128DRIPriv->bufHandle; - r128Screen->bufRgn.size = r128DRIPriv->bufMapSize; - if (drmMap(sPriv->fd, - r128Screen->bufRgn.handle, - r128Screen->bufRgn.size, - (drmAddressPtr)&r128Screen->buf)) { - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - r128Screen->bufOffset = r128DRIPriv->bufOffset; - - r128Screen->agpTexRgn.handle = r128DRIPriv->agpTexHandle; - r128Screen->agpTexRgn.size = r128DRIPriv->agpTexMapSize; - if (drmMap(sPriv->fd, - r128Screen->agpTexRgn.handle, - r128Screen->agpTexRgn.size, - (drmAddressPtr)&r128Screen->agpTex)) { - drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - r128Screen->agpTexOffset = r128DRIPriv->agpTexOffset; - - if (!(r128Screen->buffers = drmMapBufs(sPriv->fd))) { - drmUnmap((drmAddress)r128Screen->agpTex, - r128Screen->agpTexRgn.size); - drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - } - - /* Allow both AGP and PCI cards to use vertex buffers. PCI cards use - * the ring walker method, ie. the vertex buffer data is actually part - * of the command stream. - */ - r128Screen->bufMapSize = r128DRIPriv->bufMapSize; - - r128Screen->deviceID = r128DRIPriv->deviceID; - - r128Screen->depth = r128DRIPriv->depth; - r128Screen->bpp = r128DRIPriv->bpp; - r128Screen->pixel_code = (r128Screen->bpp != 16 ? - r128Screen->bpp : - r128Screen->depth); - - cpp = r128Screen->bpp / 8; - - r128Screen->fb = sPriv->pFB; - r128Screen->fbOffset = sPriv->fbOrigin; - r128Screen->fbStride = sPriv->fbStride; - r128Screen->fbSize = sPriv->fbSize; - - r128Screen->frontOffset = r128DRIPriv->frontOffset; - r128Screen->frontPitch = r128DRIPriv->frontPitch; - r128Screen->backOffset = r128DRIPriv->backOffset; - r128Screen->backPitch = r128DRIPriv->backPitch; - r128Screen->depthOffset = r128DRIPriv->depthOffset; - r128Screen->depthPitch = r128DRIPriv->depthPitch; - r128Screen->spanOffset = r128DRIPriv->spanOffset; - - r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureOffset; - r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize; - r128Screen->log2TexGran[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran; - - if (r128Screen->IsPCI) { - r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0; - r128Screen->texSize[R128_AGP_TEX_HEAP] = 0; - r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = 0; - r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS-1; - } else { - r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0; - r128Screen->texSize[R128_AGP_TEX_HEAP] = - r128DRIPriv->agpTexMapSize; - r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = - r128DRIPriv->log2AGPTexGran; - r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS; - } - - r128Screen->AGPMode = r128DRIPriv->AGPMode; - - r128Screen->CCEMode = r128DRIPriv->CCEMode; - r128Screen->CCEFifoSize = r128DRIPriv->CCEFifoSize; - - r128Screen->ringEntries = r128DRIPriv->ringSize/sizeof(CARD32); - if (!r128Screen->IsPCI) { - r128Screen->ringStartPtr = (int *)r128Screen->ring; - r128Screen->ringEndPtr = (int *)(r128Screen->ring - + r128DRIPriv->ringSize); - } - - r128Screen->MMIOFifoSlots = 0; - r128Screen->CCEFifoSlots = 0; - - r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN; - - r128Screen->driScreen = sPriv; - - switch ( r128DRIPriv->deviceID ) { - case PCI_CHIP_RAGE128RE: - case PCI_CHIP_RAGE128RF: - case PCI_CHIP_RAGE128RK: - case PCI_CHIP_RAGE128RL: - r128Screen->chipset = R128_CARD_TYPE_R128; - break; - case PCI_CHIP_RAGE128PF: - r128Screen->chipset = R128_CARD_TYPE_R128_PRO; - break; - case PCI_CHIP_RAGE128LE: - case PCI_CHIP_RAGE128LF: - r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY; - break; - default: - r128Screen->chipset = R128_CARD_TYPE_R128; - break; - } - - r128DDFastPathInit(); - r128DDEltPathInit(); - r128DDTriangleFuncsInit(); - r128DDSetupInit(); - - return r128Screen; + r128ScreenPtr r128Screen; + R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; + + /* Check the DRI version */ + { + int major, minor, patch; + if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { + if ( major != 3 || minor != 0 || patch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if ( sPriv->ddxMajor != 4 || + sPriv->ddxMinor != 0 || + sPriv->ddxPatch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if ( sPriv->drmMajor != 2 || + sPriv->drmMinor != 1 || + sPriv->drmPatch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Allocate the private area */ + r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) ); + if ( !r128Screen ) return NULL; + + /* This is first since which regions we map depends on whether or + * not we are using a PCI card. + */ + r128Screen->IsPCI = r128DRIPriv->IsPCI; + + r128Screen->mmio.handle = r128DRIPriv->registerHandle; + r128Screen->mmio.size = r128DRIPriv->registerSize; + if ( drmMap( sPriv->fd, + r128Screen->mmio.handle, + r128Screen->mmio.size, + (drmAddressPtr)&r128Screen->mmio.map ) ) { + FREE( r128Screen ); + return NULL; + } + + r128Screen->buffers = drmMapBufs( sPriv->fd ); + if ( !r128Screen->buffers ) { + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); + FREE( r128Screen ); + return NULL; + } + + if ( !r128Screen->IsPCI ) { + r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle; + r128Screen->agpTextures.size = r128DRIPriv->agpTexMapSize; + if ( drmMap( sPriv->fd, + r128Screen->agpTextures.handle, + r128Screen->agpTextures.size, + (drmAddressPtr)&r128Screen->agpTextures.map ) ) { + drmUnmapBufs( r128Screen->buffers ); + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); + FREE( r128Screen ); + return NULL; + } + } + + switch ( r128DRIPriv->deviceID ) { + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RK: + case PCI_CHIP_RAGE128RL: + r128Screen->chipset = R128_CARD_TYPE_R128; + break; + case PCI_CHIP_RAGE128PF: + r128Screen->chipset = R128_CARD_TYPE_R128_PRO; + break; + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128LF: + r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY; + break; + default: + r128Screen->chipset = R128_CARD_TYPE_R128; + break; + } + + r128Screen->cpp = r128DRIPriv->bpp / 8; + r128Screen->AGPMode = r128DRIPriv->AGPMode; + + r128Screen->frontOffset = r128DRIPriv->frontOffset; + r128Screen->frontPitch = r128DRIPriv->frontPitch; + r128Screen->backOffset = r128DRIPriv->backOffset; + r128Screen->backPitch = r128DRIPriv->backPitch; + r128Screen->depthOffset = r128DRIPriv->depthOffset; + r128Screen->depthPitch = r128DRIPriv->depthPitch; + r128Screen->spanOffset = r128DRIPriv->spanOffset; + + r128Screen->texOffset[R128_CARD_HEAP] = r128DRIPriv->textureOffset; + r128Screen->texSize[R128_CARD_HEAP] = r128DRIPriv->textureSize; + r128Screen->logTexGranularity[R128_CARD_HEAP] = r128DRIPriv->log2TexGran; + + if ( r128Screen->IsPCI ) { + r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1; + r128Screen->texOffset[R128_AGP_HEAP] = 0; + r128Screen->texSize[R128_AGP_HEAP] = 0; + r128Screen->logTexGranularity[R128_AGP_HEAP] = 0; + } else { + r128Screen->numTexHeaps = R128_NR_TEX_HEAPS; + r128Screen->texOffset[R128_AGP_HEAP] = + r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET; + r128Screen->texSize[R128_AGP_HEAP] = r128DRIPriv->agpTexMapSize; + r128Screen->logTexGranularity[R128_AGP_HEAP] = + r128DRIPriv->log2AGPTexGran; + } + + r128Screen->driScreen = sPriv; + + r128DDSetupInit(); + r128DDTriangleFuncsInit(); + r128DDFastPathInit(); + r128DDEltPathInit(); + + return r128Screen; } -/* Destroy the device specific screen private data struct */ -void r128DestroyScreen(__DRIscreenPrivate *sPriv) +/* Destroy the device specific screen private data struct. + */ +void r128DestroyScreen( __DRIscreenPrivate *sPriv ) { - r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; - - if (!r128Screen->IsPCI) { - drmUnmapBufs(r128Screen->buffers); + r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; - drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size); - drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - } - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + if ( !r128Screen->IsPCI ) { + drmUnmap( (drmAddress)r128Screen->agpTextures.map, + r128Screen->agpTextures.size ); + } + drmUnmapBufs( r128Screen->buffers ); + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); - Xfree(r128Screen); - sPriv->private = NULL; + FREE( r128Screen ); + sPriv->private = NULL; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h index 4fd6b7ac7..b3e6259e8 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -28,98 +28,58 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_SCREEN_H_ -#define _R128_SCREEN_H_ +#ifndef __R128_SCREEN_H__ +#define __R128_SCREEN_H__ #ifdef GLX_DIRECT_RENDERING #include "r128_sarea.h" typedef struct { - drmHandle handle; /* Handle to the DRM region */ - drmSize size; /* Size of the DRM region */ + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + unsigned char *map; /* Mapping of the DRM region */ } r128RegionRec, *r128RegionPtr; typedef struct { - /* MMIO register data */ - r128RegionRec mmioRgn; - unsigned char *mmio; - - /* CCE ring buffer data */ - r128RegionRec ringRgn; - unsigned char *ring; - - /* CCE ring read pointer data */ - r128RegionRec ringReadRgn; - - /* CCE vertex/indirect buffer data */ - r128RegionRec bufRgn; - unsigned char *buf; - int bufOffset; - int bufMapSize; - drmBufMapPtr buffers; - - /* CCE AGP Texture data */ - r128RegionRec agpTexRgn; - unsigned char *agpTex; - int agpTexOffset; - - /* Frame buffer data */ - unsigned char *fb; - unsigned long fbOffset; - int fbStride; - int fbSize; - - unsigned int frontX, frontY; /* Start of front buffer */ - unsigned int frontOffset, frontPitch; - unsigned int backX, backY; /* Start of shared back buffer */ - unsigned int backOffset, backPitch; - unsigned int depthX, depthY; /* Start of shared depth buffer */ - unsigned int depthOffset, depthPitch; - unsigned int spanOffset; - - int chipset; - int IsPCI; /* Current card is a PCI card */ - int AGPMode; - - int CCEMode; /* CCE mode that server/clients use */ - int CCEFifoSize; /* Size of the CCE command FIFO */ - - /* CCE ring buffer data */ - int ringEntries; - - volatile int *ringReadPtr; /* Pointer to current read addr */ - int *ringStartPtr; /* Pointer to end of ring buffer */ - int *ringEndPtr; /* Pointer to end of ring buffer */ - - /* DRI screen private data */ - int deviceID; /* PCI device ID */ - int depth; /* Depth of display (8, 15, 16, 24) */ - int bpp; /* Bit depth of disp (8, 16, 24, 32) */ - int pixel_code; /* 8, 15, 16, 24, 32 */ + + GLint chipset; + GLint cpp; + GLint IsPCI; /* Current card is a PCI card */ + GLint AGPMode; + + GLuint frontOffset; + GLuint frontPitch; + GLuint backOffset; + GLuint backPitch; + + GLuint depthOffset; + GLuint depthPitch; + GLuint spanOffset; /* Shared texture data */ - int NRTexHeaps; - int texOffset[R128_NR_TEX_HEAPS]; - int texSize[R128_NR_TEX_HEAPS]; - int log2TexGran[R128_NR_TEX_HEAPS]; - - int MMIOFifoSlots; /* Free slots in the FIFO (64 max) */ - int CCEFifoSlots; /* Free slots in the CCE FIFO */ - - int CCEFifoAddr; /* MMIO offset to write next CCE - value (only used when CCE is - in PIO mode). */ - __DRIscreenPrivate *driScreen; + GLint numTexHeaps; + GLint texOffset[R128_NR_TEX_HEAPS]; + GLint texSize[R128_NR_TEX_HEAPS]; + GLint logTexGranularity[R128_NR_TEX_HEAPS]; + + r128RegionRec mmio; + r128RegionRec agpTextures; + + drmBufMapPtr buffers; + + __DRIscreenPrivate *driScreen; + } r128ScreenRec, *r128ScreenPtr; -r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv); -void r128DestroyScreen(__DRIscreenPrivate *sPriv); + +extern r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ); +extern void r128DestroyScreen( __DRIscreenPrivate *sPriv ); #endif -#endif /* _R128_SCREEN_H_ */ +#endif /* __R128_SCREEN_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c index c25250378..f0d7c318f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c @@ -28,9 +28,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> - * Keith Whitwell <keithw@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -47,32 +47,34 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define HAVE_HW_DEPTH_PIXELS 1 #define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ - GLuint pitch = r128scrn->fbStride; \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = rmesa->r128Screen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint pitch = r128scrn->frontPitch * r128scrn->cpp; \ GLuint height = dPriv->h; \ - char *buf = (char *)(r128scrn->fb + \ - r128ctx->drawOffset + \ - (dPriv->x * r128scrn->bpp/8) + \ + char *buf = (char *)(sPriv->pFB + \ + rmesa->drawOffset + \ + (dPriv->x * r128scrn->cpp) + \ (dPriv->y * pitch)); \ - char *read_buf = (char *)(r128scrn->fb + \ - r128ctx->readOffset + \ - (dPriv->x * r128scrn->bpp/8) + \ + char *read_buf = (char *)(sPriv->pFB + \ + rmesa->readOffset + \ + (dPriv->x * r128scrn->cpp) + \ (dPriv->y * pitch)); \ GLushort p; \ (void) read_buf; (void) buf; (void) p #define LOCAL_DEPTH_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = rmesa->r128Screen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ GLuint height = dPriv->h; \ - (void) height + (void) r128scrn; (void) sPriv; (void) height #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS -#define INIT_MONO_PIXEL( p ) \ - p = r128ctx->Color +#define INIT_MONO_PIXEL( p ) p = rmesa->Color #define CLIPPIXEL( _x, _y ) \ ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) @@ -88,18 +90,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \ } -#define Y_FLIP( _y ) (height - _y - 1) +#define Y_FLIP( _y ) (height - _y - 1) #define HW_LOCK() \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - FLUSH_BATCH( r128ctx ); \ - LOCK_HARDWARE( r128ctx ); \ - r128WaitForIdleLocked( r128ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + FLUSH_BATCH( rmesa ); \ + LOCK_HARDWARE( rmesa ); \ + r128WaitForIdleLocked( rmesa ); #define HW_CLIPLOOP() \ do { \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ int _nc = dPriv->numClipRects; \ \ while ( _nc-- ) { \ @@ -113,7 +115,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. } while (0) #define HW_UNLOCK() \ - UNLOCK_HARDWARE( r128ctx ) \ + UNLOCK_HARDWARE( rmesa ) @@ -122,23 +124,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 16 bit, RGB565 color spanline and pixel functions - */ \ + */ #define WRITE_RGBA( _x, _y, r, g, b, a ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \ (((int)g & 0xfc) << 3) | \ (((int)b & 0xf8) >> 3)) #define WRITE_PIXEL( _x, _y, p ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = p + *(GLushort *)(buf + _x*2 + _y*pitch) = p #define READ_RGBA( rgba, _x, _y ) \ - do { \ - GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = 0xff; \ - } while (0) + do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 8) & 0xf8; \ + rgba[1] = (p >> 3) & 0xfc; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 0xff; \ + if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \ + if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \ + if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \ + } while (0) #define TAG(x) r128##x##_RGB565 #include "spantmp.h" @@ -175,9 +180,8 @@ do { \ /* 16-bit depth buffer functions */ - #define WRITE_DEPTH_SPAN() \ - r128WriteDepthSpanLocked( r128ctx, n, \ + r128WriteDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y, \ depth, mask ); @@ -192,20 +196,19 @@ do { \ for ( i = 0 ; i < n ; i++ ) { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ - r128WriteDepthPixelsLocked( r128ctx, n, ox, oy, depth, mask ); \ + r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \ } while (0) #define READ_DEPTH_SPAN() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLushort *buf = (GLushort *)((GLubyte *)r128scrn->fb + \ + GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i; \ \ - r128ReadDepthSpanLocked( r128ctx, n, \ + r128ReadDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < n ; i++ ) { \ depth[i] = buf[i]; \ @@ -214,8 +217,7 @@ do { \ #define READ_DEPTH_PIXELS() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLushort *buf = (GLushort *)((GLubyte *)r128scrn->fb + \ + GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i, remaining = n; \ \ @@ -236,8 +238,8 @@ do { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ \ - r128ReadDepthPixelsLocked( r128ctx, count, ox, oy ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < count ; i++ ) { \ depth[i] = buf[i]; \ @@ -256,7 +258,7 @@ do { \ /* 24-bit depth, 8-bit stencil buffer functions */ #define WRITE_DEPTH_SPAN() \ - r128WriteDepthSpanLocked( r128ctx, n, \ + r128WriteDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y, \ depth, mask ); @@ -271,20 +273,19 @@ do { \ for ( i = 0 ; i < n ; i++ ) { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ - r128WriteDepthPixelsLocked( r128ctx, n, ox, oy, depth, mask ); \ + r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \ } while (0) #define READ_DEPTH_SPAN() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i; \ \ - r128ReadDepthSpanLocked( r128ctx, n, \ + r128ReadDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < n ; i++ ) { \ depth[i] = buf[i] & 0x00ffffff; \ @@ -293,8 +294,7 @@ do { \ #define READ_DEPTH_PIXELS() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i, remaining = n; \ \ @@ -315,8 +315,8 @@ do { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ \ - r128ReadDepthPixelsLocked( r128ctx, count, ox, oy ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < count ; i++ ) { \ depth[i] = buf[i] & 0x00ffffff; \ @@ -344,10 +344,10 @@ do { \ void r128DDInitSpanFuncs( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - switch ( r128ctx->r128Screen->bpp ) { - case 16: + switch ( rmesa->r128Screen->cpp ) { + case 2: ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565; ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565; ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565; @@ -357,7 +357,7 @@ void r128DDInitSpanFuncs( GLcontext *ctx ) ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565; break; - case 32: + case 4: ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888; ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888; ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888; @@ -371,7 +371,7 @@ void r128DDInitSpanFuncs( GLcontext *ctx ) break; } - switch ( r128ctx->DepthSize ) { + switch ( rmesa->glCtx->Visual->DepthBits ) { case 16: ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.h b/xc/lib/GL/mesa/src/drv/r128/r128_span.h index 486445d31..fefa5bd67 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h @@ -28,17 +28,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_SPAN_H_ -#define _R128_SPAN_H_ +#ifndef __R128_SPAN_H__ +#define __R128_SPAN_H__ #ifdef GLX_DIRECT_RENDERING -extern void r128DDInitSpanFuncs(GLcontext *ctx); +extern void r128DDInitSpanFuncs( GLcontext *ctx ); #endif -#endif /* _R128_SPAN_H_ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c index 10a955af7..18a6f25e3 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -29,6 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * Keith Whitwell <keithw@valinux.com> * */ @@ -51,9 +52,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. static void r128UpdateAlphaMode( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 a = r128ctx->setup.misc_3d_state_cntl_reg; - CARD32 t = r128ctx->setup.tex_cntl_c; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 a = rmesa->setup.misc_3d_state_cntl_reg; + CARD32 t = rmesa->setup.tex_cntl_c; if ( ctx->Color.AlphaEnabled ) { GLubyte ref = ctx->Color.AlphaRef; @@ -63,7 +64,6 @@ static void r128UpdateAlphaMode( GLcontext *ctx ) switch ( ctx->Color.AlphaFunc ) { case GL_NEVER: a |= R128_ALPHA_TEST_NEVER; - ref = 0; break; case GL_LESS: a |= R128_ALPHA_TEST_LESS; @@ -159,48 +159,48 @@ static void r128UpdateAlphaMode( GLcontext *ctx ) t &= ~R128_ALPHA_ENABLE; } - if ( r128ctx->setup.misc_3d_state_cntl_reg != a ) { - r128ctx->setup.misc_3d_state_cntl_reg = a; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( rmesa->setup.misc_3d_state_cntl_reg != a ) { + rmesa->setup.misc_3d_state_cntl_reg = a; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } } static void r128DDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } static void r128DDBlendEquation( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } static void r128DDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } static void r128DDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } @@ -210,9 +210,9 @@ static void r128DDBlendFuncSeparate( GLcontext *ctx, static void r128UpdateZMode( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 z = r128ctx->setup.z_sten_cntl_c; - CARD32 t = r128ctx->setup.tex_cntl_c; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 z = rmesa->setup.z_sten_cntl_c; + CARD32 t = rmesa->setup.tex_cntl_c; if ( ctx->Depth.Test ) { z &= ~R128_Z_TEST_MASK; @@ -255,45 +255,45 @@ static void r128UpdateZMode( GLcontext *ctx ) t &= ~R128_Z_WRITE_ENABLE; } - if ( r128ctx->setup.z_sten_cntl_c != z ) { - r128ctx->setup.z_sten_cntl_c = z; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.z_sten_cntl_c != z ) { + rmesa->setup.z_sten_cntl_c = z; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } } static void r128DDDepthFunc( GLcontext *ctx, GLenum func ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_DEPTH; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; } static void r128DDDepthMask( GLcontext *ctx, GLboolean flag ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_DEPTH; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; } static void r128DDClearDepth( GLcontext *ctx, GLclampd d ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - switch ( r128ctx->DepthSize ) { - case 16: - r128ctx->ClearDepth = d * 0x0000ffff; + switch ( rmesa->setup.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK ) { + case R128_Z_PIX_WIDTH_16: + rmesa->ClearDepth = d * 0x0000ffff; break; - case 24: - r128ctx->ClearDepth = d * 0x00ffffff; + case R128_Z_PIX_WIDTH_24: + rmesa->ClearDepth = d * 0x00ffffff; break; - case 32: - r128ctx->ClearDepth = d * 0xffffffff; + case R128_Z_PIX_WIDTH_32: + rmesa->ClearDepth = d * 0xffffffff; break; } } @@ -305,8 +305,8 @@ static void r128DDClearDepth( GLcontext *ctx, GLclampd d ) static void r128UpdateFogAttrib( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 t = r128ctx->setup.tex_cntl_c; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 t = rmesa->setup.tex_cntl_c; GLubyte c[4]; CARD32 col; @@ -316,25 +316,25 @@ static void r128UpdateFogAttrib( GLcontext *ctx ) t &= ~R128_FOG_ENABLE; } - FLOAT_RGBA_TO_UBYTE_RGBA( c, ctx->Fog.Color ); - col = r128PackColor( 32, c[0], c[1], c[2], c[3] ); + FLOAT_RGB_TO_UBYTE_RGB( c, ctx->Fog.Color ); + col = r128PackColor( 4, c[0], c[1], c[2], 0 ); - if ( r128ctx->setup.fog_color_c != col ) { - r128ctx->setup.fog_color_c = col; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.fog_color_c != col ) { + rmesa->setup.fog_color_c = col; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } } static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_FOG; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_FOG; } @@ -344,14 +344,14 @@ static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) static void r128UpdateClipping( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - if ( r128ctx->driDrawable ) { - __DRIdrawablePrivate *drawable = r128ctx->driDrawable; + if ( rmesa->driDrawable ) { + __DRIdrawablePrivate *drawable = rmesa->driDrawable; int x1 = 0; int y1 = 0; - int x2 = r128ctx->driDrawable->w - 1; - int y2 = r128ctx->driDrawable->h - 1; + int x2 = drawable->w - 1; + int y2 = drawable->h - 1; if ( ctx->Scissor.Enabled ) { if ( ctx->Scissor.X > x1 ) { @@ -368,51 +368,25 @@ static void r128UpdateClipping( GLcontext *ctx ) } } - x1 += r128ctx->driDrawable->x; - y1 += r128ctx->driDrawable->y; - x2 += r128ctx->driDrawable->x; - y2 += r128ctx->driDrawable->y; - - if ( 0 ) { - fprintf( stderr, "%s: drawable %3d %3d %3d %3d\n", - __FUNCTION__, - r128ctx->driDrawable->x, - r128ctx->driDrawable->y, - r128ctx->driDrawable->w, - r128ctx->driDrawable->h ); - fprintf( stderr, "%s: draw buf %3d %3d %3d %3d\n", - __FUNCTION__, - ctx->DrawBuffer->Xmin, - ctx->DrawBuffer->Ymin, - ctx->DrawBuffer->Xmax, - ctx->DrawBuffer->Ymax ); - fprintf( stderr, "%s: scissor %3d %3d %3d %3d\n", - __FUNCTION__, - ctx->Scissor.X, - ctx->Scissor.Y, - ctx->Scissor.Width, - ctx->Scissor.Height ); - fprintf( stderr, "%s: final %3d %3d %3d %3d\n", - __FUNCTION__, x1, y1, x2, y2 ); - fprintf( stderr, "\n" ); - } + x1 += drawable->x; + y1 += drawable->y; + x2 += drawable->x; + y2 += drawable->y; - r128ctx->setup.sc_top_left_c = ((x1 << 0) | - (y1 << 16)); - r128ctx->setup.sc_bottom_right_c = ((x2 << 0) | - (y2 << 16)); + rmesa->setup.sc_top_left_c = ((y1 << 16) | x1); + rmesa->setup.sc_bottom_right_c = ((y2 << 16) | x2); - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } } static void r128DDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CLIP; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CLIP; } @@ -422,8 +396,8 @@ static void r128DDScissor( GLcontext *ctx, static void r128UpdateCull( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 f = r128ctx->setup.pm4_vc_fpu_setup; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 f = rmesa->setup.pm4_vc_fpu_setup; f &= ~R128_FRONT_DIR_MASK; @@ -453,26 +427,26 @@ static void r128UpdateCull( GLcontext *ctx ) } } - if ( r128ctx->setup.pm4_vc_fpu_setup != f ) { - r128ctx->setup.pm4_vc_fpu_setup = f; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP; + if ( rmesa->setup.pm4_vc_fpu_setup != f ) { + rmesa->setup.pm4_vc_fpu_setup = f; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP; } } static void r128DDCullFace( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CULL; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; } static void r128DDFrontFace( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CULL; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; } @@ -482,17 +456,17 @@ static void r128DDFrontFace( GLcontext *ctx, GLenum mode ) static void r128UpdateMasks( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - GLuint mask = r128PackColor( r128ctx->r128Screen->bpp, + GLuint mask = r128PackColor( rmesa->r128Screen->cpp, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP] ); - if ( r128ctx->setup.plane_3d_mask_c != mask ) { - r128ctx->setup.plane_3d_mask_c = mask; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( rmesa->setup.plane_3d_mask_c != mask ) { + rmesa->setup.plane_3d_mask_c = mask; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } } @@ -500,10 +474,10 @@ static GLboolean r128DDColorMask( GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_MASKS; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_MASKS; return GL_TRUE; } @@ -517,48 +491,33 @@ static GLboolean r128DDColorMask( GLcontext *ctx, * sense to break them out of the core texture state update routines. */ -static void r128UpdateRenderAttrib( GLcontext *ctx ) -{ - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 t = r128ctx->setup.tex_cntl_c; - CARD32 bias = r128ctx->lod_bias & 0xff;; - - t &= ~R128_LOD_BIAS_MASK; - t |= (bias << R128_LOD_BIAS_SHIFT); - - if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { - t |= R128_SPEC_LIGHT_ENABLE; - } else { - t &= ~R128_SPEC_LIGHT_ENABLE; - } - - if ( ctx->Color.DitherFlag ) { - t |= R128_DITHER_ENABLE; - } else { - t &= ~R128_DITHER_ENABLE; - } - - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; - } -} - static void r128DDLightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_RENDER; + CARD32 t = rmesa->setup.tex_cntl_c; + + FLUSH_BATCH( rmesa ); + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + t |= R128_SPEC_LIGHT_ENABLE; + } else { + t &= ~R128_SPEC_LIGHT_ENABLE; + } + + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } } } static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 s = r128ctx->setup.pm4_vc_fpu_setup; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 s = rmesa->setup.pm4_vc_fpu_setup; s &= ~R128_FPU_COLOR_MASK; @@ -573,12 +532,12 @@ static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) return; } - if ( r128ctx->setup.pm4_vc_fpu_setup != s ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.pm4_vc_fpu_setup = s; + if ( rmesa->setup.pm4_vc_fpu_setup != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.pm4_vc_fpu_setup = s; - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_SETUP; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_SETUP; } } @@ -589,14 +548,14 @@ static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) void r128UpdateWindow( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int x = r128ctx->driDrawable->x; - int y = r128ctx->driDrawable->y; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int x = rmesa->driDrawable->x; + int y = rmesa->driDrawable->y; - r128ctx->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | - (x << R128_WINDOW_X_SHIFT)); + rmesa->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | + (x << R128_WINDOW_X_SHIFT)); - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW; } @@ -607,73 +566,65 @@ void r128UpdateWindow( GLcontext *ctx ) static void r128DDClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128ctx->ClearColor = r128PackColor( r128ctx->r128Screen->bpp, - r, g, b, a ); + rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp, + r, g, b, a ); } static void r128DDColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128ctx->Color = r128PackColor( r128ctx->r128Screen->bpp, - r, g, b, a ); + rmesa->Color = r128PackColor( rmesa->r128Screen->cpp, + r, g, b, a ); } static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode ) { if ( ctx->Color.ColorLogicOpEnabled ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); if ( opcode == GL_COPY ) { - r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; + rmesa->Fallback &= ~R128_FALLBACK_LOGICOP; } else { - r128ctx->Fallback |= R128_FALLBACK_LOGICOP; + rmesa->Fallback |= R128_FALLBACK_LOGICOP; } } } static GLboolean r128DDSetDrawBuffer( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); int found = GL_TRUE; - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - if ( r128ctx->DrawBuffer != mode ) { - r128ctx->DrawBuffer = mode; - r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; + if ( rmesa->DrawBuffer != mode ) { + rmesa->DrawBuffer = mode; + rmesa->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; switch ( mode ) { case GL_FRONT_LEFT: - r128ctx->drawX = r128ctx->r128Screen->frontX; - r128ctx->drawY = r128ctx->r128Screen->frontY; - r128ctx->drawOffset = r128ctx->r128Screen->frontOffset; - r128ctx->drawPitch = r128ctx->r128Screen->frontPitch; - r128ctx->readX = r128ctx->r128Screen->frontX; - r128ctx->readY = r128ctx->r128Screen->frontY; + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; break; case GL_BACK_LEFT: - r128ctx->drawX = r128ctx->r128Screen->backX; - r128ctx->drawY = r128ctx->r128Screen->backY; - r128ctx->drawOffset = r128ctx->r128Screen->backOffset; - r128ctx->drawPitch = r128ctx->r128Screen->backPitch; - r128ctx->readX = r128ctx->r128Screen->backX; - r128ctx->readY = r128ctx->r128Screen->backY; + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; break; default: - r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER; + rmesa->Fallback |= R128_FALLBACK_DRAW_BUFFER; found = GL_FALSE; break; } - r128ctx->setup.dst_pitch_offset_c = (((r128ctx->drawPitch/8) << 21) | - (r128ctx->drawOffset >> 5)); - r128ctx->new_state |= R128_NEW_WINDOW; + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; } return found; @@ -683,25 +634,21 @@ static void r128DDSetReadBuffer( GLcontext *ctx, GLframebuffer *colorBuffer, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER; + rmesa->Fallback &= ~R128_FALLBACK_READ_BUFFER; switch ( mode ) { case GL_FRONT_LEFT: - r128ctx->readOffset = r128ctx->r128Screen->frontOffset; - r128ctx->readPitch = r128ctx->r128Screen->frontPitch; - r128ctx->readX = r128ctx->r128Screen->frontX; - r128ctx->readY = r128ctx->r128Screen->frontY; + rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->readPitch = rmesa->r128Screen->frontPitch; break; case GL_BACK_LEFT: - r128ctx->readOffset = r128ctx->r128Screen->backOffset; - r128ctx->readPitch = r128ctx->r128Screen->backPitch; - r128ctx->readX = r128ctx->r128Screen->backX; - r128ctx->readY = r128ctx->r128Screen->backY; + rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->readPitch = rmesa->r128Screen->backPitch; break; default: - r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER; + rmesa->Fallback |= R128_FALLBACK_READ_BUFFER; break; } } @@ -713,28 +660,27 @@ static void r128DDSetReadBuffer( GLcontext *ctx, static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLuint *stipple = (GLuint *)mask; - FLUSH_BATCH( r128ctx ); - ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + FLUSH_BATCH( rmesa ); - r128ctx->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; + rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; if ( ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON ) { - r128ctx->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; } else { - r128ctx->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; } - LOCK_HARDWARE( r128ctx ); + LOCK_HARDWARE( rmesa ); - drmR128PolygonStipple( r128ctx->driFd, stipple ); + drmR128PolygonStipple( rmesa->driFd, stipple ); - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } @@ -744,7 +690,7 @@ static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %s = %s )\n", @@ -755,68 +701,81 @@ static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) switch ( cap ) { case GL_ALPHA_TEST: case GL_BLEND: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; break; case GL_CULL_FACE: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CULL; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; break; case GL_DEPTH_TEST: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_DEPTH; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; break; case GL_DITHER: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_RENDER; + do { + CARD32 t = rmesa->setup.tex_cntl_c; + FLUSH_BATCH( rmesa ); + + if ( ctx->Color.DitherFlag ) { + t |= R128_DITHER_ENABLE; + } else { + t &= ~R128_DITHER_ENABLE; + } + + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } + } while (0); break; case GL_FOG: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_FOG; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_FOG; break; case GL_INDEX_LOGIC_OP: case GL_COLOR_LOGIC_OP: - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); if ( state && ctx->Color.LogicOp != GL_COPY ) { - r128ctx->Fallback |= R128_FALLBACK_LOGICOP; + rmesa->Fallback |= R128_FALLBACK_LOGICOP; } else { - r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; + rmesa->Fallback &= ~R128_FALLBACK_LOGICOP; } break; case GL_SCISSOR_TEST: - FLUSH_BATCH( r128ctx ); - r128ctx->scissor = state; - r128ctx->new_state |= R128_NEW_CLIP; + FLUSH_BATCH( rmesa ); + rmesa->scissor = state; + rmesa->new_state |= R128_NEW_CLIP; break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_TEXTURE; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_TEXTURE; break; case GL_POLYGON_STIPPLE: if ( (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && ctx->PB->primitive == GL_POLYGON ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; + FLUSH_BATCH( rmesa ); + rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; if ( state ) { - r128ctx->setup.dp_gui_master_cntl_c |= + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; } else { - r128ctx->setup.dp_gui_master_cntl_c |= + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; } - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } break; @@ -860,51 +819,65 @@ static void r128DDPrintDirty( const char *msg, GLuint state ) * Blits of any type should always upload the context and masks after * they are done. */ -void r128EmitHwStateLocked( r128ContextPtr r128ctx ) +void r128EmitHwStateLocked( r128ContextPtr rmesa ) { - R128SAREAPrivPtr sarea = r128ctx->sarea; - r128_context_regs_t *regs = &(r128ctx->setup); - r128TexObjPtr t0 = r128ctx->CurrentTexObj[0]; - r128TexObjPtr t1 = r128ctx->CurrentTexObj[1]; + R128SAREAPrivPtr sarea = rmesa->sarea; + r128_context_regs_t *regs = &(rmesa->setup); + r128TexObjPtr t0 = rmesa->CurrentTexObj[0]; + r128TexObjPtr t1 = rmesa->CurrentTexObj[1]; if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) { - r128DDPrintDirty( "r128EmitHwStateLocked", r128ctx->dirty ); + r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty ); } - if ( r128ctx->dirty & R128_UPLOAD_TEX0IMAGES ) { - if ( t0 ) r128UploadTexImages( r128ctx, t0 ); - r128ctx->dirty &= ~R128_UPLOAD_TEX0IMAGES; + if ( rmesa->dirty & R128_UPLOAD_TEX0IMAGES ) { + if ( t0 ) r128UploadTexImages( rmesa, t0 ); + rmesa->dirty &= ~R128_UPLOAD_TEX0IMAGES; } - if ( r128ctx->dirty & R128_UPLOAD_TEX1IMAGES ) { - if ( t1 ) r128UploadTexImages( r128ctx, t1 ); - r128ctx->dirty &= ~R128_UPLOAD_TEX1IMAGES; + if ( rmesa->dirty & R128_UPLOAD_TEX1IMAGES ) { + if ( t1 ) r128UploadTexImages( rmesa, t1 ); + rmesa->dirty &= ~R128_UPLOAD_TEX1IMAGES; } - if ( r128ctx->dirty & (R128_UPLOAD_CONTEXT | - R128_UPLOAD_SETUP | - R128_UPLOAD_MASKS | - R128_UPLOAD_WINDOW | - R128_UPLOAD_CORE | - R128_UPLOAD_TEX0) ) { + if ( rmesa->dirty & (R128_UPLOAD_CONTEXT | + R128_UPLOAD_SETUP | + R128_UPLOAD_MASKS | + R128_UPLOAD_WINDOW | + R128_UPLOAD_CORE | + R128_UPLOAD_TEX0) ) { memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); } - if ( (r128ctx->dirty & R128_UPLOAD_TEX0) && t0 ) { - memcpy( &sarea->TexState[0], &t0->setup, sizeof(sarea->TexState[0]) ); + if ( (rmesa->dirty & R128_UPLOAD_TEX0) && t0 ) { + r128_texture_regs_t *tex = &sarea->TexState[0]; + + tex->tex_cntl = t0->setup.tex_cntl; + tex->tex_combine_cntl = rmesa->tex_combine[0]; + tex->tex_size_pitch = t0->setup.tex_size_pitch; + memcpy( &tex->tex_offset[0], &t0->setup.tex_offset[0], + sizeof(tex->tex_offset ) ); + tex->tex_border_color = t0->setup.tex_border_color; } - if ( (r128ctx->dirty & R128_UPLOAD_TEX1) && t1 ) { - memcpy( &sarea->TexState[1], &t1->setup, sizeof(sarea->TexState[1]) ); + if ( (rmesa->dirty & R128_UPLOAD_TEX1) && t1 ) { + r128_texture_regs_t *tex = &sarea->TexState[1]; + + tex->tex_cntl = t1->setup.tex_cntl; + tex->tex_combine_cntl = rmesa->tex_combine[1]; + tex->tex_size_pitch = t1->setup.tex_size_pitch; + memcpy( &tex->tex_offset[0], &t1->setup.tex_offset[0], + sizeof(tex->tex_offset ) ); + tex->tex_border_color = t1->setup.tex_border_color; } - sarea->vertsize = r128ctx->vertsize; - sarea->vc_format = r128ctx->vc_format; + sarea->vertsize = rmesa->vertsize; + sarea->vc_format = rmesa->vc_format; /* Turn off the texture cache flushing */ - r128ctx->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; - sarea->dirty |= r128ctx->dirty; - r128ctx->dirty &= R128_UPLOAD_CLIPRECTS; + sarea->dirty |= rmesa->dirty; + rmesa->dirty &= R128_UPLOAD_CLIPRECTS; } static void r128DDPrintState( const char *msg, GLuint flags ) @@ -924,17 +897,16 @@ static void r128DDPrintState( const char *msg, GLuint flags ) (flags & R128_NEW_WINDOW) ? "window, " : "" ); } -/* Update the hardware state */ void r128DDUpdateHWState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int new_state = r128ctx->new_state; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int new_state = rmesa->new_state; if ( new_state ) { - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - r128ctx->new_state = 0; + rmesa->new_state = 0; if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) r128DDPrintState( "r128UpdateHwState", new_state ); @@ -959,9 +931,6 @@ void r128DDUpdateHWState( GLcontext *ctx ) if ( new_state & R128_NEW_MASKS ) r128UpdateMasks( ctx ); - if ( new_state & R128_NEW_RENDER ) - r128UpdateRenderAttrib( ctx ); - if ( new_state & R128_NEW_WINDOW ) r128UpdateWindow( ctx ); @@ -980,8 +949,8 @@ void r128DDUpdateHWState( GLcontext *ctx ) */ static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 f = r128ctx->setup.pm4_vc_fpu_setup; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 f = rmesa->setup.pm4_vc_fpu_setup; f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; @@ -1000,14 +969,14 @@ static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) } } - if ( r128ctx->setup.pm4_vc_fpu_setup != f ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.pm4_vc_fpu_setup = f; + if ( rmesa->setup.pm4_vc_fpu_setup != f ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.pm4_vc_fpu_setup = f; /* NOTE: Only upload the setup state, everything else has been * uploaded by the usual means already. */ - r128ctx->dirty |= R128_UPLOAD_SETUP; + rmesa->dirty |= R128_UPLOAD_SETUP; } } @@ -1020,7 +989,7 @@ static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) void r128DDUpdateState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( ctx->NewState & INTERESTED ) { r128DDChooseRenderState( ctx ); @@ -1030,188 +999,182 @@ void r128DDUpdateState( GLcontext *ctx ) /* Need to do this here to detect texture fallbacks before * setting triangle functions. */ - if ( r128ctx->new_state & R128_NEW_TEXTURE ) { + if ( rmesa->new_state & R128_NEW_TEXTURE ) { r128DDUpdateHWState( ctx ); } - if ( !r128ctx->Fallback ) { + if ( !rmesa->Fallback ) { ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; - ctx->IndirectTriangles |= r128ctx->IndirectTriangles; + ctx->IndirectTriangles |= rmesa->IndirectTriangles; - ctx->Driver.PointsFunc = r128ctx->PointsFunc; - ctx->Driver.LineFunc = r128ctx->LineFunc; - ctx->Driver.TriangleFunc = r128ctx->TriangleFunc; - ctx->Driver.QuadFunc = r128ctx->QuadFunc; + ctx->Driver.PointsFunc = rmesa->PointsFunc; + ctx->Driver.LineFunc = rmesa->LineFunc; + ctx->Driver.TriangleFunc = rmesa->TriangleFunc; + ctx->Driver.QuadFunc = rmesa->QuadFunc; } } -/* Initialize the context's hardware state */ -void r128DDInitState( r128ContextPtr r128ctx ) +/* Initialize the context's hardware state. + */ +void r128DDInitState( r128ContextPtr rmesa ) { int dst_bpp, depth_bpp; - CARD32 bias; - switch ( r128ctx->r128Screen->bpp ) { - case 16: dst_bpp = R128_GMC_DST_16BPP; break; - case 32: dst_bpp = R128_GMC_DST_32BPP; break; + switch ( rmesa->r128Screen->cpp ) { + case 2: + dst_bpp = R128_GMC_DST_16BPP; + break; + case 4: + dst_bpp = R128_GMC_DST_32BPP; + break; default: - fprintf( stderr, "Error: Unsupported pixel depth %d... exiting\n", - r128ctx->r128Screen->bpp ); + fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); exit( -1 ); } - switch ( r128ctx->DepthSize ) { + rmesa->ClearColor = 0x00000000; + + switch ( rmesa->glCtx->Visual->DepthBits ) { case 16: - r128ctx->ClearDepth = 0x0000ffff; + rmesa->ClearDepth = 0x0000ffff; depth_bpp = R128_Z_PIX_WIDTH_16; - r128ctx->depth_scale = 1.0 / 65536.0; + rmesa->depth_scale = 1.0 / (GLfloat)0xffff; break; case 24: - r128ctx->ClearDepth = 0x00ffffff; + rmesa->ClearDepth = 0x00ffffff; depth_bpp = R128_Z_PIX_WIDTH_24; - r128ctx->depth_scale = 1.0 / 16777216.0; - break; - case 32: - r128ctx->ClearDepth = 0xffffffff; - depth_bpp = R128_Z_PIX_WIDTH_32; - r128ctx->depth_scale = 1.0 / 4294967296.0; + rmesa->depth_scale = 1.0 / (GLfloat)0xffffff; break; default: fprintf( stderr, "Error: Unsupported depth %d... exiting\n", - r128ctx->DepthSize ); + rmesa->glCtx->Visual->DepthBits ); exit( -1 ); } - r128ctx->ClearColor = 0x00000000; + rmesa->RenderIndex = R128_FALLBACK_BIT; + rmesa->PointsFunc = NULL; + rmesa->LineFunc = NULL; + rmesa->TriangleFunc = NULL; + rmesa->QuadFunc = NULL; - r128ctx->RenderIndex = R128_FALLBACK_BIT; - r128ctx->PointsFunc = NULL; - r128ctx->LineFunc = NULL; - r128ctx->TriangleFunc = NULL; - r128ctx->QuadFunc = NULL; + rmesa->IndirectTriangles = 0; + rmesa->Fallback = 0; - r128ctx->IndirectTriangles = 0; - r128ctx->Fallback = 0; - - if ( r128ctx->glCtx->Visual->DBflag ) { - r128ctx->DrawBuffer = GL_BACK_LEFT; - r128ctx->drawOffset = r128ctx->readOffset = - r128ctx->r128Screen->backOffset; - r128ctx->drawPitch = r128ctx->readPitch = - r128ctx->r128Screen->backPitch; + if ( rmesa->glCtx->Visual->DBflag ) { + rmesa->DrawBuffer = GL_BACK_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; } else { - r128ctx->DrawBuffer = GL_FRONT_LEFT; - r128ctx->drawOffset = r128ctx->readOffset = - r128ctx->r128Screen->frontOffset; - r128ctx->drawPitch = r128ctx->readPitch = - r128ctx->r128Screen->frontPitch; + rmesa->DrawBuffer = GL_FRONT_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; } /* Harware state: */ - r128ctx->setup.dst_pitch_offset_c = (((r128ctx->drawPitch/8) << 21) | - (r128ctx->drawOffset >> 5)); - - r128ctx->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_DST_CLIPPING | - R128_GMC_BRUSH_SOLID_COLOR | - dst_bpp | - R128_GMC_SRC_DATATYPE_COLOR | - R128_GMC_BYTE_MSB_TO_LSB | - R128_GMC_CONVERSION_TEMP_6500 | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_3D_FCN_EN | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | - R128_GMC_WR_MSK_DIS); - - r128ctx->setup.sc_top_left_c = 0x00000000; - r128ctx->setup.sc_bottom_right_c = 0x1fff1fff; - - r128ctx->setup.z_offset_c = r128ctx->r128Screen->depthOffset; - r128ctx->setup.z_pitch_c = ((r128ctx->r128Screen->depthPitch >> 3) | - R128_Z_TILE); - - r128ctx->setup.z_sten_cntl_c = (depth_bpp | - R128_Z_TEST_LESS | - R128_STENCIL_TEST_ALWAYS | - R128_STENCIL_S_FAIL_KEEP | - R128_STENCIL_ZPASS_KEEP | - R128_STENCIL_ZFAIL_KEEP); - - bias = r128ctx->lod_bias & 0xff; - r128ctx->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE | - R128_SHADE_ENABLE | - R128_DITHER_ENABLE | - R128_ALPHA_IN_TEX_COMPLETE_A | - R128_LIGHT_DIS | - R128_ALPHA_LIGHT_DIS | - R128_TEX_CACHE_FLUSH | - (bias << R128_LOD_BIAS_SHIFT)); - - r128ctx->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE | - R128_MISC_SCALE_PIX_REPLICATE | - R128_ALPHA_COMB_ADD_CLAMP | - R128_FOG_VERTEX | - R128_ALPHA_BLEND_SRC_ONE | - R128_ALPHA_BLEND_DST_ZERO | - R128_ALPHA_TEST_ALWAYS); - - r128ctx->setup.texture_clr_cmp_clr_c = 0x00000000; - r128ctx->setup.texture_clr_cmp_msk_c = 0xffffffff; - - r128ctx->setup.fog_color_c = 0x00000000; - - r128ctx->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW | - R128_BACKFACE_SOLID | - R128_FRONTFACE_SOLID | - R128_FPU_COLOR_GOURAUD | - R128_FPU_SUB_PIX_4BITS | - R128_FPU_MODE_3D | - R128_TRAP_BITS_DISABLE | - R128_XFACTOR_2 | - R128_YFACTOR_2 | - R128_FLAT_SHADE_VERTEX_OGL | - R128_FPU_ROUND_TRUNCATE | - R128_WM_SEL_8DW); - - r128ctx->setup.setup_cntl = (R128_COLOR_GOURAUD | - R128_PRIM_TYPE_TRI | - R128_TEXTURE_ST_MULT_W | - R128_STARTING_VERTEX_1 | - R128_ENDING_VERTEX_3 | - R128_SU_POLY_LINE_NOT_LAST | - R128_SUB_PIX_4BITS); - - r128ctx->setup.tex_size_pitch_c = 0x00000000; - r128ctx->setup.constant_color_c = 0x00ffffff; - - r128ctx->setup.dp_write_mask = 0xffffffff; - r128ctx->setup.sten_ref_mask_c = 0xffff0000; - r128ctx->setup.plane_3d_mask_c = 0xffffffff; - - r128ctx->setup.window_xy_offset = 0x00000000; - - r128ctx->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE | - R128_TEX_CACHE_SIZE_FULL | - R128_DITHER_INIT_RESET | - R128_SCALE_3D_TEXMAP_SHADE | - R128_SCALE_PIX_REPLICATE | - R128_ALPHA_COMB_ADD_CLAMP | - R128_FOG_VERTEX | - R128_ALPHA_BLEND_SRC_ONE | - R128_ALPHA_BLEND_DST_ZERO | - R128_ALPHA_TEST_ALWAYS | - R128_COMPOSITE_SHADOW_CMP_EQUAL | - R128_TEX_MAP_ALPHA_IN_TEXTURE | - R128_TEX_CACHE_LINE_SIZE_4QW); - - r128ctx->new_state = R128_NEW_ALL; + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + + rmesa->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_DST_CLIPPING | + R128_GMC_BRUSH_SOLID_COLOR | + dst_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_GMC_BYTE_MSB_TO_LSB | + R128_GMC_CONVERSION_TEMP_6500 | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_3D_FCN_EN | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS); + + rmesa->setup.sc_top_left_c = 0x00000000; + rmesa->setup.sc_bottom_right_c = 0x1fff1fff; + + rmesa->setup.z_offset_c = rmesa->r128Screen->depthOffset; + rmesa->setup.z_pitch_c = ((rmesa->r128Screen->depthPitch >> 3) | + R128_Z_TILE); + + rmesa->setup.z_sten_cntl_c = (depth_bpp | + R128_Z_TEST_LESS | + R128_STENCIL_TEST_ALWAYS | + R128_STENCIL_S_FAIL_KEEP | + R128_STENCIL_ZPASS_KEEP | + R128_STENCIL_ZFAIL_KEEP); + + rmesa->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE | + R128_SHADE_ENABLE | + R128_DITHER_ENABLE | + R128_ALPHA_IN_TEX_COMPLETE_A | + R128_LIGHT_DIS | + R128_ALPHA_LIGHT_DIS | + R128_TEX_CACHE_FLUSH | + (0x3f << R128_LOD_BIAS_SHIFT)); + + rmesa->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE | + R128_MISC_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_VERTEX | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS); + + rmesa->setup.texture_clr_cmp_clr_c = 0x00000000; + rmesa->setup.texture_clr_cmp_msk_c = 0xffffffff; + + rmesa->setup.fog_color_c = 0x00000000; + + rmesa->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW | + R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID | + R128_FPU_COLOR_GOURAUD | + R128_FPU_SUB_PIX_4BITS | + R128_FPU_MODE_3D | + R128_TRAP_BITS_DISABLE | + R128_XFACTOR_2 | + R128_YFACTOR_2 | + R128_FLAT_SHADE_VERTEX_OGL | + R128_FPU_ROUND_TRUNCATE | + R128_WM_SEL_8DW); + + rmesa->setup.setup_cntl = (R128_COLOR_GOURAUD | + R128_PRIM_TYPE_TRI | + R128_TEXTURE_ST_MULT_W | + R128_STARTING_VERTEX_1 | + R128_ENDING_VERTEX_3 | + R128_SU_POLY_LINE_NOT_LAST | + R128_SUB_PIX_4BITS); + + rmesa->setup.tex_size_pitch_c = 0x00000000; + rmesa->setup.constant_color_c = 0x00ffffff; + + rmesa->setup.dp_write_mask = 0xffffffff; + rmesa->setup.sten_ref_mask_c = 0xffff0000; + rmesa->setup.plane_3d_mask_c = 0xffffffff; + + rmesa->setup.window_xy_offset = 0x00000000; + + rmesa->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE | + R128_TEX_CACHE_SIZE_FULL | + R128_DITHER_INIT_RESET | + R128_SCALE_3D_TEXMAP_SHADE | + R128_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_VERTEX | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS | + R128_COMPOSITE_SHADOW_CMP_EQUAL | + R128_TEX_MAP_ALPHA_IN_TEXTURE | + R128_TEX_CACHE_LINE_SIZE_4QW); + + rmesa->new_state = R128_NEW_ALL; } -/* Initialize the driver's state functions */ +/* Initialize the driver's state functions. + */ void r128DDInitStateFuncs( GLcontext *ctx ) { ctx->Driver.UpdateState = r128DDUpdateState; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h index 6d122879d..97b01c7fa 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h @@ -28,29 +28,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_STATE_H_ -#define _R128_STATE_H_ +#ifndef __R128_STATE_H__ +#define __R128_STATE_H__ #ifdef GLX_DIRECT_RENDERING #include "r128_context.h" -extern void r128DDInitState( r128ContextPtr r128ctx ); +extern void r128DDInitState( r128ContextPtr rmesa ); extern void r128DDInitStateFuncs( GLcontext *ctx ); extern void r128DDUpdateState( GLcontext *ctx ); extern void r128DDUpdateHWState( GLcontext *ctx ); extern void r128UpdateWindow( GLcontext *ctx ); -extern void r128SetClipRects( r128ContextPtr r128ctx, - XF86DRIClipRectPtr pc, int nc ); -extern void r128EmitHwStateLocked( r128ContextPtr r128ctx ); +extern void r128EmitHwStateLocked( r128ContextPtr rmesa ); #endif -#endif /* _R128_STATE_H_ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c index ff619fa46..da06d4ed5 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -44,14 +44,77 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "mem.h" +#define TEX_0 1 +#define TEX_1 2 -static void r128SetTexWrap(r128TexObjPtr t, GLenum srwap, GLenum twrap); -static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf); -static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4]); -/* Allocate and initialize hardware state associated with texture `t' */ -/* NOTE: This function is only called while holding the hardware lock */ -static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, +static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) +{ + t->setup.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK); + + switch ( swrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_WRAP; + break; + } + + switch ( twrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_WRAP; + break; + } +} + +static void r128SetTexFilter( r128TexObjPtr t, GLenum minf, GLenum magf ) +{ + t->setup.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK); + + switch ( minf ) { + case GL_NEAREST: + t->setup.tex_cntl |= R128_MIN_BLEND_NEAREST; + break; + case GL_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->setup.tex_cntl |= R128_MIN_BLEND_MIPNEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_MIPLINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR; + break; + } + + switch ( magf ) { + case GL_NEAREST: + t->setup.tex_cntl |= R128_MAG_BLEND_NEAREST; + break; + case GL_LINEAR: + t->setup.tex_cntl |= R128_MAG_BLEND_LINEAR; + break; + } +} + +static void r128SetTexBorderColor( r128TexObjPtr t, GLubyte c[4] ) +{ + t->setup.tex_border_color = r128PackColor( 4, c[0], c[1], c[2], c[3] ); +} + + +/* Allocate and initialize hardware state associated with texture `t'. + */ +static r128TexObjPtr r128CreateTexObj( r128ContextPtr rmesa, struct gl_texture_object *tObj ) { r128TexObjPtr t; @@ -64,7 +127,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, if ( !image ) return NULL; - t = (r128TexObjPtr)CALLOC( sizeof(*t) ); + t = (r128TexObjPtr) CALLOC( sizeof(*t) ); if ( !t ) return NULL; @@ -75,8 +138,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, case GL_RGBA: case GL_ALPHA: case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - if ( r128ctx->r128Screen->bpp == 32 ) { + if ( rmesa->r128Screen->cpp == 4 ) { t->texelBytes = 4; t->textureFormat = R128_DATATYPE_ARGB8888; } else { @@ -86,7 +148,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, break; case GL_RGB: - if ( r128ctx->r128Screen->bpp == 32 ) { + if ( rmesa->r128Screen->cpp == 4 ) { t->texelBytes = 4; t->textureFormat = R128_DATATYPE_ARGB8888; } else { @@ -96,14 +158,9 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, break; case GL_LUMINANCE: - if ( r128ctx->r128Screen->bpp == 32 ) { - t->texelBytes = 4; - t->textureFormat = R128_DATATYPE_ARGB8888; - } else { - t->texelBytes = 2; - /* Use this to get true greys */ - t->textureFormat = R128_DATATYPE_ARGB1555; - } + case GL_INTENSITY: + t->texelBytes = 1; + t->textureFormat = R128_DATATYPE_RGB8; break; case GL_COLOR_INDEX: @@ -176,7 +233,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, (log2Height << R128_TEX_HEIGHT_SHIFT) | (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { t->setup.tex_offset[i] = 0x00000000; } t->setup.tex_border_color = 0x00000000; @@ -196,12 +253,13 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, return t; } -/* Destroy hardware state associated with texture `t' */ -void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) +/* Destroy hardware state associated with texture `t'. + */ +void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) { #if ENABLE_PERF_BOXES /* Bump the performace counter */ - r128ctx->c_textureSwaps++; + rmesa->c_textureSwaps++; #endif if ( !t ) return; @@ -212,19 +270,21 @@ void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) if ( t->tObj ) t->tObj->DriverData = NULL; - if ( t->bound ) - r128ctx->CurrentTexObj[t->bound-1] = NULL; + + if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; + if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; remove_from_list( t ); FREE( t ); } -/* Keep track of swapped out texture objects */ -static void r128SwapOutTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) +/* Keep track of swapped out texture objects. + */ +static void r128SwapOutTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) { #if ENABLE_PERF_BOXES /* Bump the performace counter */ - r128ctx->c_textureSwaps++; + rmesa->c_textureSwaps++; #endif if ( t->memBlock ) { mmFreeMem( t->memBlock ); @@ -232,18 +292,19 @@ static void r128SwapOutTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) } t->dirty_images = ~0; - move_to_tail( &r128ctx->SwappedOut, t ); + move_to_tail( &rmesa->SwappedOut, t ); } -/* Print out debugging information about texture LRU */ -void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ) +/* Print out debugging information about texture LRU. + */ +void r128PrintLocalLRU( r128ContextPtr rmesa, int heap ) { r128TexObjPtr t; - int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]); + int sz = 1 << (rmesa->r128Screen->logTexGranularity[heap]); fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - foreach( t, &r128ctx->TexObjList[heap] ) { + foreach ( t, &rmesa->TexObjList[heap] ) { if ( !t->tObj ) { fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", t->memBlock->ofs / sz, @@ -260,9 +321,9 @@ void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ) fprintf( stderr, "\n" ); } -void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ) +void r128PrintGlobalLRU( r128ContextPtr rmesa, int heap ) { - r128_tex_region_t *list = r128ctx->sarea->texList[heap]; + r128_tex_region_t *list = rmesa->sarea->texList[heap]; int i, j; fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); @@ -285,12 +346,12 @@ void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ) fprintf( stderr, "\n" ); } -/* Reset the global texture LRU */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) +/* Reset the global texture LRU. + */ +static void r128ResetGlobalLRU( r128ContextPtr rmesa, int heap ) { - r128_tex_region_t *list = r128ctx->sarea->texList[heap]; - int sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + r128_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = 1 << rmesa->r128Screen->logTexGranularity[heap]; int i; /* (Re)initialize the global circular LRU list. The last element in @@ -298,7 +359,7 @@ static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) * the end of the array allows it to be addressed rationally when * looking up objects at a particular location in texture memory. */ - for ( i = 0 ; (i+1) * sz <= r128ctx->r128Screen->texSize[heap] ; i++ ) { + for ( i = 0 ; (i+1) * sz <= rmesa->r128Screen->texSize[heap] ; i++ ) { list[i].prev = i-1; list[i].next = i+1; list[i].age = 0; @@ -310,21 +371,21 @@ static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) list[i].next = R128_NR_TEX_REGIONS; list[R128_NR_TEX_REGIONS].prev = i; list[R128_NR_TEX_REGIONS].next = 0; - r128ctx->sarea->texAge[heap] = 0; + rmesa->sarea->texAge[heap] = 0; } -/* Update the local and glock texture LRUs */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) +/* Update the local and glock texture LRUs. + */ +static void r128UpdateTexLRU( r128ContextPtr rmesa, r128TexObjPtr t ) { int heap = t->heap; - r128_tex_region_t *list = r128ctx->sarea->texList[heap]; - int log2sz = r128ctx->r128Screen->log2TexGran[heap]; + r128_tex_region_t *list = rmesa->sarea->texList[heap]; + int log2sz = rmesa->r128Screen->logTexGranularity[heap]; int start = t->memBlock->ofs >> log2sz; int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; int i; - r128ctx->lastTexAge[heap] = ++r128ctx->sarea->texAge[heap]; + rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; if ( !t->memBlock ) { fprintf( stderr, "no memblock\n\n" ); @@ -332,12 +393,12 @@ static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) } /* Update our local LRU */ - move_to_head( &r128ctx->TexObjList[heap], t ); + move_to_head( &rmesa->TexObjList[heap], t ); /* Update the global LRU */ for ( i = start ; i <= end ; i++ ) { list[i].in_use = 1; - list[i].age = r128ctx->lastTexAge[heap]; + list[i].age = rmesa->lastTexAge[heap]; /* remove_from_list(i) */ list[(CARD32)list[i].next].prev = list[i].prev; @@ -351,23 +412,23 @@ static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) } if ( 0 ) { - r128PrintGlobalLRU( r128ctx, t->heap ); - r128PrintLocalLRU( r128ctx, t->heap ); + r128PrintGlobalLRU( rmesa, t->heap ); + r128PrintLocalLRU( rmesa, t->heap ); } } /* Update our notion of what textures have been changed since we last - held the lock. This pertains to both our local textures and the - textures belonging to other clients. Keep track of other client's - textures by pushing a placeholder texture onto the LRU list -- these - are denoted by (tObj == NULL). */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128TexturesGone( r128ContextPtr r128ctx, int heap, + * held the lock. This pertains to both our local textures and the + * textures belonging to other clients. Keep track of other client's + * textures by pushing a placeholder texture onto the LRU list -- these + * are denoted by (tObj == NULL). + */ +static void r128TexturesGone( r128ContextPtr rmesa, int heap, int offset, int size, int in_use ) { r128TexObjPtr t, tmp; - foreach_s ( t, tmp, &r128ctx->TexObjList[heap] ) { + foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) { if ( t->memBlock->ofs >= offset + size || t->memBlock->ofs + t->memBlock->size <= offset ) continue; @@ -376,37 +437,38 @@ static void r128TexturesGone( r128ContextPtr r128ctx, int heap, * bound objects, however. */ if ( t->bound ) { - r128SwapOutTexObj( r128ctx, t ); + r128SwapOutTexObj( rmesa, t ); } else { - r128DestroyTexObj( r128ctx, t ); + r128DestroyTexObj( rmesa, t ); } } if ( in_use ) { t = (r128TexObjPtr) CALLOC( sizeof(*t) ); - if (!t) return; + if ( !t ) return; - t->memBlock = mmAllocMem( r128ctx->texHeap[heap], size, 0, offset ); + t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); if ( !t->memBlock ) { fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", (int)size, (int)offset ); - mmDumpMemInfo( r128ctx->texHeap[heap] ); + mmDumpMemInfo( rmesa->texHeap[heap] ); return; } - insert_at_head( &r128ctx->TexObjList[heap], t ); + insert_at_head( &rmesa->TexObjList[heap], t ); } } /* Update our client's shared texture state. If another client has - modified a region in which we have textures, then we need to figure - out which of our textures has been removed, and update our global - LRU. */ -void r128AgeTextures( r128ContextPtr r128ctx, int heap ) + * modified a region in which we have textures, then we need to figure + * out which of our textures has been removed, and update our global + * LRU. + */ +void r128AgeTextures( r128ContextPtr rmesa, int heap ) { - R128SAREAPriv *sarea = r128ctx->sarea; + R128SAREAPrivPtr sarea = rmesa->sarea; - if ( sarea->texAge[heap] != r128ctx->lastTexAge[heap] ) { - int sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { + int sz = 1 << rmesa->r128Screen->logTexGranularity[heap]; int nr = 0; int idx; @@ -418,15 +480,16 @@ void r128AgeTextures( r128ContextPtr r128ctx, int heap ) idx = sarea->texList[heap][idx].prev, nr++ ) { /* If switching texturing schemes, then the SAREA might not - have been properly cleared, so we need to reset the - global texture LRU. */ - if ( idx * sz > r128ctx->r128Screen->texSize[heap] ) { + * have been properly cleared, so we need to reset the + * global texture LRU. + */ + if ( idx * sz > rmesa->r128Screen->texSize[heap] ) { nr = R128_NR_TEX_REGIONS; break; } - if ( sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap] ) { - r128TexturesGone( r128ctx, heap, idx * sz, sz, + if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { + r128TexturesGone( rmesa, heap, idx * sz, sz, sarea->texList[heap][idx].in_use ); } } @@ -436,24 +499,30 @@ void r128AgeTextures( r128ContextPtr r128ctx, int heap ) * global texture LRU. */ if ( nr == R128_NR_TEX_REGIONS ) { - r128TexturesGone( r128ctx, heap, 0, - r128ctx->r128Screen->texSize[heap], 0 ); - r128ResetGlobalLRU( r128ctx, heap ); + r128TexturesGone( rmesa, heap, 0, + rmesa->r128Screen->texSize[heap], 0 ); + r128ResetGlobalLRU( rmesa, heap ); } if ( 0 ) { - r128PrintGlobalLRU( r128ctx, heap ); - r128PrintLocalLRU( r128ctx, heap ); + r128PrintGlobalLRU( rmesa, heap ); + r128PrintLocalLRU( rmesa, heap ); } - r128ctx->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_TEX0IMAGES | - R128_UPLOAD_TEX1IMAGES); - r128ctx->lastTexAge[heap] = sarea->texAge[heap]; + rmesa->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_TEX0IMAGES | + R128_UPLOAD_TEX1IMAGES); + rmesa->lastTexAge[heap] = sarea->texAge[heap]; } } -/* Convert a block of Mesa-formatted texture to an 8bpp hardware format */ + +/* ================================================================ + * Texture image conversions + */ + +/* Convert a block of Mesa-formatted texture to an 8bpp hardware format. + */ static void r128ConvertTexture8bpp( CARD32 *dst, struct gl_texture_image *image, int x, int y, int width, int height, @@ -463,20 +532,6 @@ static void r128ConvertTexture8bpp( CARD32 *dst, int i, j; switch ( image->Format ) { - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width >> 2 ; j ; j-- ) { - *dst++= ((R128PACKCOLOR332( src[0], src[1], src[2] )) | - (R128PACKCOLOR332( src[3], src[4], src[5] ) << 8) | - (R128PACKCOLOR332( src[6], src[7], src[8] ) << 16) | - (R128PACKCOLOR332( src[9], src[10], src[11] ) << 24)); - src += 12; - } - } - break; - - case GL_ALPHA: case GL_LUMINANCE: case GL_INTENSITY: case GL_COLOR_INDEX: @@ -496,7 +551,8 @@ static void r128ConvertTexture8bpp( CARD32 *dst, } } -/* Convert a block of Mesa-formatted texture to a 16bpp hardware format */ +/* Convert a block of Mesa-formatted texture to a 16bpp hardware format. + */ static void r128ConvertTexture16bpp( CARD32 *dst, struct gl_texture_image *image, int x, int y, int width, int height, @@ -512,17 +568,6 @@ static void r128ConvertTexture16bpp( CARD32 *dst, switch ( image->Format ) { - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR565( src[0], src[1], src[2] )) | - (R128PACKCOLOR565( src[3], src[4], src[5] ) << 16)); - src += 6; - } - } - break; - case GL_RGBA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; @@ -534,23 +579,23 @@ static void r128ConvertTexture16bpp( CARD32 *dst, } break; - case GL_ALPHA: + case GL_RGB: for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) | - (R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16)); - src += 2; + *dst++ = ((R128PACKCOLOR565( src[0], src[1], src[2] )) | + (R128PACKCOLOR565( src[3], src[4], src[5] ) << 16)); + src += 6; } } break; - case GL_LUMINANCE: + case GL_ALPHA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x); for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR1555( src[0], src[0], src[0], 0xff )) | - (R128PACKCOLOR1555( src[1], src[1], src[1], 0xff ) << 16)); + *dst++ = ((R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) | + (R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16)); src += 2; } } @@ -567,17 +612,6 @@ static void r128ConvertTexture16bpp( CARD32 *dst, } break; - case GL_INTENSITY: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR4444( src[0], src[0], src[0], src[0] )) | - (R128PACKCOLOR4444( src[1], src[1], src[1], src[1] ) << 16)); - src += 2; - } - } - break; - default: fprintf( stderr, "%s: unsupported format 0x%x\n", __FUNCTION__, image->Format ); @@ -585,7 +619,8 @@ static void r128ConvertTexture16bpp( CARD32 *dst, } } -/* Convert a block of Mesa-formatted texture to a 32bpp hardware format */ +/* Convert a block of Mesa-formatted texture to a 32bpp hardware format. + */ static void r128ConvertTexture32bpp( CARD32 *dst, struct gl_texture_image *image, int x, int y, int width, int height, @@ -595,16 +630,6 @@ static void r128ConvertTexture32bpp( CARD32 *dst, int i, j; switch ( image->Format ) { - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( src[0], src[1], src[2], 0xff ); - src += 3; - } - } - break; - case GL_RGBA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; @@ -615,21 +640,21 @@ static void r128ConvertTexture32bpp( CARD32 *dst, } break; - case GL_ALPHA: + case GL_RGB: for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( 0xff, 0xff, 0xff, src[0] ); - src += 1; + *dst++ = R128PACKCOLOR8888( src[0], src[1], src[2], 0xff ); + src += 3; } } break; - case GL_LUMINANCE: + case GL_ALPHA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x); for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( src[0], src[0], src[0], 0xff ); + *dst++ = R128PACKCOLOR8888( 0xff, 0xff, 0xff, src[0] ); src += 1; } } @@ -645,16 +670,6 @@ static void r128ConvertTexture32bpp( CARD32 *dst, } break; - case GL_INTENSITY: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( src[0], src[0], src[0], src[0] ); - src += 1; - } - } - break; - default: fprintf( stderr, "%s: unsupported format 0x%x\n", __FUNCTION__, image->Format ); @@ -663,9 +678,9 @@ static void r128ConvertTexture32bpp( CARD32 *dst, } /* Upload the texture image associated with texture `t' at level `level' - at the address relative to `start'. */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UploadSubImage( r128ContextPtr r128ctx, + * at the address relative to `start'. + */ +static void r128UploadSubImage( r128ContextPtr rmesa, r128TexObjPtr t, int level, int x, int y, int width, int height ) { @@ -680,7 +695,7 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, int i; /* Ensure we have a valid texture to upload */ - if ( ( level < 0 ) || ( level > R128_TEX_MAXLEVELS ) ) + if ( ( level < 0 ) || ( level > R128_MAX_TEXTURE_LEVELS ) ) return; image = t->tObj->Image[level]; @@ -694,7 +709,7 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, } #if 1 - /* FIXME: The subimage index calcs are wrong - who changed them? */ + /* FIXME: The subimage index calcs are wrong... */ x = 0; y = 0; width = image->Width; @@ -768,23 +783,17 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, dwords = width * height / texelsPerDword; offset = t->bufAddr + t->image[level].offset; - /* Fix offset for AGP textures */ - if ( t->heap == R128_AGP_TEX_HEAP ) { - offset += R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; - } - #if ENABLE_PERF_BOXES /* Bump the performace counter */ - r128ctx->c_textureBytes += (dwords << 2); + rmesa->c_textureBytes += (dwords << 2); #endif - if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "r128UploadSubImage: %d,%d of %d,%d at %d,%d\n", width, height, image->Width, image->Height, x, y ); fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d " "level: %d format: %x\n", - (int)offset, pitch, dwords, level, format ); + (GLuint)offset, (GLuint)pitch, dwords, level, format ); } /* Subdivide the texture if required */ @@ -803,11 +812,11 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, " blitting: %d,%d at %d,%d - %d dwords\n", - width, height, x, y, dwords ); + width, height, x, y, dwords ); } /* Grab the indirect buffer for the texture blit */ - buffer = r128GetBufferLocked( r128ctx ); + buffer = r128GetBufferLocked( rmesa ); dst = (CARD32 *)((char *)buffer->address + R128_HOSTDATA_BLIT_OFFSET); @@ -827,13 +836,13 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, break; } - r128FireBlitLocked( r128ctx, buffer, + r128FireBlitLocked( rmesa, buffer, offset, pitch, format, x, y, width, height ); } - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } /* Upload the texture images associated with texture `t'. This might @@ -841,7 +850,7 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, * make room for these images. */ /* NOTE: This function is only called while holding the hardware lock */ -int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) +int r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ) { int i; int minLevel; @@ -850,47 +859,47 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %p )\n", - __FUNCTION__, r128ctx->glCtx, t ); + __FUNCTION__, rmesa->glCtx, t ); } if ( !t ) return 0; /* Choose the heap appropriately */ - heap = t->heap = R128_LOCAL_TEX_HEAP; - if ( !r128ctx->r128Screen->IsPCI && - t->totalSize > r128ctx->r128Screen->texSize[heap] ) { - heap = t->heap = R128_AGP_TEX_HEAP; + heap = t->heap = R128_CARD_HEAP; + if ( !rmesa->r128Screen->IsPCI && + t->totalSize > rmesa->r128Screen->texSize[heap] ) { + heap = t->heap = R128_AGP_HEAP; } /* Do we need to eject LRU texture objects? */ if ( !t->memBlock ) { /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ - t->memBlock = mmAllocMem( r128ctx->texHeap[heap], t->totalSize, 12, 0 ); + t->memBlock = mmAllocMem( rmesa->texHeap[heap], t->totalSize, 12, 0 ); /* Try AGP before kicking anything out of local mem */ - if ( !t->memBlock && heap == R128_LOCAL_TEX_HEAP ) { - t->memBlock = mmAllocMem( r128ctx->texHeap[R128_AGP_TEX_HEAP], + if ( !t->memBlock && heap == R128_CARD_HEAP ) { + t->memBlock = mmAllocMem( rmesa->texHeap[R128_AGP_HEAP], t->totalSize, 12, 0 ); if ( t->memBlock ) - heap = t->heap = R128_AGP_TEX_HEAP; + heap = t->heap = R128_AGP_HEAP; } /* Kick out textures until the requested texture fits */ while ( !t->memBlock ) { - if ( r128ctx->TexObjList[heap].prev->bound ) { + if ( rmesa->TexObjList[heap].prev->bound ) { fprintf( stderr, "r128UploadTexImages: ran into bound texture\n" ); return -1; } - if ( r128ctx->TexObjList[heap].prev == &r128ctx->TexObjList[heap] ) { - if ( r128ctx->r128Screen->IsPCI ) { + if ( rmesa->TexObjList[heap].prev == &rmesa->TexObjList[heap] ) { + if ( rmesa->r128Screen->IsPCI ) { fprintf( stderr, "r128UploadTexImages: upload texture " "failure on local texture heaps, sz=%d\n", t->totalSize ); return -1; - } else if ( heap == R128_LOCAL_TEX_HEAP ) { - heap = t->heap = R128_AGP_TEX_HEAP; + } else if ( heap == R128_CARD_HEAP ) { + heap = t->heap = R128_AGP_HEAP; continue; } else { fprintf( stderr, "r128UploadTexImages: upload texture " @@ -901,14 +910,14 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) } } - r128DestroyTexObj( r128ctx, r128ctx->TexObjList[heap].prev ); + r128DestroyTexObj( rmesa, rmesa->TexObjList[heap].prev ); - t->memBlock = mmAllocMem( r128ctx->texHeap[heap], + t->memBlock = mmAllocMem( rmesa->texHeap[heap], t->totalSize, 12, 0 ); } /* Set the base offset of the texture image */ - t->bufAddr = r128ctx->r128Screen->texOffset[heap] + t->memBlock->ofs; + t->bufAddr = rmesa->r128Screen->texOffset[heap] + t->memBlock->ofs; maxLevel = ((t->setup.tex_size_pitch & R128_TEX_SIZE_MASK) >> R128_TEX_SIZE_SHIFT); @@ -917,7 +926,7 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) /* Set texture offsets */ if ( t->setup.tex_cntl & R128_MIP_MAP_DISABLE ) { - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { t->setup.tex_offset[i] = t->bufAddr; } } else { @@ -926,22 +935,15 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) (t->image[maxLevel-i].offset + t->bufAddr); } } - /* Fix AGP texture offsets */ - if ( heap == R128_AGP_TEX_HEAP ) { - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { - t->setup.tex_offset[i] += R128_AGP_TEX_OFFSET + - r128ctx->r128Screen->agpTexOffset; - } - } /* Force loading the new state into the hardware */ switch ( t->bound ) { case 1: - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX0; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX0; break; case 2: - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX1; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX1; break; default: @@ -950,7 +952,7 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) } /* Let the world know we've used this memory recently */ - r128UpdateTexLRU( r128ctx, t ); + r128UpdateTexLRU( rmesa, t ); /* Upload any images that are new */ if ( t->dirty_images ) { @@ -961,14 +963,14 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) for ( i = 0 ; i <= num_levels ; i++ ) { if ( t->dirty_images & (1 << i) ) { - r128UploadSubImage( r128ctx, t, i, 0, 0, + r128UploadSubImage( rmesa, t, i, 0, 0, t->image[i].width, t->image[i].height ); } } - r128ctx->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + rmesa->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } t->dirty_images = 0; @@ -976,47 +978,50 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) } -/* - * Texture combiners: +/* ================================================================ + * Texture combine functions */ -#define COLOR_COMB_DISABLE (R128_COMB_DIS | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_COPY_INPUT (R128_COMB_COPY_INP | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_MODULATE (R128_COMB_MODULATE | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_MODULATE_NTEX (R128_COMB_MODULATE | \ - R128_COLOR_FACTOR_NTEX) -#define COLOR_COMB_ADD (R128_COMB_ADD | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_BLEND_TEX (R128_COMB_BLEND_TEXTURE | \ - R128_COLOR_FACTOR_TEX) - -#define ALPHA_COMB_DISABLE (R128_COMB_ALPHA_DIS | \ - R128_ALPHA_FACTOR_TEX_ALPHA) -#define ALPHA_COMB_COPY_INPUT (R128_COMB_ALPHA_COPY_INP | \ - R128_ALPHA_FACTOR_TEX_ALPHA) -#define ALPHA_COMB_MODULATE (R128_COMB_ALPHA_MODULATE | \ - R128_ALPHA_FACTOR_TEX_ALPHA) -#define ALPHA_COMB_MODULATE_NTEX (R128_COMB_ALPHA_MODULATE | \ - R128_ALPHA_FACTOR_NTEX_ALPHA) -#define ALPHA_COMB_ADD (R128_COMB_ADD | \ - R128_ALPHA_FACTOR_TEX_ALPHA) - -#define INPUT_INTERP (R128_INPUT_FACTOR_INT_COLOR | \ - R128_INP_FACTOR_A_INT_ALPHA) -#define INPUT_PREVIOUS (R128_INPUT_FACTOR_PREV_COLOR | \ - R128_INP_FACTOR_A_PREV_ALPHA) - -static void r128UpdateTextureStage( GLcontext *ctx, int unit ) +#define COLOR_COMB_DISABLE (R128_COMB_DIS | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_COPY_INPUT (R128_COMB_COPY_INP | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_MODULATE (R128_COMB_MODULATE | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_MODULATE_NTEX (R128_COMB_MODULATE | \ + R128_COLOR_FACTOR_NTEX) +#define COLOR_COMB_ADD (R128_COMB_ADD | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_BLEND_TEX (R128_COMB_BLEND_TEXTURE | \ + R128_COLOR_FACTOR_TEX) +/* Rage 128 Pro/M3 only! */ +#define COLOR_COMB_BLEND_COLOR (R128_COMB_MODULATE2X | \ + R128_COMB_FCN_MSB | \ + R128_COLOR_FACTOR_CONST_COLOR) + +#define ALPHA_COMB_DISABLE (R128_COMB_ALPHA_DIS | \ + R128_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_COPY_INPUT (R128_COMB_ALPHA_COPY_INP | \ + R128_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_MODULATE (R128_COMB_ALPHA_MODULATE | \ + R128_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_MODULATE_NTEX (R128_COMB_ALPHA_MODULATE | \ + R128_ALPHA_FACTOR_NTEX_ALPHA) +#define ALPHA_COMB_ADD (R128_COMB_ALPHA_ADD | \ + R128_ALPHA_FACTOR_TEX_ALPHA) + +#define INPUT_INTERP (R128_INPUT_FACTOR_INT_COLOR | \ + R128_INP_FACTOR_A_INT_ALPHA) +#define INPUT_PREVIOUS (R128_INPUT_FACTOR_PREV_COLOR | \ + R128_INP_FACTOR_A_PREV_ALPHA) + +static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int source = r128ctx->tmu_source[unit]; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLint source = rmesa->tmu_source[unit]; struct gl_texture_object *tObj; - r128TexObjPtr t; GLuint enabled; - CARD32 combine; + GLuint combine; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %d )\n", @@ -1038,9 +1043,6 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) return; - /* We definately have a valid texture now */ - t = tObj->DriverData; - if ( unit == 0 ) { combine = INPUT_INTERP; } else { @@ -1120,20 +1122,63 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) break; case GL_BLEND: - /* Catch the cases of GL_BLEND we can't handle (yet, in some cases). + /* Rage 128 Pro and M3 can handle GL_BLEND texturing. + */ + if ( !R128_IS_PLAIN( rmesa ) ) { + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-Ct)+CcCt */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-Ct)+CcCt */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + + case GL_INTENSITY: + /* GH: We could be smarter about this... */ + switch ( rmesa->env_color & 0xff000000 ) { + case 0x00000000: + combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-It)+CcIt */ + ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-It) */ + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + rmesa->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + + case GL_COLOR_INDEX: + default: + return; + } + break; + } + + /* Rage 128 has to fake some cases of GL_BLEND, otherwise fallback + * to software rendering. */ - if ( r128ctx->blend_flags ) { - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + if ( rmesa->blend_flags ) { + rmesa->Fallback |= R128_FALLBACK_TEXTURE; } switch ( tObj->Image[0]->Format ) { case GL_RGBA: case GL_LUMINANCE_ALPHA: - switch ( r128ctx->env_color ) { + switch ( rmesa->env_color & 0x00ffffff ) { case 0x00000000: combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_MODULATE); /* A = AfAt */ break; - case 0xffffffff: + case 0x00ffffff: if ( unit == 0 ) { combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_MODULATE); /* A = AfAt */ @@ -1145,18 +1190,18 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; break; } break; case GL_RGB: case GL_LUMINANCE: - switch ( r128ctx->env_color ) { + switch ( rmesa->env_color & 0x00ffffff ) { case 0x00000000: combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_COPY_INPUT); /* A = Af */ break; - case 0xffffffff: + case 0x00ffffff: if ( unit == 0 ) { combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_COPY_INPUT); /* A = Af */ @@ -1168,42 +1213,52 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_COPY_INPUT); /* A = fallback */ - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; break; } break; case GL_ALPHA: - combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ - ALPHA_COMB_MODULATE); /* A = AfAt */ + if ( unit == 0 ) { + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + } else { + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } break; case GL_INTENSITY: - switch ( r128ctx->env_color ) { + switch ( rmesa->env_color & 0x00ffffff ) { case 0x00000000: - combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ - ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */ break; case 0x00ffffff: if ( unit == 0 ) { - combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ - ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */ } else { - combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ - ALPHA_COMB_COPY_INPUT); /* A = Af */ + combine |= COLOR_COMB_ADD; /* C = Cf+It */ } break; - case 0xffffffff: + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + rmesa->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + switch ( rmesa->env_color & 0xff000000 ) { + case 0x00000000: + combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */ + break; + case 0xff000000: if ( unit == 0 ) { - combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ - ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */ } else { - combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ - ALPHA_COMB_ADD); /* A = Af+At */ + combine |= ALPHA_COMB_ADD; /* A = Af+It */ } break; default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; break; } break; @@ -1217,7 +1272,6 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) switch ( tObj->Image[0]->Format ) { case GL_RGBA: case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ ALPHA_COMB_MODULATE); /* A = AfAt */ break; @@ -1230,6 +1284,10 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ ALPHA_COMB_MODULATE); /* A = AfAt */ break; + case GL_INTENSITY: + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_ADD); /* A = Af+At */ + break; case GL_COLOR_INDEX: default: return; @@ -1240,13 +1298,13 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) return; } - t->setup.tex_combine_cntl = combine; + rmesa->tex_combine[unit] = combine; } static void r128UpdateTextureObject( GLcontext *ctx, int unit ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int source = r128ctx->tmu_source[unit]; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; struct gl_texture_object *tObj; r128TexObjPtr t; GLuint enabled; @@ -1256,14 +1314,10 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) __FUNCTION__, ctx, unit, ctx->Texture.ReallyEnabled ); } - /* Disable all texturing until it is known to be good */ - r128ctx->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE | - R128_SEC_TEXMAP_ENABLE); - enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { if ( enabled ) - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } @@ -1272,13 +1326,13 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) */ tObj = ctx->Texture.Unit[source].Current; if ( !tObj || !tObj->Complete ) { - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) { - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } @@ -1286,13 +1340,13 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) /* If this is the first time the texture has been used, then create * a new texture object for it. */ - r128CreateTexObj( r128ctx, tObj ); + r128CreateTexObj( rmesa, tObj ); if ( !tObj->DriverData ) { /* Can't create a texture object... */ fprintf( stderr, "%s: texture object creation failed!\n", __FUNCTION__ ); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } } @@ -1301,39 +1355,37 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) t = tObj->DriverData; /* Force the texture unit state to be loaded into the hardware */ - r128ctx->dirty |= R128_UPLOAD_CONTEXT | (R128_UPLOAD_TEX0 << unit); + rmesa->dirty |= R128_UPLOAD_CONTEXT | (R128_UPLOAD_TEX0 << unit); /* Force any texture images to be loaded into the hardware */ if ( t->dirty_images ) - r128ctx->dirty |= (R128_UPLOAD_TEX0IMAGES << unit); + rmesa->dirty |= (R128_UPLOAD_TEX0IMAGES << unit); /* Bind to the given texture unit */ - r128ctx->CurrentTexObj[unit] = t; - t->bound = unit + 1; + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; if ( t->memBlock ) - r128UpdateTexLRU( r128ctx, t ); + r128UpdateTexLRU( rmesa, t ); if ( unit == 0 ) { - r128ctx->setup.tex_cntl_c |= R128_TEXMAP_ENABLE; - r128ctx->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; - r128ctx->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; + rmesa->setup.tex_cntl_c |= R128_TEXMAP_ENABLE; + rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; + rmesa->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; t->setup.tex_cntl &= ~R128_SEC_SELECT_SEC_ST; } else { t->setup.tex_cntl |= R128_SEC_SELECT_SEC_ST; - r128ctx->setup.tex_cntl_c |= (R128_TEXMAP_ENABLE | - R128_SEC_TEXMAP_ENABLE) ; - r128ctx->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; - r128ctx->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; + rmesa->setup.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE; + rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; + rmesa->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; } } -/* Update the hardware texture state */ void r128UpdateTextureState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p ) en=0x%x\n", @@ -1341,112 +1393,47 @@ void r128UpdateTextureState( GLcontext *ctx ) } /* Clear any texturing fallbacks */ - r128ctx->Fallback &= ~R128_FALLBACK_TEXTURE; + rmesa->Fallback &= ~R128_FALLBACK_TEXTURE; - /* Unbind any currently bound textures */ - if ( r128ctx->CurrentTexObj[0] ) r128ctx->CurrentTexObj[0]->bound = 0; - if ( r128ctx->CurrentTexObj[1] ) r128ctx->CurrentTexObj[1]->bound = 0; - r128ctx->CurrentTexObj[0] = NULL; - r128ctx->CurrentTexObj[1] = NULL; + /* Unbind any currently bound textures */ + if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0; + if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0; + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; - r128ctx->setup.tex_size_pitch_c = 0x00000000; + if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) ) + rmesa->Fallback |= R128_FALLBACK_TEXTURE; + + /* Disable all texturing until it is known to be good */ + rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE | + R128_SEC_TEXMAP_ENABLE); + rmesa->setup.tex_size_pitch_c = 0x00000000; r128UpdateTextureObject( ctx, 0 ); - r128UpdateTextureStage( ctx, 0 ); + r128UpdateTextureEnv( ctx, 0 ); - if ( r128ctx->multitex ) { + if ( rmesa->multitex ) { r128UpdateTextureObject( ctx, 1 ); - r128UpdateTextureStage( ctx, 1 ); + r128UpdateTextureEnv( ctx, 1 ); } - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } -/* Set the texture wrap mode */ -static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) -{ - t->setup.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK); - - switch ( swrap ) { - case GL_CLAMP: - t->setup.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; - break; - case GL_REPEAT: - t->setup.tex_cntl |= R128_TEX_CLAMP_S_WRAP; - break; - } - - switch ( twrap ) { - case GL_CLAMP: - t->setup.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; - break; - case GL_REPEAT: - t->setup.tex_cntl |= R128_TEX_CLAMP_T_WRAP; - break; - } -} - -/* Set the texture filter mode */ -static void r128SetTexFilter( r128TexObjPtr t, GLenum minf, GLenum magf ) -{ - t->setup.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK); - - switch ( minf ) { - case GL_NEAREST: - t->setup.tex_cntl |= R128_MIN_BLEND_NEAREST; - break; - case GL_LINEAR: - t->setup.tex_cntl |= R128_MIN_BLEND_LINEAR; - break; - case GL_NEAREST_MIPMAP_NEAREST: - t->setup.tex_cntl |= R128_MIN_BLEND_MIPNEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - t->setup.tex_cntl |= R128_MIN_BLEND_MIPLINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR; - break; - } - - switch ( magf ) { - case GL_NEAREST: - t->setup.tex_cntl |= R128_MAG_BLEND_NEAREST; - break; - case GL_LINEAR: - t->setup.tex_cntl |= R128_MAG_BLEND_LINEAR; - break; - } -} - -/* Set the texture border color */ -static void r128SetTexBorderColor( r128TexObjPtr t, GLubyte c[4] ) -{ - t->setup.tex_border_color = r128PackColor( 32, c[0], c[1], c[2], c[3] ); -} - - -/* -============================================================================ - -Driver functions called directly from mesa - -============================================================================ -*/ - +/* ================================================================ + * DD interface texturing functions + * + * FIXME: Many of these are deprecated -- we should move to the new + * single-copy texture interface. + */ -/* Set the texture environment state */ static void r128DDTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct gl_texture_unit *texUnit; GLubyte c[4]; - int bias; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %s )\n", @@ -1455,59 +1442,71 @@ static void r128DDTexEnv( GLcontext *ctx, GLenum target, switch ( pname ) { case GL_TEXTURE_ENV_MODE: - /* TexEnv modes are handled in UpdateTextureState */ - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_TEXTURE | R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_TEXTURE | R128_NEW_ALPHA; break; case GL_TEXTURE_ENV_COLOR: texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; FLOAT_RGBA_TO_UBYTE_RGBA( c, texUnit->EnvColor ); - r128ctx->env_color = r128PackColor( 32, c[0], c[1], c[2], c[3] ); - if ( r128ctx->setup.constant_color_c != r128ctx->env_color ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.constant_color_c = r128ctx->env_color; + rmesa->env_color = r128PackColor( 4, c[0], c[1], c[2], c[3] ); + if ( rmesa->setup.constant_color_c != rmesa->env_color ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.constant_color_c = rmesa->env_color; - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; /* More complex multitexture/multipass fallbacks for GL_BLEND * can be done later, but this allows a single pass GL_BLEND - * in some cases (ie. Performer town demo). + * in some cases (ie. Performer town demo). This is only + * applicable to the regular Rage 128, as the Pro and M3 can + * handle true single-pass GL_BLEND texturing. */ - r128ctx->blend_flags &= ~R128_BLEND_ENV_COLOR; - if ( r128ctx->env_color != 0x00000000 && - r128ctx->env_color != 0xff000000 /*&& - r128ctx->env_color != 0x00ffffff && - r128ctx->env_color != 0xffffffff */ ) { - r128ctx->blend_flags |= R128_BLEND_ENV_COLOR; + rmesa->blend_flags &= ~R128_BLEND_ENV_COLOR; + if ( R128_IS_PLAIN( rmesa ) && + rmesa->env_color != 0x00000000 && + rmesa->env_color != 0xff000000 && + rmesa->env_color != 0x00ffffff && + rmesa->env_color != 0xffffffff ) { + rmesa->blend_flags |= R128_BLEND_ENV_COLOR; } } break; case GL_TEXTURE_LOD_BIAS_EXT: - /* GTH: This isn't exactly correct, but gives good results up to a - * certain point. It is better than completely ignoring the LOD - * bias. Unfortunately there isn't much range in the bias, the - * spec mentions strides that vary between 0.5 and 2.0 but these - * numbers don't seem to relate the the GL LOD bias value at all. - */ - if ( param[0] >= 1.0 ) { - bias = -128; - } else if ( param[0] >= 0.5 ) { - bias = -64; - } else if ( param[0] >= 0.25 ) { - bias = 0; - } else if ( param[0] >= 0.0 ) { - bias = 63; - } else { - bias = 127; - } - if ( r128ctx->lod_bias != bias ) { - FLUSH_BATCH( r128ctx ); - r128ctx->lod_bias = bias; + do { + CARD32 t = rmesa->setup.tex_cntl_c; + GLint bias; + CARD32 b; + + /* GTH: This isn't exactly correct, but gives good results up to a + * certain point. It is better than completely ignoring the LOD + * bias. Unfortunately there isn't much range in the bias, the + * spec mentions strides that vary between 0.5 and 2.0 but these + * numbers don't seem to relate the the GL LOD bias value at all. + */ + if ( param[0] >= 1.0 ) { + bias = -128; + } else if ( param[0] >= 0.5 ) { + bias = -64; + } else if ( param[0] >= 0.25 ) { + bias = 0; + } else if ( param[0] >= 0.0 ) { + bias = 63; + } else { + bias = 127; + } - r128ctx->new_state |= R128_NEW_RENDER; - } + b = (CARD32)bias & 0xff; + t &= ~R128_LOD_BIAS_MASK; + t |= (b << R128_LOD_BIAS_SHIFT); + + if ( rmesa->setup.tex_cntl_c != t ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } + } while (0); break; default: @@ -1515,35 +1514,37 @@ static void r128DDTexEnv( GLcontext *ctx, GLenum target, } } -/* Upload a new texture image */ static void r128DDTexImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t; if ( R128_DEBUG & DEBUG_VERBOSE_API ) fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level ); - if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; - if ( level >= R128_TEX_MAXLEVELS ) return; + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= R128_MAX_TEXTURE_LEVELS ) + return; t = (r128TexObjPtr)tObj->DriverData; if ( t ) { - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); /* Destroy the old texture, and upload a new one. The actual * uploading of the texture image occurs in the UploadSubImage * function. */ - r128DestroyTexObj( r128ctx, t ); - r128ctx->new_state |= R128_NEW_TEXTURE; + r128DestroyTexObj( rmesa, t ); + rmesa->new_state |= R128_NEW_TEXTURE; } } -/* Upload a new texture sub-image */ static void r128DDTexSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, @@ -1551,7 +1552,7 @@ static void r128DDTexSubImage( GLcontext *ctx, GLenum target, GLint internalFormat, const struct gl_texture_image *image ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { @@ -1560,31 +1561,34 @@ static void r128DDTexSubImage( GLcontext *ctx, GLenum target, image->Width, image->Height ); } - if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; - if ( level >= R128_TEX_MAXLEVELS ) return; + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= R128_MAX_TEXTURE_LEVELS ) + return; t = (r128TexObjPtr)tObj->DriverData; if ( t ) { - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); - LOCK_HARDWARE( r128ctx ); - r128UploadSubImage( r128ctx, t, level, + LOCK_HARDWARE( rmesa ); + r128UploadSubImage( rmesa, t, level, xoffset, yoffset, width, height ); - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); /* Update the context state */ - r128ctx->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + rmesa->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; } } -/* Set the texture parameter state */ static void r128DDTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { @@ -1592,24 +1596,32 @@ static void r128DDTexParameter( GLcontext *ctx, GLenum target, __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); } - if ( !t || !t->bound ) return; - if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; + /* If we don't have a hardware texture, it will be automatically + * created with current state before it is used, so we don't have + * to do anything now. + */ + if ( !t || !t->bound ) + return; + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; switch ( pname ) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); r128SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); r128SetTexWrap( t, tObj->WrapS, tObj->WrapT ); break; case GL_TEXTURE_BORDER_COLOR: - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); r128SetTexBorderColor( t, tObj->BorderColor ); break; @@ -1617,14 +1629,13 @@ static void r128DDTexParameter( GLcontext *ctx, GLenum target, return; } - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; } -/* Bind a texture to the currently active texture unit */ static void r128DDBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLint unit = ctx->Texture.CurrentUnit; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { @@ -1632,50 +1643,46 @@ static void r128DDBindTexture( GLcontext *ctx, GLenum target, __FUNCTION__, tObj, unit ); } - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - /* Unbind the old texture */ - if ( r128ctx->CurrentTexObj[unit] ) { - r128ctx->CurrentTexObj[unit]->bound &= ~(unit+1); - r128ctx->CurrentTexObj[unit] = NULL; + if ( rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit]->bound &= ~(unit+1); + rmesa->CurrentTexObj[unit] = NULL; } - /* The actualy binding occurs in the Tex[01]UpdateState function */ - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; } -/* Remove texture from AGP/local texture memory */ static void r128DDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; if ( t ) { if ( t->bound ) { - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - r128ctx->CurrentTexObj[t->bound-1] = 0; - r128ctx->new_state |= R128_NEW_TEXTURE; + if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; + if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; + rmesa->new_state |= R128_NEW_TEXTURE; } - r128DestroyTexObj( r128ctx, t ); + r128DestroyTexObj( rmesa, t ); tObj->DriverData = NULL; } } -/* Determine if a texture is currently residing in either AGP/local - * texture memory. - */ static GLboolean r128DDIsTextureResident( GLcontext *ctx, struct gl_texture_object *tObj ) { r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; - return t && t->memBlock; + return ( t && t->memBlock ); } -/* Initialize the driver's texture functions */ + + void r128DDInitTextureFuncs( GLcontext *ctx ) { ctx->Driver.TexEnv = r128DDTexEnv; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h index fbe39b8c0..92d4c4e3f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h @@ -28,58 +28,65 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_TEX_H_ -#define _R128_TEX_H_ +#ifndef __R128_TEX_H__ +#define __R128_TEX_H__ #ifdef GLX_DIRECT_RENDERING extern void r128UpdateTextureState( GLcontext *ctx ); -extern int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ); +extern int r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ); -extern void r128AgeTextures( r128ContextPtr r128ctx, int heap ); -extern void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ); +extern void r128AgeTextures( r128ContextPtr rmesa, int heap ); +extern void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ); -extern void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ); -extern void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ); +extern void r128PrintLocalLRU( r128ContextPtr rmesa, int heap ); +extern void r128PrintGlobalLRU( r128ContextPtr rmesa, int heap ); extern void r128DDInitTextureFuncs( GLcontext *ctx ); -#define R128PACKCOLOR332(r, g, b) \ - (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) +/* ================================================================ + * Color conversion macros: + */ + +#define R128PACKCOLOR332( r, g, b ) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) -#define R128PACKCOLOR1555(r, g, b, a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) +#define R128PACKCOLOR1555( r, g, b, a ) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) -#define R128PACKCOLOR565(r, g, b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) +#define R128PACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) -#define R128PACKCOLOR888(r, g, b) \ - (((r) << 16) | ((g) << 8) | (b)) +#define R128PACKCOLOR888( r, g, b ) \ + (((r) << 16) | ((g) << 8) | (b)) -#define R128PACKCOLOR8888(r, g, b, a) \ - (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define R128PACKCOLOR8888( r, g, b, a ) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) -#define R128PACKCOLOR4444(r, g, b, a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) +#define R128PACKCOLOR4444( r, g, b, a ) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) -static __inline__ CARD32 r128PackColor( GLuint bpp, +static __inline__ CARD32 r128PackColor( GLuint cpp, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - switch ( bpp ) { - case 16: return R128PACKCOLOR565( r, g, b ); - case 32: return R128PACKCOLOR8888( r, g, b, a ); - default: return 0; + switch ( cpp ) { + case 2: + return R128PACKCOLOR565( r, g, b ); + case 4: + return R128PACKCOLOR8888( r, g, b, a ); + default: + return 0; } } #endif -#endif /* _R128_TEX_H_ */ +#endif /* __R128_TEX_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h index 59b568321..b1611468a 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -39,44 +39,45 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_sarea.h" #include "mm.h" -/* Individual texture image information */ +/* Individual texture image information. + */ typedef struct { - GLuint offset; /* Offset into locally shared texture space (i.e., - relative to bufAddr (below) */ - GLuint width; /* Width of texture image */ - GLuint height; /* Height of texture image */ + GLuint offset; /* Relative to local texture space */ + GLuint width; + GLuint height; } r128TexImage; typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr; -/* Texture object in locally shared texture space */ +/* Texture object in locally shared texture space. + */ struct r128_tex_obj { - r128TexObjPtr next, prev; + r128TexObjPtr next, prev; struct gl_texture_object *tObj; /* Mesa texture object */ - PMemBlock memBlock; /* Memory block containing texture */ - CARD32 bufAddr; /* Offset to start of locally + PMemBlock memBlock; /* Memory block containing texture */ + CARD32 bufAddr; /* Offset to start of locally shared texture block */ - CARD32 dirty_images; /* Flags for whether or not + CARD32 dirty_images; /* Flags for whether or not images need to be uploaded to local or AGP texture space */ - GLuint age; - GLint bound; /* Texture unit currently bound to */ - GLint heap; /* Texture heap currently stored in */ - r128TexImage image[R128_TEX_MAXLEVELS]; /* Image data for all - mipmap levels */ + GLuint age; + GLint bound; /* Texture unit currently bound to */ + GLint heap; /* Texture heap currently stored in */ + r128TexImage image[R128_MAX_TEXTURE_LEVELS]; /* Image data for all + mipmap levels */ - GLint totalSize; /* Total size of the texture + GLint totalSize; /* Total size of the texture including all mipmap levels */ - GLuint internFormat; /* Internal GL format used to store + GLuint internFormat; /* Internal GL format used to store texture on card */ - CARD32 textureFormat; /* Actual hardware format */ - GLint texelBytes; /* Number of bytes per texel */ + CARD32 textureFormat; /* Actual hardware format */ + GLint texelBytes; /* Number of bytes per texel */ - r128_texture_regs_t setup; /* Setup regs for texture */ + r128_texture_regs_t setup; /* Setup regs for texture */ }; #endif /* _R128_TEXOBJ_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c index 8d1053e90..aeddb8f95 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -49,25 +49,28 @@ static struct { quad_func quad; } rast_tab[R128_MAX_TRIFUNC]; -#define R128_COLOR(to, from) \ -do { \ - (to)[0] = (from)[2]; \ - (to)[1] = (from)[1]; \ - (to)[2] = (from)[0]; \ - (to)[3] = (from)[3]; \ +#define R128_COLOR( to, from ) \ +do { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ + (to)[3] = (from)[3]; \ } while (0) static void r128_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) { + GLuint v1, GLuint v2, GLuint v3, GLuint pv ) +{ } static void r128_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) { + GLuint v1, GLuint v2, GLuint pv ) +{ } -static void r128_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { +static void r128_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) +{ } - -static void r128_null_points( GLcontext *ctx, GLuint first, GLuint last ) { +static void r128_null_points( GLcontext *ctx, GLuint first, GLuint last ) +{ } static void r128PrintRenderState( const char *msg, GLuint state ) @@ -114,10 +117,9 @@ static void r128PrintRenderState( const char *msg, GLuint state ) #include "r128_tritmp.h" -/* Initialize the table of points, line and triangle drawing functions */ void r128DDTriangleFuncsInit( void ) { - int i; + GLint i; init(); init_flat(); @@ -128,12 +130,12 @@ void r128DDTriangleFuncsInit( void ) init_twoside_offset(); init_twoside_offset_flat(); - for ( i = 0 ; i < 0x20 ; i++ ) { - if ( (i & (R128_NODRAW_BIT | R128_FALLBACK_BIT)) == R128_NODRAW_BIT ) { - rast_tab[i].points = r128_null_points; - rast_tab[i].line = r128_null_line; - rast_tab[i].triangle = r128_null_triangle; - rast_tab[i].quad = r128_null_quad; + for ( i = 0 ; i < R128_MAX_TRIFUNC ; i++ ) { + if ( i & R128_NODRAW_BIT ) { + rast_tab[i].points = r128_null_points; + rast_tab[i].line = r128_null_line; + rast_tab[i].triangle = r128_null_triangle; + rast_tab[i].quad = r128_null_quad; } } } @@ -147,7 +149,7 @@ void r128DDTriangleFuncsInit( void ) #define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_STIPPLE | DD_TRI_UNFILLED) #define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) -#define ANY_RASTER_FLAGS (/*DD_FLATSHADE |*/ DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) /* Setup the Point, Line, Triangle and Quad functions based on the * current rendering state. Wherever possible, use the hardware to @@ -155,12 +157,12 @@ void r128DDTriangleFuncsInit( void ) */ void r128DDChooseRenderState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLuint flags = ctx->TriangleCaps; - CARD32 index = 0; + GLuint index = 0; - if ( r128ctx->Fallback ) { - r128ctx->RenderIndex = R128_FALLBACK_BIT; + if ( rmesa->Fallback ) { + rmesa->RenderIndex = R128_FALLBACK_BIT; return; } @@ -171,37 +173,38 @@ void r128DDChooseRenderState( GLcontext *ctx ) if ( flags & DD_Z_NEVER ) index |= R128_NODRAW_BIT; } - r128ctx->PointsFunc = rast_tab[index].points; - r128ctx->LineFunc = rast_tab[index].line; - r128ctx->TriangleFunc = rast_tab[index].triangle; - r128ctx->QuadFunc = rast_tab[index].quad; + rmesa->PointsFunc = rast_tab[index].points; + rmesa->LineFunc = rast_tab[index].line; + rmesa->TriangleFunc = rast_tab[index].triangle; + rmesa->QuadFunc = rast_tab[index].quad; - r128ctx->RenderIndex = index; - r128ctx->IndirectTriangles = 0; + rmesa->RenderIndex = index; + rmesa->IndirectTriangles = 0; if ( flags & ANY_FALLBACK ) { - r128ctx->RenderIndex |= R128_FALLBACK_BIT; - if ( flags & POINT_FALLBACK ) { - r128ctx->PointsFunc = 0; - r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + rmesa->RenderIndex |= R128_FALLBACK_BIT; + rmesa->PointsFunc = 0; + rmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; } if ( flags & LINE_FALLBACK ) { - r128ctx->LineFunc = 0; - r128ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + rmesa->RenderIndex |= R128_FALLBACK_BIT; + rmesa->LineFunc = 0; + rmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; } if ( flags & TRI_FALLBACK ) { - r128ctx->TriangleFunc = 0; - r128ctx->QuadFunc = 0; - r128ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | - DD_QUAD_SW_RASTERIZE); + rmesa->RenderIndex |= R128_FALLBACK_BIT; + rmesa->TriangleFunc = 0; + rmesa->QuadFunc = 0; + rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); } } if ( 0 ) { gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); - r128PrintRenderState( "r128 render state", r128ctx->RenderIndex ); + r128PrintRenderState( "r128 render state", rmesa->RenderIndex ); } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h index 364aa02c9..fac43f3ce 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h @@ -28,22 +28,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_TRIS_H_ -#define _R128_TRIS_H_ +#ifndef __R128_TRIS_H__ +#define __R128_TRIS_H__ #ifdef GLX_DIRECT_RENDERING #include "r128_vb.h" -extern void r128DDChooseRenderState(GLcontext *ctx); -extern void r128DDTriangleFuncsInit(void); +extern void r128DDChooseRenderState( GLcontext *ctx ); +extern void r128DDTriangleFuncsInit( void ); -#define R128_ANTIALIAS_BIT 0x00 /* Ignored for now */ #define R128_FLAT_BIT 0x01 #define R128_OFFSET_BIT 0x02 #define R128_TWOSIDE_BIT 0x04 @@ -51,18 +50,18 @@ extern void r128DDTriangleFuncsInit(void); #define R128_FALLBACK_BIT 0x10 #define R128_MAX_TRIFUNC 0x20 -/* Draw a triangle from the vertices in the vertex buffer */ -static __inline void r128_draw_triangle( r128ContextPtr r128ctx, - r128Vertex *v0, - r128Vertex *v1, - r128Vertex *v2 ) + +static __inline void r128_draw_triangle( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1, + r128VertexPtr v2 ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 3 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 3 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -93,19 +92,18 @@ static __inline void r128_draw_triangle( r128ContextPtr r128ctx, #endif } -/* Draw a quad from the vertices in the vertex buffer */ -static __inline void r128_draw_quad( r128ContextPtr r128ctx, - r128Vertex *v0, - r128Vertex *v1, - r128Vertex *v2, - r128Vertex *v3 ) +static __inline void r128_draw_quad( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1, + r128VertexPtr v2, + r128VertexPtr v3 ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 6 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -160,15 +158,14 @@ static __inline void r128_draw_quad( r128ContextPtr r128ctx, #endif } -/* Draw a line from the vertices in the vertex buffer */ -static __inline void r128_draw_line( r128ContextPtr r128ctx, - r128Vertex *tmp0, - r128Vertex *tmp1, +static __inline void r128_draw_line( r128ContextPtr rmesa, + r128VertexPtr tmp0, + r128VertexPtr tmp1, float width ) { #if 1 - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 6 ); float dx, dy, ix, iy; int j; @@ -221,12 +218,12 @@ static __inline void r128_draw_line( r128ContextPtr r128ctx, #else - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 2 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 2 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -250,13 +247,12 @@ static __inline void r128_draw_line( r128ContextPtr r128ctx, #endif } -/* Draw a point from the vertices in the vertex buffer */ -static __inline void r128_draw_point( r128ContextPtr r128ctx, - r128Vertex *tmp, float sz ) +static __inline void r128_draw_point( r128ContextPtr rmesa, + r128VertexPtr tmp, float sz ) { #if 1 - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 6 ); int j; *(float *)&vb[0] = tmp->v.x - sz; @@ -295,12 +291,12 @@ static __inline void r128_draw_point( r128ContextPtr r128ctx, vb[j] = tmp->ui[j]; #else - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 1 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 1 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -317,4 +313,4 @@ static __inline void r128_draw_point( r128ContextPtr r128ctx, } #endif -#endif /* _R128_TRIS_H_ */ +#endif /* __R128_TRIS_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h index d448493d0..52a63e628 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h @@ -28,38 +28,31 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#if !defined(TAG) || !defined(IND) -this is an error -#endif - -/* Draw a single triangle. Note that the device-dependent vertex data - might need to be changed based on the render state. */ static __inline void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2, GLuint pv ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - r128Vertex *v[3]; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; + r128VertexPtr v[3]; #if (IND & R128_OFFSET_BIT) GLfloat offset; GLfloat z[3]; #endif - #if (IND & R128_TWOSIDE_BIT) GLuint c[3]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; - v[2] = &r128verts[e2]; + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; #if (IND & R128_TWOSIDE_BIT) c[0] = v[0]->ui[4]; @@ -73,13 +66,13 @@ static __inline void TAG(triangle)( GLcontext *ctx, GLfloat ey = v[0]->v.y - v[2]->v.y; GLfloat fx = v[1]->v.x - v[2]->v.x; GLfloat fy = v[1]->v.y - v[2]->v.y; - GLfloat cc = ex*fy - ey*fx; + GLfloat cc = ex*fy - ey*fx; #if (IND & R128_TWOSIDE_BIT) { - GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & R128_FLAT_BIT) { + if ( IND & R128_FLAT_BIT ) { R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; } else { @@ -92,21 +85,21 @@ static __inline void TAG(triangle)( GLcontext *ctx, #if (IND & R128_OFFSET_BIT) { - offset = ctx->Polygon.OffsetUnits * r128ctx->depth_scale; + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; z[0] = v[0]->v.z; z[1] = v[1]->v.z; z[2] = v[2]->v.z; - if (cc * cc > 1e-16) { - GLfloat ez = z[0] - z[2]; - GLfloat fz = z[1] - z[2]; - GLfloat a = ey*fz - ez*fy; - GLfloat b = ez*fx - ex*fz; - GLfloat ic = 1.0 / cc; - GLfloat ac = a * ic; - GLfloat bc = b * ic; - if (ac < 0.0f) ac = -ac; - if (bc < 0.0f) bc = -bc; - offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; } v[0]->v.z += offset; v[1]->v.z += offset; @@ -116,7 +109,7 @@ static __inline void TAG(triangle)( GLcontext *ctx, } #endif - r128_draw_triangle( r128ctx, v[0], v[1], v[2] ); + r128_draw_triangle( rmesa, v[0], v[1], v[2] ); #if (IND & R128_OFFSET_BIT) v[0]->v.z = z[0]; @@ -140,24 +133,23 @@ static void TAG(quad)( GLcontext *ctx, TAG(triangle)( ctx, e0, e1, e3, pv ); TAG(triangle)( ctx, e1, e2, e3, pv ); #else - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - r128Vertex *v[4]; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; + r128VertexPtr v[4]; #if (IND & R128_OFFSET_BIT) GLfloat offset; GLfloat z[4]; #endif - #if (IND & R128_TWOSIDE_BIT) int c[4]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; - v[2] = &r128verts[e2]; - v[3] = &r128verts[e3]; + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + v[3] = &verts[e3]; #if (IND & R128_TWOSIDE_BIT) c[0] = v[0]->ui[4]; @@ -172,42 +164,42 @@ static void TAG(quad)( GLcontext *ctx, GLfloat ey = v[0]->v.y - v[2]->v.y; GLfloat fx = v[1]->v.x - v[2]->v.x; GLfloat fy = v[1]->v.y - v[2]->v.y; - GLfloat cc = ex*fy - ey*fx; + GLfloat cc = ex*fy - ey*fx; #if (IND & R128_TWOSIDE_BIT) { - GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & R128_FLAT_BIT) { - R128_COLOR((char *)&v[0]->ui[4], vbcolor[pv]); + if ( IND & R128_FLAT_BIT ) { + R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; } else { - R128_COLOR((char *)&v[0]->ui[4], vbcolor[e0]); - R128_COLOR((char *)&v[1]->ui[4], vbcolor[e1]); - R128_COLOR((char *)&v[2]->ui[4], vbcolor[e2]); - R128_COLOR((char *)&v[3]->ui[4], vbcolor[e3]); + R128_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + R128_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + R128_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + R128_COLOR( (char *)&v[3]->ui[4], vbcolor[e3] ); } } #endif #if (IND & R128_OFFSET_BIT) { - offset = ctx->Polygon.OffsetUnits * r128ctx->depth_scale; + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; z[0] = v[0]->v.z; z[1] = v[1]->v.z; z[2] = v[2]->v.z; z[3] = v[3]->v.z; - if (cc * cc > 1e-16) { - GLfloat ez = z[0] - z[2]; - GLfloat fz = z[1] - z[2]; - GLfloat a = ey*fz - ez*fy; - GLfloat b = ez*fx - ex*fz; - GLfloat ic = 1.0 / cc; - GLfloat ac = a * ic; - GLfloat bc = b * ic; - if (ac < 0.0f) ac = -ac; - if (bc < 0.0f) bc = -bc; - offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; } v[0]->v.z += offset; v[1]->v.z += offset; @@ -218,7 +210,7 @@ static void TAG(quad)( GLcontext *ctx, } #endif - r128_draw_quad( r128ctx, v[0], v[1], v[2], v[3] ); + r128_draw_quad( rmesa, v[0], v[1], v[2], v[3] ); #if (IND & R128_OFFSET_BIT) v[0]->v.z = z[0]; @@ -237,23 +229,15 @@ static void TAG(quad)( GLcontext *ctx, } -/* Draw a single line. Note that the device-dependent vertex data - * might need to be changed based on the render state. - * - * Polygon offset for GL_LINE triangles is dependent on a harness in - * core mesa setting up LineZoffset on a per-triangle basis. - * - * Twosided lighting for GL_LINE triangles is dependent on the same - * harness. - */ static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint pv ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128VertexPtr r128verts = R128_DRIVER_DATA(ctx->VB)->verts; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; GLfloat width = ctx->Line.Width; - r128Vertex *v[2]; + r128VertexPtr v[2]; #if (IND & R128_OFFSET_BIT) GLfloat offset; @@ -263,8 +247,8 @@ static void TAG(line)( GLcontext *ctx, int c[2]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; + v[0] = &verts[e0]; + v[1] = &verts[e1]; #if (IND & R128_TWOSIDE_BIT) c[0] = v[0]->ui[4]; @@ -274,7 +258,7 @@ static void TAG(line)( GLcontext *ctx, #if (IND & R128_TWOSIDE_BIT) { GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; - if (IND & R128_FLAT_BIT) { + if ( IND & R128_FLAT_BIT ) { R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[1]->ui[4] = v[0]->ui[4]; } else { @@ -285,14 +269,14 @@ static void TAG(line)( GLcontext *ctx, #endif #if (IND & R128_OFFSET_BIT) - offset = ctx->LineZoffset * r128ctx->depth_scale; + offset = ctx->LineZoffset * rmesa->depth_scale; z[0] = v[0]->v.z; z[1] = v[1]->v.z; v[0]->v.z += offset; v[1]->v.z += offset; #endif - r128_draw_line( r128ctx, v[0], v[1], width ); + r128_draw_line( rmesa, v[0], v[1], width ); #if (IND & R128_OFFSET_BIT) v[0]->v.z = z[0]; @@ -303,81 +287,46 @@ static void TAG(line)( GLcontext *ctx, v[0]->ui[4] = c[0]; v[1]->ui[4] = c[1]; #endif - -#if 0 - - - if (IND & (R128_TWOSIDE_BIT|R128_FLAT_BIT|R128_OFFSET_BIT)) { - r128Vertex tmp0 = r128verts[e0]; - r128Vertex tmp1 = r128verts[e1]; - - if (IND & R128_TWOSIDE_BIT) { - GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; - - if (IND & R128_FLAT_BIT) { - R128_COLOR((char *)&tmp0.v.color, vbcolor[pv]); - *(int *)&tmp1.v.color = *(int *)&tmp0.v.color; - } else { - R128_COLOR((char *)&tmp0.v.color, vbcolor[e0]); - R128_COLOR((char *)&tmp1.v.color, vbcolor[e1]); - } - } else if (IND & R128_FLAT_BIT) { - *(int *)&tmp0.v.color = *(int *)&r128verts[pv].v.color; - *(int *)&tmp1.v.color = *(int *)&r128verts[pv].v.color; - } - - if (IND & R128_OFFSET_BIT) { - GLfloat offset = ctx->LineZoffset * r128ctx->depth_scale; - tmp0.v.z += offset; - tmp1.v.z += offset; - } - - r128_draw_line( r128ctx, &tmp0, &tmp1, width ); - } else { - r128_draw_line( r128ctx, &r128verts[e0], &r128verts[e1], width ); - } -#endif } -/* Draw a set of points. Note that the device-dependent vertex data - might need to be changed based on the render state. */ -static void TAG(points)(GLcontext *ctx, - GLuint first, GLuint last) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - GLfloat size = ctx->Point.Size * 0.5; - int i; +static void TAG(points)( GLcontext *ctx, + GLuint first, GLuint last ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; + GLfloat size = ctx->Point.Size * 0.5; + int i; - for(i = first; i < last; i++) { - if(VB->ClipMask[i] == 0) { - if (IND & (R128_TWOSIDE_BIT|R128_OFFSET_BIT)) { - r128Vertex tmp0 = r128verts[i]; + for ( i = first ; i < last ; i++) { + if ( VB->ClipMask[i] == 0 ) { + if ( IND & (R128_TWOSIDE_BIT|R128_OFFSET_BIT) ) { + r128Vertex tmp0 = verts[i]; - if (IND & R128_TWOSIDE_BIT) { + if ( IND & R128_TWOSIDE_BIT ) { GLubyte (*vbcolor)[4] = VB->ColorPtr->data; - R128_COLOR((char *)&tmp0.v.color, vbcolor[i]); + R128_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); } - if (IND & R128_OFFSET_BIT) { - GLfloat offset = ctx->PointZoffset * r128ctx->depth_scale; + if ( IND & R128_OFFSET_BIT ) { + GLfloat offset = ctx->PointZoffset * rmesa->depth_scale; tmp0.v.z += offset; } - r128_draw_point( r128ctx, &tmp0, size ); - } else - r128_draw_point( r128ctx, &r128verts[i], size ); + r128_draw_point( rmesa, &tmp0, size ); + } else { + r128_draw_point( rmesa, &verts[i], size ); + } } } } -/* Initialize the table of primitives to render. */ -static void TAG(init)(void) + +static void TAG(init)( void ) { - rast_tab[IND].triangle = TAG(triangle); - rast_tab[IND].quad = TAG(quad); - rast_tab[IND].line = TAG(line); - rast_tab[IND].points = TAG(points); + rast_tab[IND].points = TAG(points); + rast_tab[IND].line = TAG(line); + rast_tab[IND].triangle = TAG(triangle); + rast_tab[IND].quad = TAG(quad); } #undef IND diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c index 744b3c7c4..3ebacd027 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -78,10 +78,10 @@ do { \ #define TEX0_4 \ do { \ - if (VB->TexCoordPtr[0]->size == 4) { \ + if ( VB->TexCoordPtr[0]->size == 4 ) { \ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ v = &(R128_DRIVER_DATA(VB)->verts[start]); \ - for (i = start; i < end; i++, v++) { \ + for ( i = start ; i < end ; i++, v++ ) { \ float oow = 1.0 / tc[i][3]; \ v->v.rhw *= tc[i][3]; \ v->v.tu0 *= oow; \ @@ -94,10 +94,10 @@ do { \ #define TEX1_4 \ do { \ - if (VB->TexCoordPtr[1]->size == 4) { \ + if ( VB->TexCoordPtr[1]->size == 4 ) { \ GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ v = &(R128_DRIVER_DATA(VB)->verts[start]); \ - for (i = start; i < end; i++, v++) { \ + for ( i = start ; i < end ; i++, v++ ) { \ float oow = 1.0 / tc[i][3]; \ v->v.rhw2 *= tc[i][3]; \ v->v.tu1 *= oow; \ @@ -109,9 +109,9 @@ do { \ #define COORD \ do { \ GLfloat *win = VB->Win.data[i]; \ - v->v.x = win[0] + SUBPIXEL_X; \ - v->v.y = r128height - win[1] + SUBPIXEL_Y; \ - v->v.z = scale * win[2]; \ + v->v.x = win[0] + xoffset; \ + v->v.y = - win[1] + yoffset; \ + v->v.z = depth_scale * win[2]; \ v->v.rhw = v->v.rhw2 = win[3]; \ } while (0) @@ -122,43 +122,44 @@ do { \ #define COORD \ do { \ GLfloat *win = VB->Win.data[i]; \ - v->v.x = win[0] + SUBPIXEL_X; \ - v->v.y = r128height - win[1] + SUBPIXEL_Y; \ - v->v.z = scale * win[2]; \ - v->v.rhw = win[3]; \ + v->v.x = win[0] + xoffset; \ + v->v.y = - win[1] + yoffset; \ + v->v.z = depth_scale * win[2]; \ + v->v.rhw = win[3]; \ } while (0) #endif /* USE_RHW2 */ #define NOP -/* Setup the r128 vertex buffer entries */ + #define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ -static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ +static void name( struct vertex_buffer *VB, GLuint start, GLuint end ) \ { \ - r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ - r128VertexPtr v; \ - GLfloat (*tc0)[4]; \ - GLfloat (*tc1)[4]; \ - GLfloat r128height = dPriv->h; \ - GLfloat scale = r128ctx->depth_scale; \ - int i; \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + r128VertexPtr v; \ + GLfloat (*tc0)[4]; \ + GLfloat (*tc1)[4]; \ + const GLfloat depth_scale = rmesa->depth_scale; \ + const GLfloat xoffset = SUBPIXEL_X; \ + const GLfloat yoffset = dPriv->h + SUBPIXEL_Y; \ + GLint i; \ \ - (void) r128height; (void) r128ctx; (void) scale; \ + (void) xoffset; (void) yoffset; (void) depth_scale; \ \ - gl_import_client_data(VB, VB->ctx->RenderFlags, \ - (VB->ClipOrMask \ - ? VEC_WRITABLE | VEC_GOOD_STRIDE \ - : VEC_GOOD_STRIDE)); \ + gl_import_client_data( VB, VB->ctx->RenderFlags, \ + (VB->ClipOrMask \ + ? VEC_WRITABLE | VEC_GOOD_STRIDE \ + : VEC_GOOD_STRIDE) ); \ \ - tc0 = VB->TexCoordPtr[r128ctx->tmu_source[0]]->data; \ - tc1 = VB->TexCoordPtr[r128ctx->tmu_source[1]]->data; \ + tc0 = VB->TexCoordPtr[rmesa->tmu_source[0]]->data; \ + tc1 = VB->TexCoordPtr[rmesa->tmu_source[1]]->data; \ \ v = &(R128_DRIVER_DATA(VB)->verts[start]); \ \ - if (VB->ClipOrMask == 0) { \ - for (i = start; i < end; i++, v++) { \ + if ( VB->ClipOrMask == 0 ) { \ + for ( i = start ; i < end ; i++, v++ ) { \ win; \ col; \ spec; \ @@ -167,8 +168,8 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ tex1; \ } \ } else { \ - for (i = start; i < end; i++, v++) { \ - if (VB->ClipMask[i] == 0) { \ + for ( i = start ; i < end ; i++, v++ ) { \ + if ( VB->ClipMask[i] == 0 ) { \ win; \ spec; \ fog; \ @@ -221,20 +222,23 @@ SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end ) { - fprintf(stderr, "r128RasterSetup(): invalid setup function\n"); + fprintf( stderr, "r128RasterSetup(): invalid setup function\n" ); } -typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint); -static setupFunc setup_func[0x40]; +typedef void (*setupFunc)( struct vertex_buffer *, GLuint, GLuint ); +static setupFunc setup_func[R128_MAX_SETUPFUNC]; + -/* Initialize the table of vertex buffer setup functions */ void r128DDSetupInit( void ) { - int i; + GLint i; - for (i = 0; i < 0x20; i++) setup_func[i] = rs_invalid; + for ( i = 0 ; i < R128_MAX_SETUPFUNC ; i++ ) { + setup_func[i] = rs_invalid; + } - /* Functions to build vertices from scratch */ + /* Functions to build vertices from scratch + */ setup_func[R128_WIN_BIT|R128_TEX0_BIT] = rs_wt0; setup_func[R128_WIN_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wt0t1; setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wft0; @@ -252,7 +256,8 @@ void r128DDSetupInit( void ) setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgfst0; setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgfst0t1; - /* Repair functions */ + /* Repair functions + */ setup_func[R128_TEX0_BIT] = rs_t0; setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1; setup_func[R128_FOG_BIT] = rs_f; @@ -272,6 +277,7 @@ void r128DDSetupInit( void ) setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gfst0t1; } + void r128PrintSetupFlags( char *msg, GLuint flags ) { fprintf( stderr, "%s: %d %s%s%s%s%s%s\n", @@ -285,29 +291,31 @@ void r128PrintSetupFlags( char *msg, GLuint flags ) (flags & R128_TEX1_BIT) ? " tex-1," : "" ); } + /* Initialize the vertex buffer setup functions based on the current - rendering state */ + * rendering state. + */ void r128DDChooseRasterSetupFunc( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int index = R128_WIN_BIT | R128_RGBA_BIT; - - r128ctx->multitex = 0; - r128ctx->vertsize = 8; - r128ctx->vc_format = R128_TEX0_VERTEX_FORMAT; - r128ctx->tmu_source[0] = 0; - r128ctx->tmu_source[1] = 1; - r128ctx->tex_dest[0] = R128_TEX0_BIT; - r128ctx->tex_dest[1] = R128_TEX1_BIT; - r128ctx->blend_flags &= ~R128_BLEND_MULTITEX; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLint index = R128_WIN_BIT | R128_RGBA_BIT; + + rmesa->multitex = 0; + rmesa->vertsize = 8; + rmesa->vc_format = R128_TEX0_VERTEX_FORMAT; + rmesa->tmu_source[0] = 0; + rmesa->tmu_source[1] = 1; + rmesa->tex_dest[0] = R128_TEX0_BIT; + rmesa->tex_dest[1] = R128_TEX1_BIT; + rmesa->blend_flags &= ~R128_BLEND_MULTITEX; if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { - if ( ctx->Texture.Unit[0].EnvMode == GL_BLEND && - (r128ctx->env_color & 0x00ffffff) ) { - r128ctx->multitex = 1; - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->tmu_source[1] = 0; + if ( R128_IS_PLAIN( rmesa ) && /* Pro/M3 support GL_BLEND */ + ctx->Texture.Unit[0].EnvMode == GL_BLEND && rmesa->env_color ) { + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = R128_TEX1_VERTEX_FORMAT; + rmesa->tmu_source[1] = 0; index |= R128_TEX1_BIT; } @@ -316,23 +324,24 @@ void r128DDChooseRasterSetupFunc( GLcontext *ctx ) if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) { if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { - r128ctx->multitex = 1; - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->blend_flags |= R128_BLEND_MULTITEX; + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = R128_TEX1_VERTEX_FORMAT; + if ( R128_IS_PLAIN( rmesa ) ) /* Pro/M3 support GL_BLEND */ + rmesa->blend_flags |= R128_BLEND_MULTITEX; index |= R128_TEX1_BIT; } else { /* Just a funny way of doing single texturing. */ - r128ctx->tmu_source[0] = 1; - r128ctx->tex_dest[1] = R128_TEX0_BIT; - - if ( ctx->Texture.Unit[1].EnvMode == GL_BLEND && - (r128ctx->env_color & 0x00ffffff) ) { - r128ctx->multitex = 1; - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->tmu_source[1] = 1; + rmesa->tmu_source[0] = 1; + rmesa->tex_dest[1] = R128_TEX0_BIT; + + if ( R128_IS_PLAIN( rmesa ) && /* Pro/M3 support GL_BLEND */ + ctx->Texture.Unit[1].EnvMode == GL_BLEND && rmesa->env_color ) { + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = R128_TEX1_VERTEX_FORMAT; + rmesa->tmu_source[1] = 1; index |= R128_TEX1_BIT; } @@ -351,57 +360,61 @@ void r128DDChooseRasterSetupFunc( GLcontext *ctx ) r128PrintSetupFlags( "full setup function", index ); } - r128ctx->new_state |= R128_NEW_TEXTURE; - r128ctx->SetupIndex = index; + rmesa->new_state |= R128_NEW_TEXTURE; + rmesa->SetupIndex = index; ctx->Driver.RasterSetup = setup_func[index]; } -/* Check to see if any updates of the vertex buffer entries are needed */ +/* Check to see if any updates of the vertex buffer entries are needed. + */ void r128DDCheckPartialRasterSetup( GLcontext *ctx, struct gl_pipeline_stage *s ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int tmp = r128ctx->SetupDone; + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + GLint tmp = rmesa->SetupDone; s->type = 0; - r128ctx->SetupDone = GL_FALSE; + rmesa->SetupDone = 0; - if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return; - if (ctx->IndirectTriangles) return; + if ( (ctx->Array.Summary & VERT_OBJ_ANY) == 0 ) + return; - r128ctx->SetupDone = tmp; -} + if ( ctx->IndirectTriangles ) + return; + rmesa->SetupDone = tmp; +} -/* Update the vertex buffer entries, if necessary */ +/* Repair existing precalculated vertices with new data. + */ void r128DDPartialRasterSetup( struct vertex_buffer *VB ) { - r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); - int new = VB->pipeline->new_outputs; - int available = VB->pipeline->outputs; - int index = 0; + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); + GLuint new = VB->pipeline->new_outputs; + GLuint available = VB->pipeline->outputs; + GLuint index = 0; - if (new & VERT_WIN) { + if ( new & VERT_WIN ) { new = available; index |= R128_WIN_BIT | R128_FOG_BIT; } - if (new & VERT_RGBA) + if ( new & VERT_RGBA ) index |= R128_RGBA_BIT | R128_SPEC_BIT; - if (new & VERT_TEX0_ANY) + if ( new & VERT_TEX0_ANY ) index |= R128_TEX0_BIT; - if (new & VERT_TEX1_ANY) - index |= r128ctx->tex_dest[1]; + if ( new & VERT_TEX1_ANY ) + index |= rmesa->tex_dest[1]; - if (new & VERT_FOG_COORD) + if ( new & VERT_FOG_COORD ) index |= R128_FOG_BIT; - r128ctx->SetupDone &= ~index; - index &= r128ctx->SetupIndex; - r128ctx->SetupDone |= index; + rmesa->SetupDone &= ~index; + index &= rmesa->SetupIndex; + rmesa->SetupDone |= index; if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) r128PrintSetupFlags( "partial setup function", index ); @@ -410,7 +423,6 @@ void r128DDPartialRasterSetup( struct vertex_buffer *VB ) setup_func[index]( VB, VB->Start, VB->Count ); } -/* Perform the raster setup for the fast path, if using CVA */ void r128DDDoRasterSetup( struct vertex_buffer *VB ) { GLcontext *ctx = VB->ctx; @@ -418,87 +430,85 @@ void r128DDDoRasterSetup( struct vertex_buffer *VB ) if ( VB->Type == VB_CVA_PRECALC ) { r128DDPartialRasterSetup( VB ); } else if ( ctx->Driver.RasterSetup ) { - ctx->Driver.RasterSetup( VB, - VB->CopyStart, - VB->Count ); + ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count ); } } -/* Resize an existing vertex buffer */ + +/* ================================================================ + * Hardware-format vertex buffers + */ + void r128DDResizeVB( struct vertex_buffer *VB, GLuint size ) { - r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + r128VertexBufferPtr rvb = R128_DRIVER_DATA(VB); - while ( r128vb->size < size ) - r128vb->size *= 2; + while ( rvb->size < size ) + rvb->size *= 2; - ALIGN_FREE( r128vb->vert_store ); - r128vb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * r128vb->size, 32 ); - if ( !r128vb->vert_store ) { + ALIGN_FREE( rvb->vert_store ); + rvb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); exit( 1 ); } - r128vb->verts = (r128VertexPtr)r128vb->vert_store; + rvb->verts = (r128VertexPtr)rvb->vert_store; - gl_vector1ui_free( &r128vb->clipped_elements ); - gl_vector1ui_alloc( &r128vb->clipped_elements, - VEC_WRITABLE, r128vb->size, 32 ); - if ( !r128vb->clipped_elements.start ) { + gl_vector1ui_free( &rvb->clipped_elements ); + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); exit( 1 ); } ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * r128vb->size, 32 ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); if ( !VB->ClipMask ) { fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); exit( 1 ); } } -/* Create a new device-dependent vertex buffer */ void r128DDRegisterVB( struct vertex_buffer *VB ) { - r128VertexBufferPtr r128vb; + r128VertexBufferPtr rvb; - r128vb = (r128VertexBufferPtr)CALLOC( sizeof(*r128vb) ); + rvb = (r128VertexBufferPtr)CALLOC( sizeof(*rvb) ); - r128vb->size = VB->Size * 2; - r128vb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * r128vb->size, 32 ); - if ( !r128vb->vert_store ) { + rvb->size = VB->Size * 2; + rvb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); exit( 1 ); } - r128vb->verts = (r128VertexPtr)r128vb->vert_store; + rvb->verts = (r128VertexPtr)rvb->vert_store; - gl_vector1ui_alloc( &r128vb->clipped_elements, - VEC_WRITABLE, r128vb->size, 32 ); - if ( !r128vb->clipped_elements.start ) { + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); exit( 1 ); } ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * r128vb->size, 32 ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); if ( !VB->ClipMask ) { fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); exit( 1 ); } - VB->driver_data = r128vb; + VB->driver_data = rvb; } -/* Destroy a device-dependent vertex buffer */ void r128DDUnregisterVB( struct vertex_buffer *VB ) { - r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + r128VertexBufferPtr rvb = R128_DRIVER_DATA(VB); - if ( r128vb ) { - if ( r128vb->vert_store ) ALIGN_FREE( r128vb->vert_store ); - gl_vector1ui_free( &r128vb->clipped_elements ); - FREE( r128vb ); + if ( rvb ) { + if ( rvb->vert_store ) ALIGN_FREE( rvb->vert_store ); + gl_vector1ui_free( &rvb->clipped_elements ); + FREE( rvb ); VB->driver_data = 0; } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h index f1afdff2c..2e33dcc1b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h @@ -28,80 +28,78 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_VB_H_ -#define _R128_VB_H_ +#ifndef __R128_VB_H__ +#define __R128_VB_H__ #ifdef GLX_DIRECT_RENDERING /* FIXME: This is endian-specific */ typedef struct { - GLubyte blue; - GLubyte green; - GLubyte red; - GLubyte alpha; + GLubyte blue; + GLubyte green; + GLubyte red; + GLubyte alpha; } r128_color_t; /* The vertex structure. The final tu1/tv1 values are only used in * multitexture modes, and the rhw2 value is currently never used. */ typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - GLfloat rhw; /* Reciprocal homogeneous w */ - r128_color_t color; /* Diffuse color */ - r128_color_t specular; /* Specular color (alpha is fog) */ - GLfloat tu0, tv0; /* Texture 0 coordinates */ - GLfloat tu1, tv1; /* Texture 1 coordinates */ - GLfloat rhw2; /* Reciprocal homogeneous w2 */ + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + r128_color_t color; /* Diffuse color */ + r128_color_t specular; /* Specular color (alpha is fog) */ + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ + GLfloat rhw2; /* Reciprocal homogeneous w2 */ } r128_vertex; -/* Format of vertices in r128_vertex struct */ -#define R128_TEX0_VERTEX_FORMAT \ - R128_CCE_VC_FRMT_RHW | \ - R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ - R128_CCE_VC_FRMT_SPEC_FRGB | \ - R128_CCE_VC_FRMT_S_T - -#define R128_TEX1_VERTEX_FORMAT \ - R128_CCE_VC_FRMT_RHW | \ - R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ - R128_CCE_VC_FRMT_SPEC_FRGB | \ - R128_CCE_VC_FRMT_S_T | \ - R128_CCE_VC_FRMT_S2_T2 - -#define R128_PROJ_TEX1_VERTEX_FORMAT \ - R128_CCE_VC_FRMT_RHW | \ - R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ - R128_CCE_VC_FRMT_SPEC_FRGB | \ - R128_CCE_VC_FRMT_S_T | \ - R128_CCE_VC_FRMT_S2_T2 | \ - R128_CCE_VC_FRMT_RHW2 - - -/* FIXME: We currently only have assembly for 16-stride vertices */ +/* Format of vertices in r128_vertex struct: + */ +#define R128_TEX0_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T) + +#define R128_TEX1_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T | \ + R128_CCE_VC_FRMT_S2_T2) + +#define R128_PROJ_TEX1_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T | \ + R128_CCE_VC_FRMT_S2_T2 | \ + R128_CCE_VC_FRMT_RHW2) + + +/* The fastpath code still expects a 16-float stride vertex. + */ union r128_vertex_t { - r128_vertex v; - GLfloat f[16]; - CARD32 ui[16]; + r128_vertex v; + GLfloat f[16]; + GLuint ui[16]; }; typedef union r128_vertex_t r128Vertex; typedef union r128_vertex_t *r128VertexPtr; -/* Vertex buffer for use when on the fast path */ typedef struct { - GLuint size; /* Number of vertices in store */ - void *vert_store; /* Storage for vertex buffer */ - r128VertexPtr verts; /* Aligned start of verts in storage */ - int last_vert; /* Index of last vertex used */ - GLvector1ui clipped_elements; /* List of clipped elements */ + r128VertexPtr verts; + GLvector1ui clipped_elements; + GLint last_vert; + void *vert_store; + GLuint size; } *r128VertexBufferPtr; -#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data)) +#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data)) #define R128_WIN_BIT 0x01 #define R128_RGBA_BIT 0x02 @@ -109,20 +107,21 @@ typedef struct { #define R128_SPEC_BIT 0x08 #define R128_TEX0_BIT 0x10 #define R128_TEX1_BIT 0x20 - -extern void r128DDSetupInit( void ); +#define R128_MAX_SETUPFUNC 0x40 extern void r128DDChooseRasterSetupFunc( GLcontext *ctx ); extern void r128PrintSetupFlags( char *msg, GLuint flags ); extern void r128DDCheckPartialRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *s ); -extern void r128DDPartialRasterSetup(struct vertex_buffer *VB); -extern void r128DDDoRasterSetup(struct vertex_buffer *VB); + struct gl_pipeline_stage *s ); +extern void r128DDPartialRasterSetup( struct vertex_buffer *VB ); +extern void r128DDDoRasterSetup( struct vertex_buffer *VB ); -extern void r128DDResizeVB(struct vertex_buffer *VB, GLuint size); -extern void r128DDRegisterVB(struct vertex_buffer *VB); -extern void r128DDUnregisterVB(struct vertex_buffer *VB); +extern void r128DDResizeVB( struct vertex_buffer *VB, GLuint size ); +extern void r128DDRegisterVB( struct vertex_buffer *VB ); +extern void r128DDUnregisterVB( struct vertex_buffer *VB ); + +extern void r128DDSetupInit( void ); #endif -#endif /* _R128_VB_H_ */ +#endif /* __R128_VB_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c index 07450e3c0..31ba8afba 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c @@ -48,42 +48,45 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void __driRegisterExtensions( void ); -static r128ContextPtr r128Context = NULL; +static r128ContextPtr r128Ctx = NULL; -/* Initialize the driver specific screen private data */ -GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) +/* Initialize the driver specific screen private data. + */ +GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) { - sPriv->private = (void *)r128CreateScreen(sPriv); - if (!sPriv->private) { - r128DestroyScreen(sPriv); - return GL_FALSE; - } + sPriv->private = (void *) r128CreateScreen( sPriv ); + if ( !sPriv->private ) { + r128DestroyScreen( sPriv ); + return GL_FALSE; + } - return GL_TRUE; + return GL_TRUE; } -/* Reset the driver specific screen private data */ -void XMesaResetDriver(__DRIscreenPrivate *sPriv) +/* Reset the driver specific screen private data. + */ +void XMesaResetDriver( __DRIscreenPrivate *sPriv ) { - r128DestroyScreen(sPriv); + r128DestroyScreen( sPriv ); } -/* Create and initialize the Mesa and driver specific visual data */ -GLvisual *XMesaCreateVisual(Display *dpy, - __DRIscreenPrivate *driScrnPriv, - const XVisualInfo *visinfo, - const __GLXvisualConfig *config) +/* Create and initialize the Mesa and driver specific visual data. + */ +GLvisual *XMesaCreateVisual( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config ) { - /* Drivers may change the args to _mesa_create_visual() in order to - * setup special visuals. + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. */ - return _mesa_create_visual(config->rgba, + return _mesa_create_visual( config->rgba, config->doubleBuffer, config->stereo, - _mesa_bitcount(visinfo->red_mask), - _mesa_bitcount(visinfo->green_mask), - _mesa_bitcount(visinfo->blue_mask), + _mesa_bitcount( visinfo->red_mask ), + _mesa_bitcount( visinfo->green_mask ), + _mesa_bitcount( visinfo->blue_mask ), config->alphaSize, 0, /* index bits */ config->depthSize, @@ -92,134 +95,186 @@ GLvisual *XMesaCreateVisual(Display *dpy, config->accumGreenSize, config->accumBlueSize, config->accumAlphaSize, - 0 /* num samples */); + 0 /* num samples */ ); } -/* Create and initialize the Mesa and driver specific context data */ -GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis, - __DRIcontextPrivate *driContextPriv) +/* Create and initialize the Mesa and driver specific context data. + */ +GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) { - return r128CreateContext(dpy, mesaVis, driContextPriv); + return r128CreateContext( dpy, mesaVis, driContextPriv ); } -/* Destroy the Mesa and driver specific context data */ +/* Destroy the Mesa and driver specific context data. + */ void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { - r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; - if (r128ctx == (void *)r128Context) r128Context = NULL; - r128DestroyContext(r128ctx); + if ( rmesa == r128Ctx ) r128Ctx = NULL; + r128DestroyContext(rmesa); } -/* Create and initialize the Mesa and driver specific pixmap buffer data */ -GLframebuffer *XMesaCreateWindowBuffer(Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis ) { - return gl_create_framebuffer(mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, - mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 - ); + return gl_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 ); } -/* Create and initialize the Mesa and driver specific pixmap buffer data */ +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, __DRIscreenPrivate *driScrnPriv, __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) + GLvisual *mesaVis ) { #if 0 - /* Different drivers may have different combinations of hardware and - * software ancillary buffers. - */ - return gl_create_framebuffer(mesaVis, + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer( mesaVis, GL_FALSE, /* software depth buffer? */ mesaVis->StencilBits > 0, mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0); + mesaVis->AlphaBits > 0 ); #else - return NULL; /* not implemented yet */ + return NULL; /* not implemented yet */ #endif } /* Copy the back color buffer to the front color buffer */ -void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) +void XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) { - /* FIXME: This assumes buffer is currently bound to a context. This - needs to be able to swap buffers when not currently bound. Also, - this needs to swap according to buffer, and NOT according to - context! */ - if (r128Context == NULL) return; - - /* Only swap buffers when a back buffer exists */ - if (R128_MESACTX(r128Context)->Visual->DBflag) { - FLUSH_VB(R128_MESACTX(r128Context), "swap buffers"); - r128SwapBuffers(r128Context); - } + /* FIXME: This assumes buffer is currently bound to a context. This + * needs to be able to swap buffers when not currently bound. Also, + * this needs to swap according to buffer, and NOT according to + * context! + */ + if ( r128Ctx == NULL ) + return; + + /* Only swap buffers when a back buffer exists. + */ + if ( r128Ctx->glCtx->Visual->DBflag ) { + FLUSH_VB( r128Ctx->glCtx, "swap buffers" ); + if ( !r128Ctx->doPageFlip ) { + r128SwapBuffers( r128Ctx ); + } else { + r128PageFlip( r128Ctx ); + } + } } /* Force the context `c' to be the current context and associate with it - buffer `b' */ -GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) + * buffer `b'. + */ +GLboolean XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) { - if (driContextPriv) { - r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; - - r128Context = r128MakeCurrent(r128Context, r128ctx, driDrawPriv); - - gl_make_current2(R128_MESACTX(r128Context), - driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); - - if (r128Context->driDrawable != driDrawPriv) { - r128Context->driDrawable = driDrawPriv; - r128Context->dirty = R128_UPLOAD_ALL; - } - - /* GH: We need this to correctly calculate the window offset - * and aux scissor rects. - */ - r128Context->new_state = R128_NEW_WINDOW | R128_NEW_CLIP; - - if (!R128_MESACTX(r128Context)->Viewport.Width) { - gl_Viewport(R128_MESACTX(r128Context), 0, 0, - driDrawPriv->w, driDrawPriv->h); - } - } else { - gl_make_current(0,0); - r128Context = NULL; - } - - return GL_TRUE; + if ( driContextPriv ) { + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + + r128Ctx = r128MakeCurrent( r128Ctx, rmesa, driDrawPriv ); + + gl_make_current2( r128Ctx->glCtx, + driDrawPriv->mesaBuffer, + driReadPriv->mesaBuffer ); + + if ( r128Ctx->driDrawable != driDrawPriv ) { + r128Ctx->driDrawable = driDrawPriv; + r128Ctx->dirty = R128_UPLOAD_ALL; + } + + /* GH: We need this to correctly calculate the window offset + * and aux scissor rects. + */ + r128Ctx->new_state = R128_NEW_WINDOW | R128_NEW_CLIP; + + if ( !r128Ctx->glCtx->Viewport.Width ) { + gl_Viewport( r128Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); + } + } else { + gl_make_current( 0, 0 ); + r128Ctx = NULL; + } + + return GL_TRUE; } -/* Force the context `c' to be unbound from its buffer */ -GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; + return GL_TRUE; } /* This function is called by libGL.so as soon as libGL.so is loaded. - * This is where we'd register new extension functions with the dispatcher. + * This is where we'd register new extension functions with the + * dispatcher. */ void __driRegisterExtensions( void ) { } +/* Initialize the fullscreen mode. + */ GLboolean -XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) +XMesaOpenFullScreen( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + GLint ret; + + /* FIXME: Do we need to check this? + */ + if ( !r128Ctx->glCtx->Visual->DBflag ) + return GL_TRUE; + + LOCK_HARDWARE( rmesa ); + r128WaitForIdleLocked( rmesa ); + + /* Ignore errors. If this fails, we simply don't do page flipping. + */ + ret = drmR128FullScreen( rmesa->driFd, GL_TRUE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = ( ret == 0 ); + + return GL_TRUE; } +/* Shut down the fullscreen mode. + */ GLboolean -XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) +XMesaCloseFullScreen( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + + LOCK_HARDWARE( rmesa ); + r128WaitForIdleLocked( rmesa ); + + /* Don't care if this fails, we're not page flipping anymore. + */ + drmR128FullScreen( rmesa->driFd, GL_FALSE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = GL_FALSE; + rmesa->currentPage = 0; + + return GL_TRUE; } #endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile new file mode 100644 index 000000000..10e71732a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile @@ -0,0 +1,381 @@ +XCOMM $XFree86$ + +#include <Threads.tmpl> + +#define DoNormalLib NormalLibGlx +#define DoSharedLib SharedLibGlx +#define DoExtraLib SharedLibGlx +#define DoDebugLib DebugLibGlx +#define DoProfileLib ProfileLibGlx + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + +#ifdef i386Architecture +#ifdef MesaUse3DNow + 3DNOW_DEFS = -DUSE_3DNOW_ASM +#endif +#ifdef MesaUseKatmai + KATMAI_DEFS = -DUSE_KATMAI_ASM +#endif + ASM_DEFINES = -DUSE_X86_ASM -DUSE_MMX_ASM $(3DNOW_DEFS) $(KATMAI_DEFS) +#endif + +#if BuildXF86DRI + DRI_DEFINES = GlxDefines -DDRIVERTS + DRI_INCLUDES = -I../../../../dri \ + -I../../../../glx \ + -I../../../dri \ + -I$(TOP)/include \ + -I$(TOP)/include/GL \ + -I$(XF86OSSRC) \ + -I$(XF86COMSRC) \ + -I$(SERVERSRC)/GL/dri \ + -I$(XF86DRIVERSRC)/ati \ + -I../../../include \ + -I../.. \ + -I../../X \ + -I../common +#endif + +MESA_INCLUDES = -I. -I.. -I../../include \ + -I../../../../dri/drm + + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFINES) + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + + RADEONSRCS = radeon_context.c \ + radeon_dd.c \ + radeon_fastpath.c \ + radeon_eltpath.c \ + radeon_ioctl.c \ + radeon_lock.c \ + radeon_pipeline.c \ + radeon_screen.c \ + radeon_span.c \ + radeon_state.c \ + radeon_tex.c \ + radeon_tris.c \ + radeon_vb.c \ + radeon_xmesa.c + + RADEONOBJS = radeon_context.o \ + radeon_dd.o \ + radeon_fastpath.o \ + radeon_eltpath.o \ + radeon_ioctl.o \ + radeon_lock.o \ + radeon_pipeline.o \ + radeon_screen.o \ + radeon_span.o \ + radeon_state.o \ + radeon_tex.o \ + radeon_tris.o \ + radeon_vb.o \ + radeon_xmesa.o + +#if !GlxUseBuiltInDRIDriver + DRISRCS = ../../../dri/dri_mesa.c \ + ../../../../dri/dri_tmm.c + + DRIOBJS = ../../../dri/dri_mesa.o \ + ../../../../dri/dri_tmm.o + + DRMSRCS = ../../../../dri/drm/xf86drm.c \ + ../../../../dri/drm/xf86drmHash.c \ + ../../../../dri/drm/xf86drmRandom.c \ + ../../../../dri/drm/xf86drmSL.c \ + ../../../../dri/drm/xf86drmRadeon.c + + DRMOBJS = ../../../../dri/drm/xf86drm.o \ + ../../../../dri/drm/xf86drmHash.o \ + ../../../../dri/drm/xf86drmRandom.o \ + ../../../../dri/drm/xf86drmSL.o \ + ../../../../dri/drm/xf86drmRadeon.o + + MESASRCS = ../../aatriangle.c \ + ../../accum.c \ + ../../alpha.c \ + ../../alphabuf.c \ + ../../attrib.c \ + ../../bbox.c \ + ../../bitmap.c \ + ../../blend.c \ + ../../buffers.c \ + ../../clip.c \ + ../../colortab.c \ + ../../config.c \ + ../../context.c \ + ../../copypix.c \ + ../../cva.c \ + ../../debug_xform.c \ + ../../depth.c \ + ../../dlist.c \ + ../../drawpix.c \ + ../../enable.c \ + ../../enums.c \ + ../../eval.c \ + ../../extensions.c \ + ../../feedback.c \ + ../../fog.c \ + ../../get.c \ + ../../glapi.c \ + ../../glapinoop.c \ + ../../glthread.c \ + ../../hash.c \ + ../../image.c \ + ../../imaging.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.c \ + ../../points.c \ + ../../polygon.c \ + ../../quads.c \ + ../../rastpos.c \ + ../../readpix.c \ + ../../rect.c \ + ../../scissor.c \ + ../../shade.c \ + ../../span.c \ + ../../stages.c \ + ../../state.c \ + ../../stencil.c \ + ../../teximage.c \ + ../../texobj.c \ + ../../texstate.c \ + ../../texture.c \ + ../../texutil.c \ + ../../translate.c \ + ../../triangle.c \ + ../../varray.c \ + ../../vb.c \ + ../../vbcull.c \ + ../../vbfill.c \ + ../../vbindirect.c \ + ../../vbrender.c \ + ../../vbxform.c \ + ../../vector.c \ + ../../vertices.c \ + ../../winpos.c \ + ../../xform.c \ + ../../zoom.c + + MESAOBJS = ../../aatriangle.o \ + ../../accum.o \ + ../../alpha.o \ + ../../alphabuf.o \ + ../../attrib.o \ + ../../bbox.o \ + ../../bitmap.o \ + ../../blend.o \ + ../../buffers.o \ + ../../clip.o \ + ../../colortab.o \ + ../../config.o \ + ../../context.o \ + ../../copypix.o \ + ../../cva.o \ + ../../debug_xform.o \ + ../../depth.o \ + ../../dlist.o \ + ../../drawpix.o \ + ../../enable.o \ + ../../enums.o \ + ../../eval.o \ + ../../extensions.o \ + ../../feedback.o \ + ../../fog.o \ + ../../get.o \ + ../../hash.o \ + ../../hint.o \ + ../../image.o \ + ../../imaging.o \ + ../../light.o \ + ../../lines.o \ + ../../logic.o \ + ../../masking.o \ + ../../matrix.o \ + ../../mem.o \ + ../../mmath.o \ + ../../pb.o \ + ../../pipeline.o \ + ../../pixel.o \ + ../../pixeltex.o \ + ../../points.o \ + ../../polygon.o \ + ../../quads.o \ + ../../rastpos.o \ + ../../readpix.o \ + ../../rect.o \ + ../../scissor.o \ + ../../shade.o \ + ../../span.o \ + ../../stages.o \ + ../../state.o \ + ../../stencil.o \ + ../../teximage.o \ + ../../texobj.o \ + ../../texstate.o \ + ../../texture.o \ + ../../texutil.o \ + ../../translate.o \ + ../../triangle.o \ + ../../varray.o \ + ../../vb.o \ + ../../vbcull.o \ + ../../vbfill.o \ + ../../vbindirect.o \ + ../../vbrender.o \ + ../../vbxform.o \ + ../../vector.o \ + ../../vertices.o \ + ../../winpos.o \ + ../../xform.o \ + ../../zoom.o + +#ifdef i386Architecture + X86_SRCS = ../../X86/common_x86.c \ + ../../X86/common_x86_asm.S \ + ../../X86/x86.c \ + ../../X86/x86_cliptest.S \ + ../../X86/x86_vertex.S \ + ../../X86/x86_xform_masked2.S \ + ../../X86/x86_xform_masked3.S \ + ../../X86/x86_xform_masked4.S \ + ../../X86/x86_xform_raw2.S \ + ../../X86/x86_xform_raw3.S \ + ../../X86/x86_xform_raw4.S + + X86_OBJS = ../../X86/common_x86.o \ + ../../X86/common_x86_asm.o \ + ../../X86/x86.o \ + ../../X86/x86_cliptest.o \ + ../../X86/x86_vertex.o \ + ../../X86/x86_xform_masked2.o \ + ../../X86/x86_xform_masked3.o \ + ../../X86/x86_xform_masked4.o \ + ../../X86/x86_xform_raw2.o \ + ../../X86/x86_xform_raw3.o \ + ../../X86/x86_xform_raw4.o + + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o + +#ifdef MesaUse3DNow + 3DNOW_SRCS = ../../X86/3dnow.c \ + ../../X86/3dnow_norm_raw.S \ + ../../X86/3dnow_vertex.S \ + ../../X86/3dnow_xform_masked1.S \ + ../../X86/3dnow_xform_masked2.S \ + ../../X86/3dnow_xform_masked3.S \ + ../../X86/3dnow_xform_masked4.S \ + ../../X86/3dnow_xform_raw1.S \ + ../../X86/3dnow_xform_raw2.S \ + ../../X86/3dnow_xform_raw3.S \ + ../../X86/3dnow_xform_raw4.S + + 3DNOW_OBJS = ../../X86/3dnow.o \ + ../../X86/3dnow_norm_raw.o \ + ../../X86/3dnow_vertex.o \ + ../../X86/3dnow_xform_masked1.o \ + ../../X86/3dnow_xform_masked2.o \ + ../../X86/3dnow_xform_masked3.o \ + ../../X86/3dnow_xform_masked4.o \ + ../../X86/3dnow_xform_raw1.o \ + ../../X86/3dnow_xform_raw2.o \ + ../../X86/3dnow_xform_raw3.o \ + ../../X86/3dnow_xform_raw4.o +#endif + +#ifdef MesaUseKatmai + KATMAI_SRCS = ../../X86/katmai.c \ + ../../X86/katmai_norm_raw.S \ + ../../X86/katmai_vertex.S \ + ../../X86/katmai_xform_masked1.S \ + ../../X86/katmai_xform_masked2.S \ + ../../X86/katmai_xform_masked3.S \ + ../../X86/katmai_xform_masked4.S \ + ../../X86/katmai_xform_raw1.S \ + ../../X86/katmai_xform_raw2.S \ + ../../X86/katmai_xform_raw3.S \ + ../../X86/katmai_xform_raw4.S + + KATMAI_OBJS = ../../X86/katmai.o \ + ../../X86/katmai_norm_raw.o \ + ../../X86/katmai_vertex.o \ + ../../X86/katmai_xform_masked1.o \ + ../../X86/katmai_xform_masked2.o \ + ../../X86/katmai_xform_masked3.o \ + ../../X86/katmai_xform_masked4.o \ + ../../X86/katmai_xform_raw1.o \ + ../../X86/katmai_xform_raw2.o \ + ../../X86/katmai_xform_raw3.o \ + ../../X86/katmai_xform_raw4.o +#endif +#endif +#endif + +#ifdef GlxSoProf + LOSRCS = ../../../../lowpc.c + HISRCS = ../../../../highpc.c + + LOOBJS = ../../../../lowpc.o + HIOBJS = ../../../../highpc.o +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) $(KATMAI_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) $(KATMAI_OBJS) + + COMMONSRCS = ../common/mm.c ../common/hwlog.c + COMMONOBJS = ../common/mm.o ../common/hwlog.o + + SRCS = $(LOSRCS) $(DRISRCS) $(DRMSRCS) $(MESASRCS) \ + $(ASMSRCS) $(COMMONSRCS) $(RADEONSRCS) $(HISRCS) + OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) \ + $(ASMOBJS) $(COMMONOBJS) $(RADEONOBJS) $(HIOBJS) + +REQUIREDLIBS += MathLibrary +#if !GlxBuiltInRadeon +REQUIREDLIBS += -L../../../.. -lGL +#endif + + +#if !GlxUseBuiltInDRIDriver +#undef DoNormalLib NormalLibGlx +#undef DoExtraLib SharedLibGlx +#undef DoDebugLib DebugLibGlx +#undef DoProfileLib ProfileLibGlx +#endif + +#include <Library.tmpl> + +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +#if !GlxUseBuiltInDRIDriver +LIBNAME = radeon_dri.so +ALL_OBJS = $(OBJS) +ALL_DEPS = DONE +SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) + +#ifdef GlxSoProf +SOPROF_LIBNAME = _radeon_dri_p +NormalDepLibraryTarget($(SOPROF_LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallLibrary($(SOPROF_LIBNAME),$(MODULEDIR)/dri) +#endif +#endif + +DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c new file mode 100644 index 000000000..2ead8e213 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -0,0 +1,234 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include <stdlib.h> + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_dd.h" +#include "radeon_state.h" +#include "radeon_span.h" +#include "radeon_tex.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "context.h" +#include "simple_list.h" +#include "mem.h" + +#ifndef RADEON_DEBUG +int RADEON_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_API */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_VERBOSE_LRU */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VERBOSE_IOCTL */ +/* | DEBUG_VERBOSE_2D */ + ); +#endif + +/* Create the device specific context. + */ +GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ) +{ + GLcontext *ctx = driContextPriv->mesaContext; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + radeonContextPtr rmesa; + radeonScreenPtr radeonScreen; + int i; + + rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) return GL_FALSE; + + rmesa->glCtx = ctx; + rmesa->display = dpy; + + rmesa->driContext = driContextPriv; + rmesa->driScreen = sPriv; + rmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + + rmesa->hHWContext = driContextPriv->hHWContext; + rmesa->driHwLock = &sPriv->pSAREA->lock; + rmesa->driFd = sPriv->fd; + + radeonScreen = rmesa->radeonScreen = (radeonScreenPtr)(sPriv->private); + + rmesa->sarea = (RADEONSAREAPrivPtr)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); + + rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + if ( !rmesa->tmp_matrix ) { + FREE( rmesa ); + return GL_FALSE; + } + + make_empty_list( &rmesa->SwappedOut ); + + for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) { + rmesa->CurrentTexObj[i] = NULL; + make_empty_list( &rmesa->TexObjList[i] ); + rmesa->texHeap[i] = mmInit( 0, radeonScreen->texSize[i] ); + rmesa->lastTexAge[i] = -1; + } + rmesa->lastTexHeap = radeonScreen->numTexHeaps; + + rmesa->RenderIndex = -1; /* Impossible value */ + rmesa->OnFastPath = 0; + + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + rmesa->elt_buf = NULL; + rmesa->retained_buf = NULL; + rmesa->vert_heap = radeonScreen->buffers->list->address; + + /* KW: Set the maximum texture size small enough that we can + * guarentee that both texture units can bind a maximal texture + * and have them both in on-card memory at once. (Kevin or + * Gareth: Please check these numbers are OK) + */ + if ( radeonScreen->texSize[0] < 2*1024*1024 ) { + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = (1 << 8); + } else if ( radeonScreen->texSize[0] < 8*1024*1024 ) { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = (1 << 9); + } else { + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = (1 << 10); + } + + /* FIXME: Support all available texture units... */ + ctx->Const.MaxTextureUnits = 2; + +#if ENABLE_PERF_BOXES + if (getenv("LIBGL_PERFORMANCE_BOXES")) + rmesa->boxes = 1; + else + rmesa->boxes = 0; +#endif + + ctx->DriverCtx = (void *)rmesa; + + radeonDDInitExtensions( ctx ); + + radeonDDInitDriverFuncs( ctx ); + radeonDDInitIoctlFuncs( ctx ); + radeonDDInitStateFuncs( ctx ); + radeonDDInitSpanFuncs( ctx ); + radeonDDInitTextureFuncs( ctx ); + + ctx->Driver.TriangleCaps = (DD_TRI_CULL | + DD_TRI_LIGHT_TWOSIDE | + DD_TRI_STIPPLE | + DD_TRI_OFFSET); + + /* Ask Mesa to clip fog coordinates for us. + */ + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; + + if ( ctx->VB ) + radeonDDRegisterVB( ctx->VB ); + + if ( ctx->NrPipelineStages ) { + ctx->NrPipelineStages = + radeonDDRegisterPipelineStages( ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages ); + } + + radeonDDInitState( rmesa ); + + driContextPriv->driverPrivate = (void *)rmesa; + + return GL_TRUE; +} + +/* Destroy the device specific context. + */ +void radeonDestroyContext( radeonContextPtr rmesa ) +{ + if ( rmesa ) { + radeonTexObjPtr t, next_t; + int i; + + for ( i = 0 ; i < rmesa->radeonScreen->numTexHeaps ; i++ ) { + foreach_s ( t, next_t, &rmesa->TexObjList[i] ) { + radeonDestroyTexObj( rmesa, t ); + } + mmDestroy( rmesa->texHeap[i] ); + } + + foreach_s ( t, next_t, &rmesa->SwappedOut ) { + radeonDestroyTexObj( rmesa, t ); + } + + ALIGN_FREE( rmesa->tmp_matrix ); + FREE( rmesa ); + } + +#if 0 + /* Use this to force shared object profiling. */ + glx_fini_prof(); +#endif +} + +/* Load the device specific context into the hardware. The actual + * setting of the hardware state is done in the radeonUpdateHWState(). + */ +radeonContextPtr radeonMakeCurrent( radeonContextPtr oldCtx, + radeonContextPtr newCtx, + __DRIdrawablePrivate *dPriv ) +{ + if ( oldCtx ) { + if ( oldCtx != newCtx ) { + newCtx->new_state |= RADEON_NEW_CONTEXT; + newCtx->dirty = RADEON_UPLOAD_ALL; + } + if ( oldCtx->driDrawable != dPriv ) { + newCtx->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + } + } else { + newCtx->new_state |= RADEON_NEW_CONTEXT; + newCtx->dirty = RADEON_UPLOAD_ALL; + } + + newCtx->driDrawable = dPriv; + + return newCtx; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h new file mode 100644 index 000000000..be3fef41e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -0,0 +1,253 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_CONTEXT_H__ +#define __RADEON_CONTEXT_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include <X11/Xlibint.h> + +#include "dri_mesaint.h" +#include "dri_tmm.h" + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +#include "types.h" + +#include "radeon_sarea.h" +#include "radeon_reg.h" + +struct radeon_context; +typedef struct radeon_context radeonContextRec; +typedef struct radeon_context *radeonContextPtr; + +#include "radeon_lock.h" +#include "radeon_texobj.h" +#include "radeon_screen.h" + +/* Flags for what context state needs to be updated */ +#define RADEON_NEW_ALPHA 0x0001 +#define RADEON_NEW_DEPTH 0x0002 +#define RADEON_NEW_FOG 0x0004 +#define RADEON_NEW_CLIP 0x0008 +#define RADEON_NEW_CULL 0x0010 +#define RADEON_NEW_MASKS 0x0020 +#define RADEON_NEW_WINDOW 0x0040 +#define RADEON_NEW_TEXTURE 0x0080 +#define RADEON_NEW_CONTEXT 0x0100 +#define RADEON_NEW_ALL 0x01ff + +/* Flags for software fallback cases */ +#define RADEON_FALLBACK_TEXTURE 0x0001 +#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +#define RADEON_FALLBACK_READ_BUFFER 0x0004 +#define RADEON_FALLBACK_STENCIL 0x0008 +#define RADEON_FALLBACK_RENDER_MODE 0x0010 +#define RADEON_FALLBACK_MULTIDRAW 0x0020 +#define RADEON_FALLBACK_LOGICOP 0x0040 + +typedef void (*radeon_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); + +struct radeon_elt_tab { + void (*emit_unclipped_verts)( struct vertex_buffer *VB ); + + void (*build_tri_verts)( radeonContextPtr rmesa, + struct vertex_buffer *VB, + GLfloat *O, GLuint *elt ); + + void (*interp)( GLfloat t, GLfloat *O, + const GLfloat *I, const GLfloat *J ); + + void (*project_and_emit_verts)( radeonContextPtr rmesa, + const GLfloat *verts, + GLuint *elts, + GLuint nr ); +}; + +struct radeon_context { + GLcontext *glCtx; /* Mesa context */ + + /* Driver and hardware state management + */ + GLuint new_state; + GLuint dirty; /* Hardware state to be updated */ + radeon_context_regs_t setup; + + GLuint vertsize; + GLuint vc_format; + GLfloat depth_scale; + + CARD32 Color; /* Current draw color */ + CARD32 ClearColor; /* Color used to clear color buffer */ + CARD32 ClearDepth; /* Value used to clear depth buffer */ + CARD32 ClearStencil; /* Value used to clear stencil */ + + /* Map GL texture units onto hardware + */ + GLint multitex; + GLint tmu_source[RADEON_MAX_TEXTURE_UNITS]; + GLint tex_dest[RADEON_MAX_TEXTURE_UNITS]; + GLuint color_combine[RADEON_MAX_TEXTURE_UNITS]; + GLuint alpha_combine[RADEON_MAX_TEXTURE_UNITS]; + GLuint env_color[RADEON_MAX_TEXTURE_UNITS]; + GLuint lod_bias[RADEON_MAX_TEXTURE_UNITS]; + + /* Texture object bookkeeping + */ + radeonTexObjPtr CurrentTexObj[RADEON_MAX_TEXTURE_UNITS]; + radeonTexObj TexObjList[RADEON_NR_TEX_HEAPS]; + radeonTexObj SwappedOut; + memHeap_t *texHeap[RADEON_NR_TEX_HEAPS]; + GLint lastTexAge[RADEON_NR_TEX_HEAPS]; + GLint lastTexHeap; + + /* Current rendering state, fallbacks + */ + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + + GLuint IndirectTriangles; + GLuint Fallback; + + /* Fast path + */ + GLuint SetupIndex; + GLuint SetupDone; + GLuint RenderIndex; + GLuint OnFastPath; + radeon_interp_func interp; + GLfloat *tmp_matrix; + + /* Vertex buffers + */ + drmBufPtr vert_buf; + GLuint vert_prim; + GLuint num_verts; + + /* Elt path + */ + drmBufPtr elt_buf, retained_buf; + GLushort *first_elt, *next_elt; + GLfloat *next_vert, *vert_heap; + GLushort next_vert_index; + GLushort first_vert_index; + GLuint elt_vertsize; + struct radeon_elt_tab *elt_tab; + GLfloat device_matrix[16]; + + /* Page flipping + */ + GLuint doPageFlip; + GLuint currentPage; + + /* Drawable, cliprect and scissor information + */ + GLenum DrawBuffer; /* Optimize draw buffer update */ + GLint drawOffset, drawPitch; + GLint readOffset, readPitch; + + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + + GLuint scissor; + XF86DRIClipRectRec scissor_rect; /* Current software scissor */ + + /* Mirrors of some DRI state + */ + Display *display; /* X server display */ + + __DRIcontextPrivate *driContext; /* DRI context */ + __DRIscreenPrivate *driScreen; /* DRI screen */ + __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + RADEONSAREAPrivPtr sarea; /* Private SAREA data */ + + /* Performance counters + */ + GLuint boxes; /* Draw performance boxes */ + GLuint hardwareWentIdle; + GLuint c_clears; + GLuint c_drawWaits; + GLuint c_textureSwaps; + GLuint c_textureBytes; + GLuint c_vertexBuffers; +}; + +#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx)) + + +extern GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ); +extern void radeonDestroyContext( radeonContextPtr rmesa ); +extern radeonContextPtr radeonMakeCurrent( radeonContextPtr oldCtx, + radeonContextPtr newCtx, + __DRIdrawablePrivate *dPriv ); + + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 0 +#define ENABLE_PERF_BOXES 0 + +#if DO_DEBUG +extern int RADEON_DEBUG; +#else +#define RADEON_DEBUG 0 +#endif + +#define DEBUG_ALWAYS_SYNC 0x01 +#define DEBUG_VERBOSE_API 0x02 +#define DEBUG_VERBOSE_MSG 0x04 +#define DEBUG_VERBOSE_LRU 0x08 +#define DEBUG_VERBOSE_DRI 0x10 +#define DEBUG_VERBOSE_IOCTL 0x20 +#define DEBUG_VERBOSE_2D 0x40 + +#endif +#endif /* __RADEON_CONTEXT_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c new file mode 100644 index 000000000..b86506a8d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c @@ -0,0 +1,217 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" +#include "radeon_dd.h" + +#include "extensions.h" +#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM) +#include "X86/common_x86_asm.h" +#endif + +#define RADEON_DATE "20010105" + + +/* Return the width and height of the current color buffer. + */ +static void radeonDDGetBufferSize( GLcontext *ctx, + GLuint *width, GLuint *height ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + LOCK_HARDWARE( rmesa ); + *width = rmesa->driDrawable->w; + *height = rmesa->driDrawable->h; + UNLOCK_HARDWARE( rmesa ); +} + +/* Return various strings for glGetString(). + */ +static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + static GLubyte buffer[128]; + + switch ( name ) { + case GL_VENDOR: + return "VA Linux Systems, Inc."; + + case GL_RENDERER: + sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE ); + + /* Append any chipset-specific information. None yet. + */ + + /* Append any AGP-specific information. + */ + switch ( rmesa->radeonScreen->AGPMode ) { + case 1: + strncat( buffer, " AGP 1x", 7 ); + break; + case 2: + strncat( buffer, " AGP 2x", 7 ); + break; + case 4: + strncat( buffer, " AGP 4x", 7 ); + break; + } + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( gl_x86_cpu_features ) { + strncat( buffer, " x86", 4 ); + } +#endif +#ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + strncat( buffer, "/3DNow!", 7 ); + } +#endif +#ifdef USE_KATMAI_ASM + if ( cpu_has_xmm ) { + strncat( buffer, "/SSE", 4 ); + } +#endif + return buffer; + + default: + return NULL; + } +} + +/* Send all commands to the hardware. If vertex buffers or indirect + * buffers are in use, then we need to make sure they are sent to the + * hardware. All commands that are normally sent to the ring are + * already considered `flushed'. + */ +static void radeonDDFlush( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + +#if ENABLE_PERF_BOXES + if ( rmesa->boxes ) { + LOCK_HARDWARE( rmesa ); + radeonPerformanceBoxesLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + } + + /* Log the performance counters if necessary */ + radeonPerformanceCounters( rmesa ); +#endif +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +static void radeonDDFinish( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + rmesa->c_drawWaits++; +#endif + + radeonDDFlush( ctx ); + radeonWaitForIdle( rmesa ); +} + +/* Return various parameters requested by Mesa (this is deprecated). + */ +static GLint radeonDDGetParameteri( const GLcontext *ctx, GLint param ) +{ + switch ( param ) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + return 0; + } +} + +/* Initialize the extensions supported by this driver. + */ +void radeonDDInitExtensions( GLcontext *ctx ) +{ + gl_extensions_disable( ctx, "GL_ARB_imaging" ); + gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); + gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); + + gl_extensions_disable( ctx, "GL_EXT_blend_color" ); + gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); + gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); + gl_extensions_disable( ctx, "GL_EXT_convolution" ); + gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); + gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); + gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); + gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" ); + gl_extensions_enable( ctx, "GL_EXT_texture_env_dot3" ); + + gl_extensions_disable( ctx, "GL_HP_occlusion_test" ); + + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + + gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); + gl_extensions_disable( ctx, "GL_SGI_color_table" ); + gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); +} + +/* Initialize the driver's misc functions. + */ +void radeonDDInitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = radeonDDGetBufferSize; + ctx->Driver.GetString = radeonDDGetString; + ctx->Driver.Finish = radeonDDFinish; + ctx->Driver.Flush = radeonDDFlush; + + ctx->Driver.Error = NULL; + ctx->Driver.GetParameteri = radeonDDGetParameteri; + + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; + + ctx->Driver.RegisterVB = radeonDDRegisterVB; + ctx->Driver.UnregisterVB = radeonDDUnregisterVB; + ctx->Driver.BuildPrecalcPipeline = radeonDDBuildPrecalcPipeline; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h new file mode 100644 index 000000000..98dd22fae --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h @@ -0,0 +1,46 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_DD_H__ +#define __RADEON_DD_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonDDInitExtensions( GLcontext *ctx ); +extern void radeonDDInitDriverFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c new file mode 100644 index 000000000..a2bf4e1f5 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c @@ -0,0 +1,504 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + +#include <stdio.h> + +#include "radeon_context.h" +#include "radeon_pipeline.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_state.h" +#include "radeon_vb.h" + +#include "types.h" +#include "enums.h" +#include "cva.h" +#include "vertices.h" +#include "mmath.h" +#include "xform.h" + +/* Always use a full-sized stride for vertices. [FIXME] + * Stride in the buffers must be a quadword multiple. + */ +#define CLIP_STRIDE 10 + +static void fire_elts( radeonContextPtr rmesa ) +{ + GLuint vertsize = rmesa->vertsize; + + LOCK_HARDWARE( rmesa ); + + /* Fire queued elements and discard that buffer if its contents + * won't be referenced by future elements. + */ + if ( rmesa->elt_buf ) + { + GLuint retain = (rmesa->elt_buf == rmesa->retained_buf); + + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), + !retain ); + } else if ( !retain ) { + radeonReleaseBufLocked( rmesa, rmesa->elt_buf ); + } + + rmesa->elt_buf = 0; + } + else if ( rmesa->vert_buf ) + { + radeonFlushVerticesLocked( rmesa ); + } + + radeonGetEltBufLocked( rmesa ); + + UNLOCK_HARDWARE( rmesa ); + + /* Give the compiler a chance to optimize the divisions. + */ + switch ( vertsize ) { + case 8: + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * + RADEON_BUFFER_SIZE / (8 * sizeof(GLuint))) - 1); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 8 * sizeof(GLfloat)); + break; + + case 10: + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * + RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) - 1); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 10 * sizeof(GLfloat)); + break; + } + + rmesa->first_elt = rmesa->next_elt = (GLushort *) + ((GLubyte *)rmesa->elt_buf->address + RADEON_INDEX_PRIM_OFFSET); + + rmesa->elt_vertsize = vertsize; +} + + +static void release_bufs( radeonContextPtr rmesa ) +{ + if ( rmesa->retained_buf && rmesa->retained_buf != rmesa->elt_buf ) + { + LOCK_HARDWARE( rmesa ); + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), + 0 ); + + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; + } + + radeonReleaseBufLocked( rmesa, rmesa->retained_buf ); + UNLOCK_HARDWARE( rmesa ); + } + + rmesa->retained_buf = 0; +} + + + + +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) + + +#define INTERP_RGBA( t, out, a, b ) { \ + GLuint i; \ + for ( i = 0 ; i < 4 ; i++ ) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ + GLfloat fo = LINTERP( t, fa, fb ); \ + FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ + } \ +} + + +#define CLIP( SGN, V, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]]; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + for ( i = n = 0 ; i < nr ; i++ ) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i]; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert]; \ + outdata[n++] = next_vert++; \ + \ + if ( NEGATIVE( dpI ) ) { \ + GLfloat t = dpI / (dpI - dpJ); \ + interp( t, O, I, J ); \ + } \ + else \ + { \ + GLfloat t = dpJ / (dpJ - dpI); \ + interp( t, O, J, I ); \ + } \ + } \ + \ + if ( !NEGATIVE( dpI ) ) \ + outdata[n++] = elt_i; \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if ( n < 3 ) return; \ + } \ +} while (0) + + +static void radeon_tri_clip( radeonContextPtr rmesa, + struct vertex_buffer *VB, + GLuint *elt, + GLubyte mask ) +{ + struct radeon_elt_tab *tab = rmesa->elt_tab; + radeon_interp_func interp = tab->interp; + GLuint vertsize = rmesa->vertsize; + GLuint inlist[2][VB_MAX_CLIPPED_VERTS]; + GLuint in = 0; + GLuint n = 3, next_vert = 3; + GLuint i; + GLfloat verts[VB_MAX_CLIPPED_VERTS][CLIP_STRIDE]; + + /* Build temporary vertices in clipspace. This is the potential + * downside to this path. + */ + tab->build_tri_verts( rmesa, VB, (GLfloat *)verts, elt ); + + inlist[0][0] = 0; + inlist[0][1] = 1; + inlist[0][2] = 2; + + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); + + + { + GLuint *out = inlist[in]; + GLint space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); + + if ( space < (GLint)(n * (vertsize + 2) * sizeof(GLuint)) ) { + fire_elts( rmesa ); + } + + /* Project the new vertices and emit to dma buffers. Translate + * out values to physical addresses for setup dma. + */ + tab->project_and_emit_verts( rmesa, (GLfloat *)verts, out, n ); + + /* Convert the planar polygon to a list of triangles and emit to + * elt buffers. + */ + for ( i = 2 ; i < n ; i++ ) { + rmesa->next_elt[0] = (GLushort) out[0]; + rmesa->next_elt[1] = (GLushort) out[i-1]; + rmesa->next_elt[2] = (GLushort) out[i]; + rmesa->next_elt += 3; + } + } +} + + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ + +#define INIT( x ) + +#define TRI_THRESHOLD (GLint)(2 * sizeof(GLuint)) + +#define UNCLIPPED_VERT( x ) (GLushort)(rmesa->first_vert_index - x) + +#define TRIANGLE( e2, e1, e0 ) \ +do { \ + if ( (GLint)((GLuint)rmesa->next_vert - \ + (GLuint)rmesa->next_elt) < TRI_THRESHOLD ) { \ + fire_elts( rmesa ); \ + } \ + rmesa->next_elt[0] = UNCLIPPED_VERT( e2 ); \ + rmesa->next_elt[1] = UNCLIPPED_VERT( e1 ); \ + rmesa->next_elt[2] = UNCLIPPED_VERT( e0 ); \ + rmesa->next_elt += 3; \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask = mask[e2] | mask[e1] | mask[e0]; \ + if ( ormask == 0 ) { \ + TRIANGLE( e2, e1, e0 ); \ + } else if ( (mask[e2] & mask[e1] & mask[e0]) == 0 ) { \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + radeon_tri_clip( rmesa, VB, out, ormask ); \ + } \ +} while (0) + +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + GLuint *elt = VB->EltPtr->data; \ + GLuint out[VB_MAX_CLIPPED_VERTS]; \ + GLubyte *mask = VB->ClipMask; \ + (void) mask; (void) out; (void) elt; (void) rmesa; + + + +#define RENDER_POINTS( start, count ) +#define RENDER_LINE( i1, i0 ) +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ) + +#define TAG(x) radeon_##x##_elt +#include "render_tmp.h" + + + +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + GLuint *elt = VB->EltPtr->data; \ + (void) elt; (void) rmesa; + +#define RENDER_POINTS( start, count ) +#define RENDER_LINE( i1, i0 ) +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ + TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + TRIANGLE( elt[i2], elt[i1], elt[i0] ) + +#define TAG(x) radeon_##x##_elt_unclipped +#include "render_tmp.h" + + + + +static void refresh_projection_matrix( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLmatrix *mat = &ctx->Viewport.WindowMap; + GLfloat *m = rmesa->device_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY]; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; +} + +#define CLIP_UBYTE_R 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_B 2 +#define CLIP_UBYTE_A 3 + + +#define TYPE (0) +#define TAG(x) x +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "radeon_elttmp.h" + +#define TYPE (RADEON_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "radeon_elttmp.h" + + +/* Very sparsely popluated array - fix the indices. + */ +static struct radeon_elt_tab radeonEltTab[RADEON_MAX_SETUPFUNC]; + +void radeonDDEltPathInit( void ) +{ + radeon_render_init_elt(); + radeon_render_init_elt_unclipped(); + + radeon_init_eltpath( &radeonEltTab[0] ); + radeon_init_eltpath_RGBA( &radeonEltTab[RADEON_RGBA_BIT] ); + radeon_init_eltpath_TEX0( &radeonEltTab[RADEON_TEX0_BIT] ); + radeon_init_eltpath_RGBA_TEX0( &radeonEltTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT)] ); + radeon_init_eltpath_TEX0_TEX1( &radeonEltTab[(RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); + radeon_init_eltpath_RGBA_TEX0_TEX1( &radeonEltTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); +} + +#define VALID_SETUP (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) + + + +/* Use a temporary array for device coordinates, so that we can easily + * tap into existing mesa assembly. Otherwise consider emitting + * device coordinates to dma buffers directly from the project/cliptest + * routine. (requires output stride, potential loss of writecombining + * efficiency?) + * + * This path is a lot closer to the standard vertex path in the + * initial stages than the original fastpath. A slightly more optimal + * path could be constructed, but would require us to write new + * assembly. + */ +void radeonDDEltPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_elt_tab *tab = + &radeonEltTab[rmesa->SetupIndex & VALID_SETUP]; + GLint vertsize = rmesa->vertsize; + GLint space; + + VB->ClipPtr = TransformRaw( &VB->Clip, + &ctx->ModelProjectMatrix, + VB->ObjPtr ); + + refresh_projection_matrix( ctx ); + + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &VB->Win, + VB->ClipMask, + &VB->ClipOrMask, + &VB->ClipAndMask ); + + if ( VB->ClipAndMask ) + return; + + if ( rmesa->vert_buf ) + radeonFlushVertices( rmesa ); + + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); + + /* Allocate a single buffer to hold unclipped vertices. All + * unclipped vertices must be contiguous. + */ + if ( space < (GLint)(VB->Count * vertsize * sizeof(GLuint)) || + rmesa->vertsize != rmesa->elt_vertsize ) { + fire_elts( rmesa ); + } + + rmesa->retained_buf = rmesa->elt_buf; + + /* Emit unclipped vertices to the buffer. + */ + tab->emit_unclipped_verts( VB ); + + /* Emit indices and clipped vertices to one or more buffers. + */ + if ( VB->ClipOrMask ) { + rmesa->elt_tab = tab; + radeon_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 ); + } else { + radeon_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 ); + } + + /* Send to hardware and release the elt buffer. + */ + release_bufs( rmesa ); + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; + + FLUSH_BATCH( rmesa ); +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h new file mode 100644 index 000000000..1fa8f60b9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h @@ -0,0 +1,246 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +/* Buffers fill from high addresses down with vertices and from low + * addresses up with elements. + */ + + +/* Emit the bulk of the vertices to the first dma buffer. Leave + * empty slots for clipped vertices so that we can still address + * vertices by index. + */ +static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); + GLfloat *dev = VB->Projected->start; + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + GLuint buffer_stride = rmesa->vertsize; + + GLfloat *f = rmesa->next_vert; + GLuint count = VB->Count; + GLubyte *clipmask = VB->ClipMask; + + const GLfloat *m = rmesa->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; + + rmesa->retained_buf = rmesa->elt_buf; + rmesa->first_vert_index = rmesa->next_vert_index; + + for ( i = 0 ; i < count ; f -= buffer_stride, i++ ) + { + if ( !clipmask[i] ) + { + f[0] = sx * dev[0] + tx; + f[1] = sy * dev[1] + ty; + f[2] = sz * dev[2] + tz; + f[3] = dev[3]; + + if ( TYPE & RADEON_RGBA_BIT ) { + *(GLuint *)&f[4] = *(GLuint *)color; + } + + if ( TYPE & RADEON_TEX0_BIT ) { + *(GLuint *)&f[6] = *(GLuint *)&tex0_data[0]; + *(GLuint *)&f[7] = *(GLuint *)&tex0_data[1]; + } + + if ( TYPE & RADEON_TEX1_BIT ) { + *(GLuint *)&f[8] = *(GLuint *)&tex1_data[0]; + *(GLuint *)&f[9] = *(GLuint *)&tex1_data[1]; + } + } + + STRIDE_F( dev, 16 ); + if ( TYPE & RADEON_RGBA_BIT ) color += color_stride; + if ( TYPE & RADEON_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & RADEON_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); + } + + rmesa->next_vert = f; + rmesa->next_vert_index -= count; +} + + +/* Build three temporary clipspace vertex for clipping a triangle. + * Recreate from the VB data rather than trying to read back from + * uncached memory. + */ +static void TAG(build_tri_verts)( radeonContextPtr rmesa, + struct vertex_buffer *VB, + GLfloat *O, + GLuint *elt ) +{ + GLint i; + + for ( i = 0 ; i < 3 ; i++, O += CLIP_STRIDE ) { + GLfloat *clip = VB->Clip.start + elt[i]*4; + + O[0] = clip[0]; + O[1] = clip[1]; + O[2] = clip[2]; + O[3] = clip[3]; + + if ( TYPE & RADEON_RGBA_BIT ) { + GLubyte *color = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]); + *(GLuint *)&O[4] = *(GLuint *)color; + } + + *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]); + + if ( TYPE & RADEON_TEX0_BIT ) { + GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]); + *(GLuint *)&O[6] = *(GLuint *)&tex0_data[0]; + *(GLuint *)&O[7] = *(GLuint *)&tex0_data[1]; + } + + if ( TYPE & RADEON_TEX1_BIT ) { + GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]); + *(GLuint *)&O[8] = *(GLuint *)&tex1_data[0]; + *(GLuint *)&O[9] = *(GLuint *)&tex1_data[1]; + } + } +} + + +/* Interpolate between two of the vertices constructed above. + */ +static void TAG(interp)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) +{ + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & RADEON_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); + } + + *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */ + + if ( TYPE & RADEON_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); + } + + if ( TYPE & RADEON_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); + } +} + + + +/* When clipping is complete, scan the final vertex list and emit any + * new ones to dma buffers. Update the element list to a format + * suitable for sending to hardware. + */ +static void TAG(project_and_emit_verts)( radeonContextPtr rmesa, + const GLfloat *verts, + GLuint *elt, + GLuint nr) +{ + GLfloat *O = rmesa->next_vert; + GLushort index = rmesa->next_vert_index; + GLuint buffer_stride = rmesa->vertsize; + + const GLfloat *m = rmesa->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; + + for ( i = 0 ; i < nr ; i++ ) { + const GLfloat *I = &verts[elt[i] * CLIP_STRIDE]; + GLuint tmp = *(GLuint *)&I[5]; + + if ( (elt[i] = tmp) == ~0 ) { + GLfloat oow = 1.0 / I[3]; + + elt[i] = index--; + + O[0] = sx * I[0] * oow + tx; + O[1] = sy * I[1] * oow + ty; + O[2] = sz * I[2] * oow + tz; + O[3] = oow; + + if ( TYPE & RADEON_RGBA_BIT ) { + *(GLuint *)&O[4] = *(GLuint *)&I[4]; + } + + if ( TYPE & RADEON_TEX0_BIT ) { + *(GLuint *)&O[6] = *(GLuint *)&I[6]; + *(GLuint *)&O[7] = *(GLuint *)&I[7]; + } + + if ( TYPE & RADEON_TEX1_BIT ) { + *(GLuint *)&O[8] = *(GLuint *)&I[8]; + *(GLuint *)&O[9] = *(GLuint *)&I[9]; + } + + O -= buffer_stride; + } + } + + rmesa->next_vert = O; + rmesa->next_vert_index = index; +} + + + +static void TAG(radeon_init_eltpath)( struct radeon_elt_tab *tab ) +{ + tab->emit_unclipped_verts = TAG(emit_unclipped_verts); + tab->build_tri_verts = TAG(build_tri_verts); + tab->interp = TAG(interp); + tab->project_and_emit_verts = TAG(project_and_emit_verts); +} + +#undef TYPE +#undef TAG +#undef STRIDE diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c new file mode 100644 index 000000000..b5437e7f9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c @@ -0,0 +1,542 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_state.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" + +#include "mmath.h" +#include "cva.h" +#include "vertices.h" + + +struct radeon_fast_tab { + void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); + void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); +}; + +#define POINT(x) radeon_draw_point( rmesa, &vert[x], psize ) +#define LINE(x,y) radeon_draw_line( rmesa, &vert[x], &vert[y], lwidth ) +#define TRI(x,y,z) radeon_draw_triangle( rmesa, &vert[x], &vert[y], &vert[z] ) + + +/* Direct, and no clipping required. The clip funcs have not been + * written yet, so this is only useful for the fast path. + */ +#define RENDER_POINTS( start, count ) \ +do { \ + GLuint e; \ + for ( e = start ; e < count ; e++ ) \ + POINT( elt[e] ); \ +} while (0) + +#define RENDER_LINE( i1, i ) \ +do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + LINE( e1, e ); \ +} while (0) + +#define RENDER_TRI( i2, i1, i, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if ( parity ) { \ + GLuint tmp = e2; \ + e2 = e1; \ + e1 = tmp; \ + } \ + TRI( e2, e1, e ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i, pv ) \ +do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + TRI( e3, e2, e ); \ + TRI( e2, e1, e ); \ +} while (0) + +#define LOCAL_VARS \ + radeonVertexPtr vert = RADEON_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + GLcontext *ctx = VB->ctx; \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + const GLfloat lwidth = ctx->Line.Width; \ + const GLfloat psize = ctx->Point.Size; \ + (void) lwidth; (void) psize; (void) vert; + +#define TAG(x) radeon_##x##_smooth_indirect +#include "render_tmp.h" + + + +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) + + +#define INTERP_RGBA( t, out, a, b ) \ +do { \ + int i; \ + for ( i = 0 ; i < 4 ; i++ ) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ + GLfloat fo = LINTERP( t, fa, fb ); \ + FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ + } \ +} while (0) + + +#define CLIP( SGN, V, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]].f; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + inlist[0] = vlist1; \ + for ( i = n = 0 ; i < nr ; i++ ) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i].f; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t, *in, *out; \ + \ + if ( NEGATIVE( dpI ) ) { \ + t = dpI / (dpI - dpJ); \ + in = I; \ + out = J; \ + } else { \ + t = dpJ / (dpJ - dpI); \ + in = J; \ + out = I; \ + } \ + \ + interp( t, O, in, out ); \ + \ + clipmask[next_vert] = 0; \ + outdata[n++] = next_vert++; \ + } \ + \ + clipmask[elt_i] |= PLANE; /* don't set up */ \ + \ + if ( !NEGATIVE( dpI ) ) { \ + outdata[n++] = elt_i; \ + clipmask[elt_i] &= ~PLANE; /* set up after all */ \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if ( n < 3 ) return; \ + } \ +} while (0) + +#define LINE_CLIP( x, y, z, w, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLfloat dpI = DOT4V( I, x, y, z, w); \ + GLfloat dpJ = DOT4V( J, x, y, z, w); \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + \ + interp( t, O, I, J ); \ + \ + clipmask[next_vert] = 0; \ + \ + if ( NEGATIVE( dpI ) ) { \ + clipmask[elts[0]] |= PLANE; \ + I = O; \ + elts[0] = next_vert++; \ + } else { \ + clipmask[elts[1]] |= PLANE; \ + J = O; \ + elts[1] = next_vert++; \ + } \ + } else if ( NEGATIVE( dpI ) ) return; \ + } \ +} while (0) + + +static __inline void radeon_tri_clip( GLuint **p_elts, + radeonVertexPtr verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + radeon_interp_func interp ) +{ + GLuint *elts = *p_elts; + GLuint next_vert = *p_next_vert; + GLuint in = 0; + GLuint n = 3; + GLuint vlist1[VB_MAX_CLIPPED_VERTS]; + GLuint vlist2[VB_MAX_CLIPPED_VERTS]; + GLuint *inlist[2]; + GLuint *out; + GLuint i; + + inlist[0] = elts; + inlist[1] = vlist2; + + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); + + /* Convert the planar polygon to a list of triangles */ + out = inlist[in]; + + for ( i = 2 ; i < n ; i++ ) { + elts[0] = out[0]; + elts[1] = out[i-1]; + elts[2] = out[i]; + elts += 3; + } + + *p_next_vert = next_vert; + *p_elts = elts; +} + + +static __inline void radeon_line_clip( GLuint **p_elts, + radeonVertexPtr verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + radeon_interp_func interp ) +{ + GLuint *elts = *p_elts; + GLfloat *I = verts[elts[0]].f; + GLfloat *J = verts[elts[1]].f; + GLuint next_vert = *p_next_vert; + + LINE_CLIP( 1, 0, 0, -1, CLIP_LEFT_BIT ); + LINE_CLIP( -1, 0, 0, 1, CLIP_RIGHT_BIT ); + LINE_CLIP( 0, 1, 0, -1, CLIP_TOP_BIT ); + LINE_CLIP( 0, -1, 0, 1, CLIP_BOTTOM_BIT ); + LINE_CLIP( 0, 0, 1, -1, CLIP_FAR_BIT ); + LINE_CLIP( 0, 0, -1, 1, CLIP_NEAR_BIT ); + + *p_next_vert = next_vert; + *p_elts += 2; +} + + + +#define CLIP_POINT( e ) \ +do { \ + if ( mask[e] ) *out++ = e; \ +} while (0) + +#define CLIP_LINE( e1, e0 ) \ +do { \ + GLubyte ormask = mask[e0] | mask[e1]; \ + out[0] = e1; \ + out[1] = e0; \ + out += 2; \ + if ( ormask ) { \ + out-=2; \ + if ( !(mask[e0] & mask[e1]) ) { \ + radeon_line_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ + } \ + } \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask; \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + out += 3; \ + ormask = mask[e2] | mask[e1] | mask[e0]; \ + if ( ormask ) { \ + out -= 3; \ + if ( !(mask[e2] & mask[e1] & mask[e0]) ) { \ + radeon_tri_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ + } \ + } \ +} while (0) + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); \ + GLuint *elt = VB->EltPtr->data; \ + radeonVertexPtr verts = rvb->verts; \ + GLuint next_vert = rvb->last_vert; \ + GLuint *out = rvb->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + radeon_interp_func interp = rmesa->interp; \ + (void) interp; (void) verts; + +#define POSTFIX \ + rvb->clipped_elements.count = out - rvb->clipped_elements.data; \ + rvb->last_vert = next_vert; + + +#define INIT( x ) + +#define RENDER_POINTS( start, count ) \ +do { \ + GLuint i; \ + for ( i = start; i < count ; i++ ) \ + CLIP_POINT( elt[i] ); \ +} while (0) + +#define RENDER_LINE( i1, i0 ) \ +do { \ + CLIP_LINE( elt[i1], elt[i0] ); \ +} while (0) + +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ +do { \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ); \ +} while (0) + +#define TAG(x) radeon_##x##_clip_elt +#include "render_tmp.h" + + + +/* Pack rgba and/or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_UBYTE_COLOR 4 +#define CLIP_UBYTE_R 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_B 2 +#define CLIP_UBYTE_A 3 +#define CLIP_S0 6 +#define CLIP_T0 7 +#define CLIP_S1 8 +#define CLIP_T1 9 + +#define TYPE (0) +#define TAG(x) x +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "radeon_fasttmp.h" + +/* This one *could* get away with sneaking TEX1 into the color and + * specular slots, thus fitting inside a cache line. Would be even + * better to switch to a smaller vertex. + */ +#define TYPE (RADEON_TEX0_BIT | RADEON_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "radeon_fasttmp.h" + + + +static void radeon_render_elements_direct( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = radeon_render_tab_smooth_indirect[prim]; + GLuint p = 0; + + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + do { + func( VB, 0, nr, 0 ); + } while ( ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc( VB, ++p ) ); +} + +/* GH: These should go away altogether on the Radeon. We should disable + * the viewport mapping entirely in Mesa and let the hardware do it in + * all cases. + */ +static void radeon_project_vertices( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY]; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; + + gl_project_v16( rvb->verts[VB->CopyStart].f, + rvb->verts[rvb->last_vert].f, + m, + 16 * 4 ); +} + +static void radeon_project_clipped_vertices( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY]; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; + + gl_project_clipped_v16( rvb->verts[VB->CopyStart].f, + rvb->verts[rvb->last_vert].f, + m, + 16 * 4, + VB->ClipMask + VB->CopyStart ); +} + +static struct radeon_fast_tab radeonFastTab[RADEON_MAX_SETUPFUNC]; + +void radeonDDFastPathInit( void ) +{ + radeon_render_init_clip_elt(); + radeon_render_init_smooth_indirect(); + + radeon_init_fastpath( &radeonFastTab[0] ); + radeon_init_fastpath_RGBA( &radeonFastTab[RADEON_RGBA_BIT] ); + radeon_init_fastpath_TEX0( &radeonFastTab[RADEON_TEX0_BIT] ); + radeon_init_fastpath_RGBA_TEX0( &radeonFastTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT)] ); + radeon_init_fastpath_TEX0_TEX1( &radeonFastTab[(RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); + radeon_init_fastpath_RGBA_TEX0_TEX1( &radeonFastTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); +} + +#define VALID_SETUP (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT) + +void radeonDDFastPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + struct radeon_fast_tab *tab = + &radeonFastTab[rmesa->SetupIndex & VALID_SETUP]; + GLuint do_cliptest = 1; + + gl_prepare_arrays_cva( VB ); /* still need this */ + + if ( ( gl_reduce_prim[prim] == GL_TRIANGLES ) && + ( VB->Count < (RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) ) && + ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL | + MAT_FLAG_PERSPECTIVE) ) ) + { + radeonDDEltPath( VB ); + return; + } + + /* Reserve enough space for the pathological case */ + if ( VB->EltPtr->count * 12 > RADEON_DRIVER_DATA(VB)->size ) { + radeonDDResizeVB( VB, VB->EltPtr->count * 12 ); + do_cliptest = 1; + } + + tab->build_vertices( VB, do_cliptest ); /* object->clip space */ + + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + if ( VB->ClipOrMask ) { + if ( !VB->ClipAndMask ) { + render_func *clip = radeon_render_tab_clip_elt; + + rmesa->interp = tab->interp; + + clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ + + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(RADEON_DRIVER_DATA(VB)->clipped_elements); + + radeon_project_clipped_vertices( VB ); /* clip->device space */ + radeon_render_elements_direct( VB ); /* render using new list */ + } + } else { + radeon_project_vertices( VB ); /* clip->device space */ + radeon_render_elements_direct( VB ); /* render using orig list */ + } + + /* This indicates that there is no cached data to reuse */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h new file mode 100644 index 000000000..a7bc8e9ca --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h @@ -0,0 +1,185 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +/* The first part of setup is applied to all vertices, clipped or + * unclipped. This data w!ill be used for clipping, and then all + * vertices with a zero clipmask will be projected to device space. + * + * This could be split into several loops, but - it seems that the + * large stride of the fxVertices makes cache issues the big + * performance factor, and that multiple loops mean multiple cache + * misses.... + */ +static void TAG(radeon_setup_full)( struct vertex_buffer *VB, + GLuint do_cliptest ) +{ + GLcontext *ctx = VB->ctx; + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + const GLfloat *m = ctx->ModelProjectMatrix.m; + GLuint start = VB->CopyStart; + GLuint count = VB->Count; + + gl_xform_points3_v16_general( rvb->verts[start].f, + m, + VB->ObjPtr->start, + VB->ObjPtr->stride, + count - start ); + + if ( do_cliptest ) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16( rvb->verts[start].f, + rvb->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), + VB->ClipMask + start ); + } + + /* These branches are all resolved at compile time. Hopefully all + * the pointers are valid addresses even when not enabled. + */ + if ( TYPE ) { + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = rvb->verts[start].f; + GLfloat *end = f + (16 * (count - start)); + + while ( f != end ) { + if ( TYPE & RADEON_RGBA_BIT ) { +#if defined (USE_X86_ASM) + /* GH: Finally! Some damned hardware manufacturer uses + * little-endian RGBA for vertex color... + */ + __asm__ ( "movl (%%ecx), %%eax \n" + "movl %%eax, 16(%%edi) \n" + : + : "c" (color), "D" (f) + : "%eax" ); +#else + *(GLuint *)(f+CLIP_UBYTE_COLOR) = *(GLuint *)color; +#endif + } + if ( TYPE & RADEON_TEX0_BIT ) { +#if defined (USE_X86_ASM) + __asm__ ( "movl (%%ecx), %%eax \n" + "movl %%eax, 24(%%edi) \n" + "movl 4(%%ecx), %%eax \n" + "movl %%eax, 28(%%edi)" + : + : "c" (tex0_data), "D" (f) + : "%eax" ); +#else + *(GLuint *)(f+CLIP_S0) = *(GLuint *)tex0_data; + *(GLuint *)(f+CLIP_T0) = *(GLuint *)(tex0_data+1); +#endif + } + if ( TYPE & RADEON_TEX1_BIT ) { + /* Hits a second cache line. + */ +#if defined (USE_X86_ASM) + __asm__ ( "movl (%%esi), %%eax \n" + "movl %%eax, 32(%%edi) \n" + "movl 4(%%esi), %%eax \n" + "movl %%eax, 36(%%edi)" + : + : "S" (tex1_data), "D" (f) + : "%eax" ); +#else + *(GLuint *)(f+CLIP_S1) = *(GLuint *)tex1_data; + *(GLuint *)(f+CLIP_T1) = *(GLuint *)(tex1_data+1); +#endif + } + if ( TYPE & RADEON_RGBA_BIT ) color += color_stride; + if ( TYPE & RADEON_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & RADEON_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); + f += 16; + } + } + + rvb->clipped_elements.count = start; + rvb->last_vert = count; +} + + +/* Changed to just put the interp func instead of the whole clip + * routine into the header. Less code and better chance of doing some + * of this stuff in assembly. + */ +static void TAG(radeon_interp_vert)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) +{ + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & RADEON_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); + } + + if ( TYPE & RADEON_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); + } + + if ( TYPE & RADEON_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); + } +} + + +static void TAG(radeon_init_fastpath)( struct radeon_fast_tab *tab ) +{ + tab->build_vertices = TAG(radeon_setup_full); + tab->interp = TAG(radeon_interp_vert); +} + +#undef TYPE +#undef TAG +#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c new file mode 100644 index 000000000..9845732c8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -0,0 +1,703 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" + +#include "mem.h" + +#define RADEON_TIMEOUT 2048 +#define USE_IN_MEMORY_SCRATCH_REGS 0 + + +/* ============================================================= + * Hardware vertex buffer handling + */ + +/* Get a new VB from the pool of vertex buffers in AGP space. + */ +drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa ) +{ + int fd = rmesa->radeonScreen->driScreen->fd; + int index = 0; + int size = 0; + drmDMAReq dma; + drmBufPtr buf = NULL; + int to = 0; + int ret; + + dma.context = rmesa->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = RADEON_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; + + while ( !buf && ( to++ < RADEON_TIMEOUT ) ) { + ret = drmDMA( fd, &dma ); + + if ( ret == 0 ) { + buf = &rmesa->radeonScreen->buffers->list[index]; + buf->used = 0; +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + rmesa->c_vertexBuffers++; +#endif + return buf; + } + } + + if ( !buf ) { + drmRadeonEngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Could not get new VB... exiting\n" ); + exit( -1 ); + } + + return buf; +} + +static GLboolean intersect_rect( XF86DRIClipRectPtr out, + XF86DRIClipRectPtr a, + XF86DRIClipRectPtr 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 radeonFlushVerticesLocked( radeonContextPtr rmesa ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->vert_buf; + int count = rmesa->num_verts; + int prim = RADEON_TRIANGLES; + int fd = rmesa->driScreen->fd; + int i; + + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + if ( !buffer ) + return; + + if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) + radeonEmitHwStateLocked( rmesa ); + + if ( !nbox ) + count = 0; + + if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + + if ( !count || !(rmesa->dirty & RADEON_UPLOAD_CLIPRECTS) ) + { + if ( nbox == 1 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); + } + else + { + for ( i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + int discard = 0; + + if ( rmesa->scissor ) { + rmesa->sarea->nbox = 0; + + for ( ; i < nr ; i++ ) { + *b = pbox[i]; + if ( intersect_rect( b, b, &rmesa->scissor_rect ) ) { + rmesa->sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if ( !rmesa->sarea->nbox ) { + if ( nr < nbox ) continue; + count = 0; + } + } else { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + discard = 1; + } + + rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, discard ); + } + } + + rmesa->dirty &= ~RADEON_UPLOAD_CLIPRECTS; +} + + + +/* ================================================================ + * Indexed vertex buffer handling + */ + +void radeonGetEltBufLocked( radeonContextPtr rmesa ) +{ + rmesa->elt_buf = radeonGetBufferLocked( rmesa ); +} + +void radeonFireEltsLocked( radeonContextPtr rmesa, + GLuint start, GLuint end, + GLuint discard ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->elt_buf; + int prim = RADEON_TRIANGLES; + int fd = rmesa->driScreen->fd; + int i; + + if ( !buffer ) + return; + + if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) + radeonEmitHwStateLocked( rmesa ); + + if ( !nbox ) + end = start; + + if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + + if ( start == end || !(rmesa->dirty & RADEON_UPLOAD_CLIPRECTS) ) + { + if ( nbox == 1 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + else + { + for ( i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + int d = 0; + + if ( rmesa->scissor ) { + rmesa->sarea->nbox = 0; + + for ( ; i < nr ; i++ ) { + *b = pbox[i]; + if ( intersect_rect( b, b, &rmesa->scissor_rect ) ) { + rmesa->sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if ( !rmesa->sarea->nbox ) { + if ( nr < nbox ) continue; + end = start; + } + } else { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + d = discard; + } + + rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + } + + rmesa->dirty &= ~RADEON_UPLOAD_CLIPRECTS; +} + +void radeonFlushEltsLocked( radeonContextPtr rmesa ) +{ + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), + 0 ); + + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; + } +} + +void radeonReleaseBufLocked( radeonContextPtr rmesa, drmBufPtr buffer ) +{ + int fd = rmesa->driScreen->fd; + + if ( !buffer ) + return; + + drmRadeonFlushVertexBuffer( fd, RADEON_TRIANGLES, buffer->idx, 0, 1 ); +} + + +/* Allocate some space in the current vertex buffer. If the current + * buffer is full, flush it and grab another one. + */ +CARD32 *radeonAllocVertices( radeonContextPtr rmesa, GLuint count ) +{ + return radeonAllocVerticesInline( rmesa, count ); +} + + +/* ================================================================ + * Texture uploads + */ + +void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, GLint width, GLint height ) +{ + GLint ret; + + ret = drmRadeonTextureBlit( rmesa->driFd, buffer->idx, + offset, pitch, format, + x, y, width, height ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); + exit( 1 ); + } +} + + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +#define RADEON_MAX_OUTSTANDING 2 + +/* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + * GH: We probably don't want a timeout here, as we can wait as + * long as we want for a frame to complete. If it never does, then + * the card has locked. + */ +#if USE_IN_MEMORY_SCRATCH_REGS +static int radeonWaitForFrameCompletion( radeonContextPtr rmesa ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + __volatile__ CARD32 *scratch = rmesa->radeonScreen->scratch; + CARD32 frame; + int wait = 0; + + while ( 1 ) { + /* Read the frame counter from the in-memory copy of the scratch + * register. Nifty, eh? Should significantly reduce the bus + * traffic for SwapBuffers-limited apps (generally pretty trivial + * ones, but anyway). + */ + frame = scratch[0]; + if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) { + break; + } + wait++; + } + + return wait; +} +#else +static void delay( void ) { +/* Prevent an optimizing compiler from removing a spin loop */ +} + +static int radeonWaitForFrameCompletion( radeonContextPtr rmesa ) +{ + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; + RADEONSAREAPrivPtr sarea = rmesa->sarea; + CARD32 frame; + int wait = 0; + int i; + + while ( 1 ) { + frame = INREG( RADEON_LAST_FRAME_REG ); + if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) { + break; + } + wait++; + /* Spin in place a bit so we aren't hammering the bus */ + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } + + return wait; +} +#endif + +/* Copy the back color buffer to the front color buffer. + */ +void radeonSwapBuffers( radeonContextPtr rmesa ) +{ + GLint nbox = rmesa->numClipRects; + GLint i; + GLint ret; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx ); + } + + FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !radeonWaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; + } else { + rmesa->hardwareWentIdle = 0; + } + + for ( i = 0 ; i < nbox ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + rmesa->sarea->nbox = n; + + ret = drmRadeonSwapBuffers( rmesa->driFd ); + + if ( ret ) { + fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + UNLOCK_HARDWARE( rmesa ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + radeonPerformanceCounters( rmesa ); +#endif +} + +void radeonPageFlip( radeonContextPtr rmesa ) +{ + GLint ret; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p ): page=%d\n\n", + __FUNCTION__, rmesa->glCtx, rmesa->currentPage ); + } + + FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !radeonWaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; + } else { + rmesa->hardwareWentIdle = 0; + } + + /* The kernel will have been initialized to perform page flipping + * on a swapbuffers ioctl. + */ + ret = drmRadeonSwapBuffers( rmesa->driFd ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + exit( 1 ); + } + + if ( rmesa->currentPage == 0 ) { + rmesa->drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->drawPitch = rmesa->radeonScreen->frontPitch; + rmesa->currentPage = 1; + } else { + rmesa->drawOffset = rmesa->radeonScreen->backOffset; + rmesa->drawPitch = rmesa->radeonScreen->backPitch; + rmesa->currentPage = 0; + } + + rmesa->setup.rb3d_coloroffset = rmesa->drawOffset; + rmesa->setup.rb3d_colorpitch = rmesa->drawPitch; + + rmesa->new_state |= RADEON_NEW_WINDOW; + + /* FIXME: Do we need this anymore? */ + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + radeonPerformanceCounters( rmesa ); +#endif +} + + +/* ================================================================ + * Buffer clear + */ +#define RADEON_MAX_CLEARS 256 + +static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + RADEONSAREAPrivPtr sarea = rmesa->sarea; +#if USE_IN_MEMORY_SCRATCH_REGS + __volatile__ CARD32 *scratch = rmesa->radeonScreen->scratch; +#else + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; +#endif + CARD32 clear; + GLuint flags = 0; + GLint ret, i; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n", + __FUNCTION__, all, cx, cy, cw, ch ); + } + + FLUSH_BATCH( rmesa ); + + /* Update and emit any new state. We need to do this here to catch + * changes to the masks. + * FIXME: Just update the masks? + */ + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= DRM_RADEON_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= DRM_RADEON_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( mask & DD_DEPTH_BIT ) { + if ( ctx->Depth.Mask ) { + flags |= DRM_RADEON_DEPTH; + } + mask &= ~DD_DEPTH_BIT; + } +#if 0 + /* FIXME: Add stencil support */ + if ( mask & DD_STENCIL_BIT ) { + flags |= DRM_RADEON_DEPTH; + mask &= ~DD_STENCIL_BIT; + } +#endif + + if ( !flags ) + return mask; + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( rmesa ); + + /* Throttle the number of clear ioctls we do. + */ +#if USE_IN_MEMORY_SCRATCH_REGS + while ( 1 ) { + clear = scratch[2]; + if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { + break; + } + } +#else + while ( 1 ) { + clear = INREG( RADEON_LAST_CLEAR_REG ); + if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { + break; + } + /* Spin in place a bit so we aren't hammering the bus */ + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } +#endif + + if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeonEmitHwStateLocked( rmesa ); + } + + for ( i = 0 ; i < rmesa->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, rmesa->numClipRects ); + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + GLint n = 0; + + if ( !all ) { + for ( ; i < nr ; i++ ) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if ( x < cx ) w -= cx - x, x = cx; + if ( y < cy ) h -= cy - y, y = cy; + if ( x + w > cx + cw ) w = cx + cw - x; + if ( y + h > cy + ch ) h = cy + ch - y; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + } + + rmesa->sarea->nbox = n; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) { + fprintf( stderr, + "drmRadeonClear: flag 0x%x color %x depth %x nbox %d\n", + flags, + (GLuint)rmesa->ClearColor, + (GLuint)rmesa->ClearDepth, + rmesa->sarea->nbox ); + } + + ret = drmRadeonClear( rmesa->driFd, flags, + cx, cy, cw, ch, + rmesa->ClearColor, rmesa->ClearDepth ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "drmRadeonClear: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + + return mask; +} + + +void radeonWaitForIdleLocked( radeonContextPtr rmesa ) +{ + int fd = rmesa->radeonScreen->driScreen->fd; + int to = 0; + int ret; + + do { + ret = drmRadeonWaitForIdleCP( fd ); + } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); + + if ( ret < 0 ) { + drmRadeonEngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Radeon timed out... exiting\n" ); + exit( -1 ); + } +} + + +void radeonDDInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = radeonDDClear; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h new file mode 100644 index 000000000..ceb9225da --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h @@ -0,0 +1,161 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_IOCTL_H__ +#define __RADEON_IOCTL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_dri.h" +#include "radeon_lock.h" + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +#define RADEON_BUFFER_MAX_DWORDS (RADEON_BUFFER_SIZE / sizeof(CARD32)) + + +extern drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa ); +extern void radeonFlushVerticesLocked( radeonContextPtr rmesa ); + +extern void radeonGetEltBufLocked( radeonContextPtr rmesa ); +extern void radeonFlushEltsLocked( radeonContextPtr rmesa ); +extern void radeonFireEltsLocked( radeonContextPtr rmesa, + GLuint start, GLuint end, + GLuint discard ); +extern void radeonReleaseBufLocked( radeonContextPtr rmesa, drmBufPtr buffer ); + +/* Make this available as both a regular and an inline function. + */ +extern CARD32 *radeonAllocVertices( radeonContextPtr rmesa, GLuint count ); + +static __inline CARD32 *radeonAllocVerticesInline( radeonContextPtr rmesa, + GLuint count ) +{ + int bytes = count * rmesa->vertsize * 4; + CARD32 *head; + + if ( !rmesa->vert_buf ) { + LOCK_HARDWARE( rmesa ); + + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFlushEltsLocked( rmesa ); + } + + rmesa->vert_buf = radeonGetBufferLocked( rmesa ); + + UNLOCK_HARDWARE( rmesa ); + } else if ( rmesa->vert_buf->used + bytes > rmesa->vert_buf->total ) { + LOCK_HARDWARE( rmesa ); + + radeonFlushVerticesLocked( rmesa ); + rmesa->vert_buf = radeonGetBufferLocked( rmesa ); + + UNLOCK_HARDWARE( rmesa ); + } + + head = (CARD32 *)((char *)rmesa->vert_buf->address + + rmesa->vert_buf->used); + + rmesa->vert_buf->used += bytes; + rmesa->num_verts += count; + return head; +} + +extern void radeonFireBlitLocked( radeonContextPtr rmesa, + drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, + GLint width, GLint height ); + +extern void radeonSwapBuffers( radeonContextPtr rmesa ); +extern void radeonPageFlip( radeonContextPtr rmesa ); + +extern void radeonWaitForIdleLocked( radeonContextPtr rmesa ); + + +extern void radeonDDInitIoctlFuncs( GLcontext *ctx ); + + +/* ================================================================ + * Helper macros: + */ + +#define FLUSH_BATCH( rmesa ) \ +do { \ + if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) \ + fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ + if ( rmesa->vert_buf ) { \ + radeonFlushVertices( rmesa ); \ + } else if ( rmesa->next_elt != rmesa->first_elt ) { \ + radeonFlushElts( rmesa ); \ + } \ +} while (0) + +/* 64-bit align the next element address, and then make room for the + * next indexed prim packet header. + */ +#define ALIGN_NEXT_ELT( rmesa ) \ +do { \ + rmesa->next_elt = (GLushort *) \ + (((GLuint)rmesa->next_elt + 7) & ~0x7); \ + rmesa->next_elt = (GLushort *) \ + ((GLubyte *)rmesa->next_elt + RADEON_INDEX_PRIM_OFFSET); \ +} while (0) + +#define radeonFlushVertices( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + radeonFlushVerticesLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#define radeonFlushElts( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + radeonFlushEltsLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#define radeonWaitForIdle( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + radeonWaitForIdleLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#endif +#endif /* __RADEON_IOCTL_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c new file mode 100644 index 000000000..583fd6dfe --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c @@ -0,0 +1,95 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_lock.h" +#include "radeon_tex.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#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 *dPriv = rmesa->driDrawable; + __DRIscreenPrivate *sPriv = rmesa->driScreen; + RADEONSAREAPrivPtr sarea = rmesa->sarea; + int stamp = dPriv->lastStamp; + int i; + + drmGetLock( rmesa->driFd, rmesa->hHWContext, 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. + */ + XMESA_VALIDATE_DRAWABLE_INFO( rmesa->display, sPriv, dPriv ); + + if ( stamp != dPriv->lastStamp ) { + rmesa->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + rmesa->SetupDone = 0; + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_CLIPRECTS; + + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = dPriv->pClipRects; + + if ( sarea->ctxOwner != rmesa->hHWContext ) { + sarea->ctxOwner = rmesa->hHWContext; + rmesa->dirty = RADEON_UPLOAD_ALL; + } + + for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != rmesa->lastTexAge[i] ) { + radeonAgeTextures( rmesa, i ); + } + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h new file mode 100644 index 000000000..966f7c80f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h @@ -0,0 +1,112 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_LOCK_H__ +#define __RADEON_LOCK_H__ + +#ifdef GLX_DIRECT_RENDERING + +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->driHwLock, rmesa->hHWContext, \ + (DRM_LOCK_HELD | rmesa->hHWContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( rmesa, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware. + */ +#define UNLOCK_HARDWARE( rmesa ) \ + do { \ + DRM_UNLOCK( rmesa->driFd, \ + rmesa->driHwLock, \ + rmesa->hHWContext ); \ + DEBUG_RESET(); \ + } while (0) + +#endif +#endif /* __RADEON_LOCK_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c new file mode 100644 index 000000000..1c4175575 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c @@ -0,0 +1,168 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "types.h" +#include "fog.h" + +static struct gl_pipeline_stage radeon_fast_stage = { + "Radeon Fast Path", + (PIPE_OP_VERT_XFORM | + PIPE_OP_RAST_SETUP_0 | + PIPE_OP_RAST_SETUP_1 | + PIPE_OP_RENDER), + PIPE_PRECALC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + radeonDDFastPath +}; + +#define ILLEGAL_ENABLES (TEXTURE0_3D | \ + TEXTURE1_3D | \ + ENABLE_TEXMAT0 | \ + ENABLE_TEXMAT1 | \ + ENABLE_TEXGEN0 | \ + ENABLE_TEXGEN1 | \ + ENABLE_USERCLIP | \ + ENABLE_LIGHT | \ + ENABLE_FOG) + +/* Build the PRECALC pipeline with our stage, if possible. Otherwise, + * return GL_FALSE. + */ +GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_pipeline *pipe = &ctx->CVA.pre; + + if ( rmesa->RenderIndex == 0 && + (ctx->Enabled & ILLEGAL_ENABLES) == 0 && + (ctx->Array.Flags & (VERT_OBJ_234 | + VERT_TEX0_4 | + VERT_TEX1_4 | + VERT_ELT)) == (VERT_OBJ_23 | VERT_ELT) ) + { + pipe->stages[0] = &radeon_fast_stage; + pipe->stages[1] = 0; + pipe->new_inputs = ctx->RenderFlags & VERT_DATA; + pipe->ops = pipe->stages[0]->ops; + + rmesa->OnFastPath = GL_TRUE; + return GL_TRUE; + } + + if ( rmesa->OnFastPath ) { + rmesa->OnFastPath = GL_FALSE; + + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->Array.NewArrayState |= ctx->Array.Summary; + } + + return GL_FALSE; +} + + +/* Still do the normal fixup and copy-to-current, so this isn't so + * bad. + */ +#define ILLEGAL_INPUTS_IMM (VERT_OBJ_4 | \ + VERT_TEX0_4 | \ + VERT_TEX1_4 | \ + VERT_MATERIAL) + +static void radeonDDCheckRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *d ) +{ + d->type = PIPE_IMMEDIATE | PIPE_PRECALC; + d->inputs = ctx->RenderFlags; + + /* Radeon requires an extra input: + */ + if ( ctx->FogMode == FOG_FRAGMENT ) + d->inputs |= VERT_FOG_COORD; + + d->outputs = VERT_SETUP_FULL; + + if ( ctx->IndirectTriangles & DD_SW_SETUP ) + d->type = PIPE_IMMEDIATE; +} + + +GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr ) +{ + int i, o; + + for ( i = o = 0 ; i < nr ; i++ ) { + switch ( in[i].ops ) { + /* Completely replace Mesa's fog processing to generate fog + * coordinates instead of messing with colors. + */ + case PIPE_OP_FOG: + out[o] = gl_fog_coord_stage; + o++; + break; + + case PIPE_OP_RAST_SETUP_0: + out[o] = in[i]; + out[o].cva_state_change = (NEW_LIGHTING | + NEW_TEXTURING | + NEW_RASTER_OPS); + out[o].state_change = ~0; + out[o].check = radeonDDCheckPartialRasterSetup; + out[o].run = radeonDDPartialRasterSetup; + o++; + break; + + case PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1: + out[o] = in[i]; + out[o].check = radeonDDCheckRasterSetup; + out[o].run = radeonDDDoRasterSetup; + o++; + break; + + default: + out[o++] = in[i]; + break; + } + } + + return o; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h new file mode 100644 index 000000000..01d5cd884 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h @@ -0,0 +1,54 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_PIPELINE_H__ +#define __RADEON_PIPELINE_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx ); +extern GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr ); + +extern void radeonDDFastPathInit( void ); +extern void radeonDDFastPath( struct vertex_buffer *VB ); + +extern void radeonDDEltPathInit( void ); +extern void radeonDDEltPath( struct vertex_buffer *VB ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c new file mode 100644 index 000000000..dea4bb1ef --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -0,0 +1,220 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_dri.h" + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "mem.h" + +#if 1 +/* Including xf86PciInfo.h introduces a bunch of errors... + */ +#define PCI_CHIP_RADEON_QD 0x5144 +#define PCI_CHIP_RADEON_QE 0x5145 +#define PCI_CHIP_RADEON_QF 0x5146 +#define PCI_CHIP_RADEON_QG 0x5147 +#endif + + +/* Create the device specific screen private data struct. + */ +radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) +{ + radeonScreenPtr radeonScreen; + RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; + + /* Check the DRI version */ + { + int major, minor, patch; + if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { + if ( major != 3 || minor != 0 || patch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if ( sPriv->ddxMajor != 4 || + sPriv->ddxMinor != 0 || + sPriv->ddxPatch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if ( sPriv->drmMajor != 1 || + sPriv->drmMinor != 0 || + sPriv->drmPatch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Allocate the private area */ + radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) ); + if ( !radeonScreen ) return NULL; + + /* This is first since which regions we map depends on whether or + * not we are using a PCI card. + */ + radeonScreen->IsPCI = radeonDRIPriv->IsPCI; + + radeonScreen->mmio.handle = radeonDRIPriv->registerHandle; + radeonScreen->mmio.size = radeonDRIPriv->registerSize; + if ( drmMap( sPriv->fd, + radeonScreen->mmio.handle, + radeonScreen->mmio.size, + &radeonScreen->mmio.map ) ) { + FREE( radeonScreen ); + return NULL; + } + + radeonScreen->status.handle = radeonDRIPriv->statusHandle; + radeonScreen->status.size = radeonDRIPriv->statusSize; + if ( drmMap( sPriv->fd, + radeonScreen->status.handle, + radeonScreen->status.size, + &radeonScreen->status.map ) ) { + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + FREE( radeonScreen ); + return NULL; + } + radeonScreen->scratch = (__volatile__ CARD32 *) + ((GLubyte *)radeonScreen->status.map + RADEON_SCRATCH_REG_OFFSET); + + radeonScreen->buffers = drmMapBufs( sPriv->fd ); + if ( !radeonScreen->buffers ) { + drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + FREE( radeonScreen ); + return NULL; + } + + if ( !radeonScreen->IsPCI ) { + radeonScreen->agpTextures.handle = radeonDRIPriv->agpTexHandle; + radeonScreen->agpTextures.size = radeonDRIPriv->agpTexMapSize; + if ( drmMap( sPriv->fd, + radeonScreen->agpTextures.handle, + radeonScreen->agpTextures.size, + (drmAddressPtr)&radeonScreen->agpTextures.map ) ) { + drmUnmapBufs( radeonScreen->buffers ); + drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + FREE( radeonScreen ); + return NULL; + } + } + + + switch ( radeonDRIPriv->deviceID ) { + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + break; + default: + radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + break; + } + + radeonScreen->cpp = radeonDRIPriv->bpp / 8; + radeonScreen->AGPMode = radeonDRIPriv->AGPMode; + + radeonScreen->frontOffset = radeonDRIPriv->frontOffset; + radeonScreen->frontPitch = radeonDRIPriv->frontPitch; + radeonScreen->backOffset = radeonDRIPriv->backOffset; + radeonScreen->backPitch = radeonDRIPriv->backPitch; + radeonScreen->depthOffset = radeonDRIPriv->depthOffset; + radeonScreen->depthPitch = radeonDRIPriv->depthPitch; + + radeonScreen->texOffset[RADEON_CARD_HEAP] = radeonDRIPriv->textureOffset; + radeonScreen->texSize[RADEON_CARD_HEAP] = radeonDRIPriv->textureSize; + radeonScreen->logTexGranularity[RADEON_CARD_HEAP] = + radeonDRIPriv->log2TexGran; + + if ( radeonScreen->IsPCI ) { + radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; + radeonScreen->texOffset[RADEON_AGP_HEAP] = 0; + radeonScreen->texSize[RADEON_AGP_HEAP] = 0; + radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = 0; + } else { + radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS; + radeonScreen->texOffset[RADEON_AGP_HEAP] = + radeonDRIPriv->agpTexOffset + RADEON_AGP_TEX_OFFSET; + radeonScreen->texSize[RADEON_AGP_HEAP] = radeonDRIPriv->agpTexMapSize; + radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = + radeonDRIPriv->log2AGPTexGran; + } + + radeonScreen->driScreen = sPriv; + + radeonDDSetupInit(); + radeonDDTriangleFuncsInit(); + radeonDDFastPathInit(); + radeonDDEltPathInit(); + + return radeonScreen; +} + +/* Destroy the device specific screen private data struct. + */ +void radeonDestroyScreen( __DRIscreenPrivate *sPriv ) +{ + radeonScreenPtr radeonScreen = (radeonScreenPtr)sPriv->private; + + if ( !radeonScreen->IsPCI ) { + drmUnmap( radeonScreen->agpTextures.map, + radeonScreen->agpTextures.size ); + } + drmUnmapBufs( radeonScreen->buffers ); + drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + + FREE( radeonScreen ); + sPriv->private = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h new file mode 100644 index 000000000..4aeb5d73f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -0,0 +1,87 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_SCREEN_H__ +#define __RADEON_SCREEN_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_sarea.h" + +typedef struct { + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + drmAddress map; /* Mapping of the DRM region */ +} radeonRegionRec, *radeonRegionPtr; + +typedef struct { + + GLint chipset; + GLint cpp; + GLint IsPCI; /* Current card is a PCI card */ + GLint AGPMode; + + GLuint frontOffset; + GLuint frontPitch; + GLuint backOffset; + GLuint backPitch; + + GLuint depthOffset; + GLuint depthPitch; + + /* Shared texture data */ + int numTexHeaps; + int texOffset[RADEON_NR_TEX_HEAPS]; + int texSize[RADEON_NR_TEX_HEAPS]; + int logTexGranularity[RADEON_NR_TEX_HEAPS]; + + radeonRegionRec mmio; + radeonRegionRec status; + radeonRegionRec agpTextures; + + drmBufMapPtr buffers; + + __volatile__ CARD32 *scratch; + + __DRIscreenPrivate *driScreen; + +} radeonScreenRec, *radeonScreenPtr; + +extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ); +extern void radeonDestroyScreen( __DRIscreenPrivate *sPriv ); + +#endif +#endif /* __RADEON_SCREEN_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c new file mode 100644 index 000000000..75f7a1396 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c @@ -0,0 +1,345 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_span.h" + +#define DBG 0 + +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(sPriv->pFB + \ + rmesa->drawOffset + \ + (dPriv->x * radeonScreen->cpp) + \ + (dPriv->y * pitch)); \ + char *read_buf = (char *)(sPriv->pFB + \ + rmesa->readOffset + \ + (dPriv->x * radeonScreen->cpp) + \ + (dPriv->y * pitch)); \ + GLushort p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint pitch = radeonScreen->depthPitch * radeonScreen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(sPriv->pFB + \ + radeonScreen->depthOffset + \ + (dPriv->x * radeonScreen->cpp) + \ + (dPriv->y * pitch)); \ + (void) buf + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +#define INIT_MONO_PIXEL( p ) p = rmesa->Color + +#define CLIPPIXEL( _x, _y ) \ + ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) + + +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ + if ((_y < miny) || (_y >= maxy)) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \ + if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \ + } + +#define Y_FLIP( _y ) (height - _y - 1) + + +#define HW_LOCK() \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + FLUSH_BATCH( rmesa ); \ + LOCK_HARDWARE( rmesa ); \ + radeonWaitForIdleLocked( rmesa ); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + int _nc = dPriv->numClipRects; \ + \ + while ( _nc-- ) { \ + int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ + int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ + int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \ + int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; + +#define HW_ENDCLIPLOOP() \ + } \ + } while (0) + +#define HW_UNLOCK() \ + UNLOCK_HARDWARE( rmesa ) + + + +/* ================================================================ + * Color buffer + */ + +/* 16 bit, RGB565 color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 8) & 0xf8; \ + rgba[1] = (p >> 3) & 0xfc; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 0xff; \ + if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \ + if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \ + if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \ + } while (0) + +#define TAG(x) radeon##x##_RGB565 +#include "spantmp.h" + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16) | \ + (a << 24) ) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ +} while (0) + +#define TAG(x) radeon##x##_ARGB8888 +#include "spantmp.h" + + + +/* ================================================================ + * Depth buffer + */ + +/* The Radeon has depth tiling on all the time, so we have to convert + * the x,y coordinates into the memory bus address (mba) in the same + * manner as the engine. In each case, the linear block address (ba) + * is calculated, and then wired with x and y to produce the final + * memory address. + */ +static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, + GLint x, GLint y ) +{ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; + GLuint pitch = radeonScreen->frontPitch; + GLuint ba, address = 0; /* a[0] = 0 */ + + ba = (y / 16) * (pitch / 32) + (x / 32); + + address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ + address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ + address |= (x & 0x8) << 4; /* a[7] = x[3] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + +static __inline GLuint radeon_mba_z32( radeonContextPtr rmesa, + GLint x, GLint y ) +{ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; + GLuint pitch = radeonScreen->frontPitch; + GLuint ba, address = 0; /* a[0..1] = 0 */ + + ba = (y / 16) * (pitch / 16) + (x / 16); + + address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ + address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ + address |= + (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= + (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + + +/* 16-bit depth buffer functions + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + radeon_mba_z16( rmesa, _x, _y )) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + radeon_mba_z16( rmesa, _x, _y )); + +#define TAG(x) radeon##x##_16 +#include "depthtmp.h" + +/* 24 bit depth, 8 bit stencil depthbuffer functions + */ +#define WRITE_DEPTH( _x, _y, d ) \ +do { \ + GLuint tmp = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )); \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )) = tmp; \ +} while (0) + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )) & 0x00ffffff; + +#define TAG(x) radeon##x##_24_8 +#include "depthtmp.h" + + +/* ================================================================ + * Stencil buffer + */ + +/* 24 bit depth, 8 bit stencil depthbuffer functions + */ +#define WRITE_STENCIL( _x, _y, d ) \ +do { \ + GLuint tmp = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )); \ + tmp &= 0x00ffffff; \ + tmp |= (((d) & 0xff) << 24); \ + *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )) = tmp; \ +} while (0) + +#define READ_STENCIL( d, _x, _y ) \ +do { \ + GLuint tmp = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )); \ + tmp &= 0xff000000; \ + d = tmp >> 24; \ +} while (0) + +#define TAG(x) radeon##x##_24_8 +#include "stenciltmp.h" + + + +void radeonDDInitSpanFuncs( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch ( rmesa->radeonScreen->cpp ) { + case 2: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_RGB565; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_RGB565; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB565; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_RGB565; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB565; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_RGB565; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_RGB565; + break; + + case 4: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_ARGB8888; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_ARGB8888; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB8888; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_ARGB8888; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB8888; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_ARGB8888; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_ARGB8888; + break; + + default: + break; + } + + switch ( rmesa->glCtx->Visual->DepthBits ) { + case 16: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_16; + break; + + case 24: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_24_8; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_24_8; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_24_8; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_24_8; + + ctx->Driver.ReadStencilSpan = radeonReadStencilSpan_24_8; + ctx->Driver.WriteStencilSpan = radeonWriteStencilSpan_24_8; + ctx->Driver.ReadStencilPixels = radeonReadStencilPixels_24_8; + ctx->Driver.WriteStencilPixels = radeonWriteStencilPixels_24_8; + break; + + default: + break; + } + + ctx->Driver.WriteCI8Span = NULL; + ctx->Driver.WriteCI32Span = NULL; + ctx->Driver.WriteMonoCISpan = NULL; + ctx->Driver.WriteCI32Pixels = NULL; + ctx->Driver.WriteMonoCIPixels = NULL; + ctx->Driver.ReadCI32Span = NULL; + ctx->Driver.ReadCI32Pixels = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h new file mode 100644 index 000000000..e9cb056b8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h @@ -0,0 +1,45 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_SPAN_H__ +#define __RADEON_SPAN_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonDDInitSpanFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c new file mode 100644 index 000000000..7aa4bc6f6 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -0,0 +1,1338 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "pb.h" +#include "enums.h" + + +/* ============================================================= + * Alpha blending + */ + +static void radeonUpdateAlphaMode( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 a = rmesa->setup.pp_misc; + CARD32 p = rmesa->setup.pp_cntl; + CARD32 b = rmesa->setup.rb3d_blendcntl; + CARD32 c = rmesa->setup.rb3d_cntl; + + if ( ctx->Color.AlphaEnabled ) { + GLubyte ref = ctx->Color.AlphaRef; + + a &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK); + + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: + a |= RADEON_ALPHA_TEST_FAIL; + break; + case GL_LESS: + a |= RADEON_ALPHA_TEST_LESS; + break; + case GL_LEQUAL: + a |= RADEON_ALPHA_TEST_LEQUAL; + break; + case GL_EQUAL: + a |= RADEON_ALPHA_TEST_EQUAL; + break; + case GL_GEQUAL: + a |= RADEON_ALPHA_TEST_GEQUAL; + break; + case GL_GREATER: + a |= RADEON_ALPHA_TEST_GREATER; + break; + case GL_NOTEQUAL: + a |= RADEON_ALPHA_TEST_NEQUAL; + break; + case GL_ALWAYS: + a |= RADEON_ALPHA_TEST_PASS; + break; + } + + a |= (ref & RADEON_REF_ALPHA_MASK); + p |= RADEON_ALPHA_TEST_ENABLE; + } else { + p &= ~RADEON_ALPHA_TEST_ENABLE; + } + + if ( ctx->Color.BlendEnabled ) { + b &= ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK); + + switch ( ctx->Color.BlendSrcRGB ) { + case GL_ZERO: + b |= RADEON_SRC_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= RADEON_SRC_BLEND_GL_ONE; + break; + case GL_DST_COLOR: + b |= RADEON_SRC_BLEND_GL_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA: + b |= RADEON_SRC_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= RADEON_SRC_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + case GL_SRC_ALPHA_SATURATE: + b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE; + break; + } + + switch ( ctx->Color.BlendDstRGB ) { + case GL_ZERO: + b |= RADEON_DST_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= RADEON_DST_BLEND_GL_ONE; + break; + case GL_SRC_COLOR: + b |= RADEON_DST_BLEND_GL_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + b |= RADEON_DST_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= RADEON_DST_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + } + + c |= RADEON_ALPHA_BLEND_ENABLE; + } else { + c &= ~RADEON_ALPHA_BLEND_ENABLE; + } + + if ( rmesa->setup.pp_misc != a ) { + rmesa->setup.pp_misc = a; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( rmesa->setup.rb3d_blendcntl != b ) { + rmesa->setup.rb3d_blendcntl = b; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( rmesa->setup.rb3d_cntl != c ) { + rmesa->setup.rb3d_cntl = c; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } +} + +static void radeonDDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendEquation( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + + +/* ============================================================= + * Depth testing + */ + +static void radeonUpdateZMode( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 z = rmesa->setup.rb3d_zstencilcntl; + CARD32 c = rmesa->setup.rb3d_cntl; + + if ( ctx->Depth.Test ) { + z &= ~RADEON_Z_TEST_MASK; + + switch ( ctx->Depth.Func ) { + case GL_NEVER: + z |= RADEON_Z_TEST_NEVER; + break; + case GL_ALWAYS: + z |= RADEON_Z_TEST_ALWAYS; + break; + case GL_LESS: + z |= RADEON_Z_TEST_LESS; + break; + case GL_LEQUAL: + z |= RADEON_Z_TEST_LEQUAL; + break; + case GL_EQUAL: + z |= RADEON_Z_TEST_EQUAL; + break; + case GL_GEQUAL: + z |= RADEON_Z_TEST_GEQUAL; + break; + case GL_GREATER: + z |= RADEON_Z_TEST_GREATER; + break; + case GL_NOTEQUAL: + z |= RADEON_Z_TEST_NEQUAL; + break; + } + + c |= RADEON_Z_ENABLE; + } else { + c &= ~RADEON_Z_ENABLE; + } + + if ( ctx->Depth.Mask ) { + z |= RADEON_Z_WRITE_ENABLE; + } else { + z &= ~RADEON_Z_WRITE_ENABLE; + } + + if ( rmesa->setup.rb3d_zstencilcntl != z ) { + rmesa->setup.rb3d_zstencilcntl = z; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( rmesa->setup.rb3d_cntl != c ) { + rmesa->setup.rb3d_cntl = c; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDDepthFunc( GLcontext *ctx, GLenum func ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_DEPTH; +} + +static void radeonDDDepthMask( GLcontext *ctx, GLboolean flag ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_DEPTH; +} + +static void radeonDDClearDepth( GLcontext *ctx, GLclampd d ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch ( rmesa->setup.rb3d_zstencilcntl & RADEON_DEPTH_FORMAT_MASK ) { + case RADEON_DEPTH_FORMAT_16BIT_INT_Z: + rmesa->ClearDepth = d * 0x0000ffff; + break; + case RADEON_DEPTH_FORMAT_24BIT_INT_Z: + rmesa->ClearDepth = d * 0x00ffffff; + break; + } +} + + +/* ============================================================= + * Fog + */ + +static void radeonUpdateFogAttrib( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 p = rmesa->setup.pp_cntl; + GLubyte c[4]; + CARD32 col; + + if ( ctx->FogMode == FOG_FRAGMENT ) { + p |= RADEON_FOG_ENABLE; + } else { + p &= ~RADEON_FOG_ENABLE; + } + + FLOAT_RGB_TO_UBYTE_RGB( c, ctx->Fog.Color ); + col = radeonPackColor( 4, c[0], c[1], c[2], 0 ); + + if ( rmesa->setup.pp_fog_color != col ) { + rmesa->setup.pp_fog_color = col; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_FOG; +} + + +/* ============================================================= + * Clipping + */ + +static void radeonUpdateClipping( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( rmesa->driDrawable ) { + __DRIdrawablePrivate *drawable = rmesa->driDrawable; + int x = 0; + int y = 0; + int w = drawable->w - 1; + int h = drawable->h - 1; + + if ( ctx->Scissor.Enabled ) { + if ( ctx->Scissor.X > x ) { + x = ctx->Scissor.X; + } + if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y ) { + y = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height; + } + if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < w ) { + w = ctx->Scissor.X + ctx->Scissor.Width - 1; + } + if ( drawable->h - ctx->Scissor.Y - 1 < h ) { + h = drawable->h - ctx->Scissor.Y - 1; + } + } + + rmesa->scissor_rect.x1 = x + rmesa->driDrawable->x; + rmesa->scissor_rect.y1 = y + rmesa->driDrawable->y; + rmesa->scissor_rect.x2 = w + rmesa->driDrawable->x; + rmesa->scissor_rect.y2 = h + rmesa->driDrawable->y; + + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + } +} + +static void radeonDDScissor( GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CLIP; +} + + +/* ============================================================= + * Culling + */ + +static void radeonUpdateCull( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 s = rmesa->setup.se_cntl; + + s &= ~RADEON_FFACE_CULL_DIR_MASK; + + switch ( ctx->Polygon.FrontFace ) { + case GL_CW: + s |= RADEON_FFACE_CULL_CW; + break; + case GL_CCW: + s |= RADEON_FFACE_CULL_CCW; + break; + } + + s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~RADEON_FFACE_SOLID; + break; + case GL_BACK: + s &= ~RADEON_BFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); + break; + } + } + + if ( rmesa->setup.se_cntl != s ) { + rmesa->setup.se_cntl = s; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_SETUP; + } +} + +static void radeonDDCullFace( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CULL; +} + +static void radeonDDFrontFace( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CULL; +} + + +/* ============================================================= + * Masks + */ + +static void radeonUpdateMasks( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + GLuint mask = radeonPackColor( rmesa->radeonScreen->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); + + if ( rmesa->setup.rb3d_planemask != mask ) { + rmesa->setup.rb3d_planemask = mask; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } +} + +static GLboolean radeonDDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_MASKS; + + return GL_TRUE; +} + + +/* ============================================================= + * Rendering attributes + * + * We really don't want to recalculate all this every time we bind a + * texture. These things shouldn't change all that often, so it makes + * sense to break them out of the core texture state update routines. + */ + +static void radeonDDLightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { + CARD32 p = rmesa->setup.pp_cntl; + + FLUSH_BATCH( rmesa ); + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + p |= RADEON_SPECULAR_ENABLE; + } else { + p &= ~RADEON_SPECULAR_ENABLE; + } + + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + } +} + +static void radeonDDShadeModel( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 s = rmesa->setup.se_cntl; + + s &= ~(RADEON_DIFFUSE_SHADE_MASK | + RADEON_ALPHA_SHADE_MASK | + RADEON_SPECULAR_SHADE_MASK | + RADEON_FOG_SHADE_MASK); + + switch ( mode ) { + case GL_FLAT: + s |= (RADEON_DIFFUSE_SHADE_FLAT | + RADEON_ALPHA_SHADE_FLAT | + RADEON_SPECULAR_SHADE_FLAT | + RADEON_FOG_SHADE_FLAT); + break; + case GL_SMOOTH: + s |= (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD); + break; + default: + return; + } + + if ( rmesa->setup.se_cntl != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.se_cntl = s; + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_SETUP; + } +} + + +/* ============================================================= + * Window position + */ + +void radeonUpdateWindow( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + GLfloat xoffset = (GLfloat)dPriv->x; + GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; + const GLfloat one = 1.0; +#if 0 + CARD32 m = rmesa->setup.re_misc; + CARD32 sx, sy; +#endif + + rmesa->setup.se_vport_xscale = *(GLuint *)&one; + rmesa->setup.se_vport_xoffset = *(GLuint *)&xoffset; + rmesa->setup.se_vport_yscale = *(GLuint *)&one; + rmesa->setup.se_vport_yoffset = *(GLuint *)&yoffset; + rmesa->setup.se_vport_zscale = *(GLuint *)&rmesa->depth_scale; + rmesa->setup.se_vport_zoffset = 0x00000000; + +#if 0 + /* FIXME: This appears to be broken... + */ + m &= ~(RADEON_STIPPLE_X_OFFSET_MASK | + RADEON_STIPPLE_Y_OFFSET_MASK); + + sx = rmesa->driDrawable->x & RADEON_STIPPLE_COORD_MASK; + sy = rmesa->driDrawable->y & RADEON_STIPPLE_COORD_MASK; + + m |= ((sx << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (sy << RADEON_STIPPLE_Y_OFFSET_SHIFT)); + + if ( rmesa->setup.re_misc != m ) { + rmesa->setup.re_misc = m; + rmesa->dirty |= RADEON_UPLOAD_MISC; + } +#endif + rmesa->dirty |= RADEON_UPLOAD_VIEWPORT; +} + + +/* ============================================================= + * Miscellaneous + */ + +static void radeonDDClearColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + rmesa->ClearColor = radeonPackColor( rmesa->radeonScreen->cpp, + r, g, b, a ); +} + +static void radeonDDColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + rmesa->Color = radeonPackColor( rmesa->radeonScreen->cpp, + r, g, b, a ); +} + +static void radeonDDLogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + if ( ctx->Color.ColorLogicOpEnabled ) { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + + /* FIXME: We can do color logic ops. + */ + if ( opcode == GL_COPY ) { + rmesa->Fallback &= ~RADEON_FALLBACK_LOGICOP; + } else { + rmesa->Fallback |= RADEON_FALLBACK_LOGICOP; + } + } +} + +static GLboolean radeonDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int found = GL_TRUE; + + FLUSH_BATCH( rmesa ); + + if ( rmesa->DrawBuffer != mode ) { + rmesa->DrawBuffer = mode; + rmesa->Fallback &= ~RADEON_FALLBACK_DRAW_BUFFER; + + switch ( mode ) { + case GL_FRONT_LEFT: + rmesa->drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->drawPitch = rmesa->radeonScreen->frontPitch; + break; + case GL_BACK_LEFT: + rmesa->drawOffset = rmesa->radeonScreen->backOffset; + rmesa->drawPitch = rmesa->radeonScreen->backPitch; + break; + default: + rmesa->Fallback |= RADEON_FALLBACK_DRAW_BUFFER; + found = GL_FALSE; + break; + } + + rmesa->setup.rb3d_coloroffset = + (rmesa->drawOffset & RADEON_COLOROFFSET_MASK); + rmesa->setup.rb3d_colorpitch = rmesa->drawPitch; + + rmesa->new_state |= RADEON_NEW_WINDOW; + } + + return found; +} + +static void radeonDDSetReadBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + rmesa->Fallback &= ~RADEON_FALLBACK_READ_BUFFER; + + switch ( mode ) { + case GL_FRONT_LEFT: + rmesa->readOffset = rmesa->radeonScreen->frontOffset; + rmesa->readPitch = rmesa->radeonScreen->frontPitch; + break; + case GL_BACK_LEFT: + rmesa->readOffset = rmesa->radeonScreen->backOffset; + rmesa->readPitch = rmesa->radeonScreen->backPitch; + break; + default: + rmesa->Fallback |= RADEON_FALLBACK_READ_BUFFER; + break; + } +} + + +/* ============================================================= + * Polygon stipple + */ + +static void radeonDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint *stipple = (GLuint *)mask; + + FLUSH_BATCH( rmesa ); + + if ( ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON ) { + rmesa->setup.pp_cntl |= RADEON_STIPPLE_ENABLE; + } else { + rmesa->setup.pp_cntl &= ~RADEON_STIPPLE_ENABLE; + } + + LOCK_HARDWARE( rmesa ); + + /* FIXME: Use window x,y offsets into stipple RAM. + */ + drmRadeonPolygonStipple( rmesa->driFd, stipple ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; +} + + +/* ============================================================= + * State enable/disable + */ + +static void radeonDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch ( cap ) { + case GL_ALPHA_TEST: + case GL_BLEND: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; + break; + + case GL_CULL_FACE: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CULL; + break; + + case GL_DEPTH_TEST: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_DEPTH; + break; + + case GL_DITHER: + do { + CARD32 r = rmesa->setup.rb3d_cntl; + FLUSH_BATCH( rmesa ); + + if ( ctx->Color.DitherFlag ) { + r |= RADEON_DITHER_ENABLE; + } else { + r &= ~RADEON_DITHER_ENABLE; + } + + if ( rmesa->setup.rb3d_cntl != r ) { + rmesa->setup.rb3d_cntl = r; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + } while (0); + break; + + case GL_FOG: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_FOG; + break; + + case GL_INDEX_LOGIC_OP: + case GL_COLOR_LOGIC_OP: + FLUSH_BATCH( rmesa ); + if ( state && ctx->Color.LogicOp != GL_COPY ) { + rmesa->Fallback |= RADEON_FALLBACK_LOGICOP; + } else { + rmesa->Fallback &= ~RADEON_FALLBACK_LOGICOP; + } + break; + + case GL_SCISSOR_TEST: + FLUSH_BATCH( rmesa ); + rmesa->scissor = state; + rmesa->new_state |= RADEON_NEW_CLIP; + break; + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_TEXTURE; + break; + + case GL_POLYGON_STIPPLE: + if ( ctx->PB->primitive == GL_POLYGON ) { + FLUSH_BATCH( rmesa ); + if ( state ) { + rmesa->setup.pp_cntl |= RADEON_STIPPLE_ENABLE; + } else { + rmesa->setup.pp_cntl &= ~RADEON_STIPPLE_ENABLE; + } + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + break; + + default: + return; + } +} + + +/* ============================================================= + * State initialization, management + */ + +static void radeonDDPrintDirty( const char *msg, GLuint state ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & RADEON_UPLOAD_CONTEXT) ? "context, " : "", + (state & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", + (state & RADEON_UPLOAD_LINE) ? "line, " : "", + (state & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", + (state & RADEON_UPLOAD_MASKS) ? "masks, " : "", + (state & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", + (state & RADEON_UPLOAD_SETUP) ? "setup, " : "", + (state & RADEON_UPLOAD_TCL) ? "tcl, " : "", + (state & RADEON_UPLOAD_MISC) ? "misc, " : "", + (state & RADEON_UPLOAD_TEX0) ? "tex0, " : "", + (state & RADEON_UPLOAD_TEX1) ? "tex1, " : "", + (state & RADEON_UPLOAD_TEX2) ? "tex2, " : "", + (state & RADEON_UPLOAD_TEX0IMAGES) ? "tex0 images, " : "", + (state & RADEON_UPLOAD_TEX1IMAGES) ? "tex1 images, " : "", + (state & RADEON_UPLOAD_TEX2IMAGES) ? "tex2 images, " : "", + (state & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (state & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); +} + +/* + * Load the current context's state into the hardware. + * + * NOTE: Be VERY careful about ensuring the context state is marked for + * upload, the only place it shouldn't be uploaded is when the setup + * state has changed in ReducedPrimitiveChange as this comes right after + * a state update. + * + * Blits of any type should always upload the context and masks after + * they are done. + */ +void radeonEmitHwStateLocked( radeonContextPtr rmesa ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + radeon_context_regs_t *regs = &(rmesa->setup); + radeonTexObjPtr t0 = rmesa->CurrentTexObj[0]; + radeonTexObjPtr t1 = rmesa->CurrentTexObj[1]; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + radeonDDPrintDirty( "radeonEmitHwStateLocked", rmesa->dirty ); + } + + if ( (rmesa->dirty & RADEON_UPLOAD_TEX0IMAGES) && t0 ) { + radeonUploadTexImages( rmesa, t0 ); + rmesa->dirty &= ~RADEON_UPLOAD_TEX0IMAGES; + } + if ( (rmesa->dirty & RADEON_UPLOAD_TEX1IMAGES) && t1 ) { + radeonUploadTexImages( rmesa, t1 ); + rmesa->dirty &= ~RADEON_UPLOAD_TEX1IMAGES; + } + if ( rmesa->dirty & RADEON_UPLOAD_TEX2IMAGES ) { + /* FIXME: Enable the third texture unit... */ + rmesa->dirty &= ~RADEON_UPLOAD_TEX2IMAGES; + } + + if ( rmesa->dirty & (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_VERTFMT | + RADEON_UPLOAD_LINE | + RADEON_UPLOAD_BUMPMAP | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_VIEWPORT | + RADEON_UPLOAD_SETUP | + RADEON_UPLOAD_TCL | + RADEON_UPLOAD_MISC) ) { + memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); + } + + /* Assemble the texture state, combining the texture object and + * texture environment state into the hardware texture unit state. + */ + if ( (rmesa->dirty & RADEON_UPLOAD_TEX0) && t0 ) { + radeon_texture_regs_t *tex = &sarea->TexState[0]; + + tex->pp_txfilter = t0->setup.pp_txfilter | rmesa->lod_bias[0] << 8; + tex->pp_txformat = t0->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ0; + tex->pp_txoffset = t0->setup.pp_txoffset; + + tex->pp_txcblend = rmesa->color_combine[0]; + tex->pp_txablend = rmesa->alpha_combine[0]; + tex->pp_tfactor = rmesa->env_color[0]; + + tex->pp_border_color = t0->setup.pp_border_color; + } + + if ( (rmesa->dirty & RADEON_UPLOAD_TEX1) && t1 ) { + radeon_texture_regs_t *tex = &sarea->TexState[1]; + + tex->pp_txfilter = t1->setup.pp_txfilter | rmesa->lod_bias[1] << 8; + tex->pp_txformat = t1->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ1; + tex->pp_txoffset = t1->setup.pp_txoffset; + + tex->pp_txcblend = rmesa->color_combine[1]; + tex->pp_txablend = rmesa->alpha_combine[1]; + tex->pp_tfactor = rmesa->env_color[1]; + + tex->pp_border_color = t1->setup.pp_border_color; + } + + if ( rmesa->dirty & RADEON_UPLOAD_TEX2 ) { + /* FIXME: Enable the third texture unit... */ + memset( &sarea->TexState[2], 0, sizeof(sarea->TexState[2]) ); + } + + sarea->vertsize = rmesa->vertsize; + sarea->vc_format = rmesa->vc_format; + + sarea->dirty |= rmesa->dirty; + rmesa->dirty &= RADEON_UPLOAD_CLIPRECTS; +} + +static void radeonDDPrintState( const char *msg, GLuint flags ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & RADEON_NEW_CONTEXT) ? "context, " : "", + (flags & RADEON_NEW_ALPHA) ? "alpha, " : "", + (flags & RADEON_NEW_DEPTH) ? "depth, " : "", + (flags & RADEON_NEW_FOG) ? "fog, " : "", + (flags & RADEON_NEW_CLIP) ? "clip, " : "", + (flags & RADEON_NEW_TEXTURE) ? "texture, " : "", + (flags & RADEON_NEW_CULL) ? "cull, " : "", + (flags & RADEON_NEW_MASKS) ? "masks, " : "", + (flags & RADEON_NEW_WINDOW) ? "window, " : "" ); +} + +void radeonDDUpdateHWState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int new_state = rmesa->new_state; + + if ( new_state ) { + FLUSH_BATCH( rmesa ); + + rmesa->new_state = 0; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) + radeonDDPrintState( "radeonUpdateHwState", new_state ); + + /* Update the various parts of the context's state. + */ + if ( new_state & RADEON_NEW_ALPHA ) + radeonUpdateAlphaMode( ctx ); + + if ( new_state & RADEON_NEW_DEPTH ) + radeonUpdateZMode( ctx ); + + if ( new_state & RADEON_NEW_FOG ) + radeonUpdateFogAttrib( ctx ); + + if ( new_state & RADEON_NEW_CLIP ) + radeonUpdateClipping( ctx ); + + if ( new_state & RADEON_NEW_CULL ) + radeonUpdateCull( ctx ); + + if ( new_state & RADEON_NEW_MASKS ) + radeonUpdateMasks( ctx ); + + if ( new_state & RADEON_NEW_WINDOW ) + radeonUpdateWindow( ctx ); + + if ( new_state & RADEON_NEW_TEXTURE ) + radeonUpdateTextureState( ctx ); + } +} + +/* This is called when Mesa switches between rendering triangle + * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc), + * and lines, points and bitmaps. + * + * As the radeon uses triangles to render lines and points, it is + * necessary to turn off hardware culling when rendering these + * primitives. + */ +static void radeonDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 s = rmesa->setup.se_cntl; + + s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~RADEON_FFACE_SOLID; + break; + case GL_BACK: + s &= ~RADEON_BFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); + break; + } + } + + if ( rmesa->setup.se_cntl != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.se_cntl = s; + + /* NOTE: Only upload the setup state, everything else has been + * uploaded by the usual means already. Also, note that this is + * an optimization (see comment in the kernel's radeon_state.c), + * which will not be necessary when/if we use the Radeon's + * native point/line support. + */ + rmesa->dirty |= RADEON_UPLOAD_SETUP; + } +} + + +#define INTERESTED (~(NEW_MODELVIEW | \ + NEW_PROJECTION | \ + NEW_TEXTURE_MATRIX | \ + NEW_USER_CLIP | \ + NEW_CLIENT_STATE)) + +void radeonDDUpdateState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( ctx->NewState & INTERESTED ) { + radeonDDChooseRenderState( ctx ); + radeonDDChooseRasterSetupFunc( ctx ); + } + + /* Need to do this here to detect texture fallbacks before + * setting triangle functions. + * GH: Do we need this anymore? The Radeon doesn't really have + * texturing fallbacks like the r128... + */ + if ( rmesa->new_state & RADEON_NEW_TEXTURE ) { + radeonDDUpdateHWState( ctx ); + } + + if ( !rmesa->Fallback ) { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= rmesa->IndirectTriangles; + + ctx->Driver.PointsFunc = rmesa->PointsFunc; + ctx->Driver.LineFunc = rmesa->LineFunc; + ctx->Driver.TriangleFunc = rmesa->TriangleFunc; + ctx->Driver.QuadFunc = rmesa->QuadFunc; + } +} + + +/* Initialize the context's hardware state. + */ +void radeonDDInitState( radeonContextPtr rmesa ) +{ + GLuint color_fmt, depth_fmt; + + switch ( rmesa->radeonScreen->cpp ) { + case 2: + color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 4: + color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + default: + fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); + exit( -1 ); + } + + rmesa->ClearColor = 0x00000000; + + switch ( rmesa->glCtx->Visual->DepthBits ) { + case 16: + rmesa->ClearDepth = 0x0000ffff; + depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + rmesa->depth_scale = 1.0 / (GLfloat)0xffff; + break; + case 24: + rmesa->ClearDepth = 0x00ffffff; + depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + rmesa->depth_scale = 1.0 / (GLfloat)0xffffff; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + rmesa->glCtx->Visual->DepthBits ); + exit( -1 ); + } + + rmesa->RenderIndex = RADEON_FALLBACK_BIT; + rmesa->PointsFunc = NULL; + rmesa->LineFunc = NULL; + rmesa->TriangleFunc = NULL; + rmesa->QuadFunc = NULL; + + rmesa->IndirectTriangles = 0; + rmesa->Fallback = 0; + + if ( rmesa->glCtx->Visual->DBflag ) { + rmesa->DrawBuffer = GL_BACK_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->radeonScreen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->radeonScreen->backPitch; + } else { + rmesa->DrawBuffer = GL_FRONT_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->radeonScreen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->radeonScreen->frontPitch; + } + + /* Harware state: + */ + rmesa->setup.pp_misc = (RADEON_ALPHA_TEST_PASS | + RADEON_CHROMA_FUNC_FAIL | + RADEON_CHROMA_KEY_NEAREST | + RADEON_SHADOW_FUNC_EQUAL | + RADEON_SHADOW_PASS_1 | + RADEON_RIGHT_HAND_CUBE_OGL); + + rmesa->setup.pp_fog_color = ((0x00000000 & RADEON_FOG_COLOR_MASK) | + RADEON_FOG_VERTEX | + RADEON_FOG_USE_DEPTH); + + rmesa->setup.re_solid_color = 0x00000000; + + rmesa->setup.rb3d_blendcntl = (RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO ); + + rmesa->setup.rb3d_depthoffset = rmesa->radeonScreen->depthOffset; + + rmesa->setup.rb3d_depthpitch = ((rmesa->radeonScreen->depthPitch & + RADEON_DEPTHPITCH_MASK) | + RADEON_DEPTH_ENDIAN_NO_SWAP); + + rmesa->setup.rb3d_zstencilcntl = (depth_fmt | + RADEON_Z_TEST_LESS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE); + + rmesa->setup.pp_cntl = (RADEON_SCISSOR_ENABLE | + RADEON_ANTI_ALIAS_NONE); + + rmesa->setup.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + color_fmt | + RADEON_ZBLOCK16); + + rmesa->setup.rb3d_coloroffset = (rmesa->drawOffset & + RADEON_COLOROFFSET_MASK); + + rmesa->setup.re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) | + (0x7ff << RADEON_RE_HEIGHT_SHIFT)); + + rmesa->setup.rb3d_colorpitch = ((rmesa->drawPitch & + RADEON_COLORPITCH_MASK) | + RADEON_COLOR_ENDIAN_NO_SWAP); + + rmesa->setup.se_cntl = (RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD | + RADEON_VPORT_XY_XFORM_ENABLE | + RADEON_VPORT_Z_XFORM_ENABLE | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + rmesa->setup.se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + + rmesa->setup.re_line_pattern = ((0x0000 & RADEON_LINE_PATTERN_MASK) | + (0 << RADEON_LINE_REPEAT_COUNT_SHIFT) | + (0 << RADEON_LINE_PATTERN_START_SHIFT) | + RADEON_LINE_PATTERN_LITTLE_BIT_ORDER); + + rmesa->setup.re_line_state = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | + (0 << RADEON_LINE_CURRENT_COUNT_SHIFT)); + + rmesa->setup.se_line_width = 0x0000000; + + rmesa->setup.pp_lum_matrix = 0x00000000; + + rmesa->setup.pp_rot_matrix_0 = 0x00000000; + rmesa->setup.pp_rot_matrix_1 = 0x00000000; + + rmesa->setup.rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); + + rmesa->setup.rb3d_ropcntl = 0x00000000; + rmesa->setup.rb3d_planemask = 0xffffffff; + + rmesa->setup.se_vport_xscale = 0x00000000; + rmesa->setup.se_vport_xoffset = 0x00000000; + rmesa->setup.se_vport_yscale = 0x00000000; + rmesa->setup.se_vport_yoffset = 0x00000000; + rmesa->setup.se_vport_zscale = 0x00000000; + rmesa->setup.se_vport_zoffset = 0x00000000; + + rmesa->setup.se_cntl_status = (RADEON_VC_NO_SWAP | + RADEON_TCL_BYPASS); + +#ifdef TCL_ENABLE + /* FIXME: Obviously these need to be properly initialized */ + rmesa->setup.se_tcl_material_emmissive.red = 0x00000000; + rmesa->setup.se_tcl_material_emmissive.green = 0x00000000; + rmesa->setup.se_tcl_material_emmissive.blue = 0x00000000; + rmesa->setup.se_tcl_material_emmissive.alpha = 0x00000000; + + rmesa->setup.se_tcl_material_ambient.red = 0x00000000; + rmesa->setup.se_tcl_material_ambient.green = 0x00000000; + rmesa->setup.se_tcl_material_ambient.blue = 0x00000000; + rmesa->setup.se_tcl_material_ambient.alpha = 0x00000000; + + rmesa->setup.se_tcl_material_diffuse.red = 0x00000000; + rmesa->setup.se_tcl_material_diffuse.green = 0x00000000; + rmesa->setup.se_tcl_material_diffuse.blue = 0x00000000; + rmesa->setup.se_tcl_material_diffuse.alpha = 0x00000000; + + rmesa->setup.se_tcl_material_specular.red = 0x00000000; + rmesa->setup.se_tcl_material_specular.green = 0x00000000; + rmesa->setup.se_tcl_material_specular.blue = 0x00000000; + rmesa->setup.se_tcl_material_specular.alpha = 0x00000000; + + rmesa->setup.se_tcl_shininess = 0x00000000; + rmesa->setup.se_tcl_output_vtx_fmt = 0x00000000; + rmesa->setup.se_tcl_output_vtx_sel = 0x00000000; + rmesa->setup.se_tcl_matrix_select_0 = 0x00000000; + rmesa->setup.se_tcl_matrix_select_1 = 0x00000000; + rmesa->setup.se_tcl_ucp_vert_blend_ctl = 0x00000000; + rmesa->setup.se_tcl_texture_proc_ctl = 0x00000000; + rmesa->setup.se_tcl_light_model_ctl = 0x00000000; + for ( i = 0 ; i < 4 ; i++ ) { + rmesa->setup.se_tcl_per_light_ctl[i] = 0x00000000; + } +#endif + + rmesa->setup.re_top_left = ((0 << RADEON_RE_LEFT_SHIFT) | + (0 << RADEON_RE_TOP_SHIFT) ); + + rmesa->setup.re_misc = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | + RADEON_STIPPLE_LITTLE_BIT_ORDER); + + rmesa->env_color[0] = 0x00000000; + rmesa->env_color[1] = 0x00000000; + rmesa->env_color[2] = 0x00000000; + + rmesa->new_state = RADEON_NEW_ALL; +} + +/* Initialize the driver's state functions. + */ +void radeonDDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = radeonDDUpdateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = radeonDDClearColor; + ctx->Driver.Index = NULL; + ctx->Driver.Color = radeonDDColor; + ctx->Driver.SetDrawBuffer = radeonDDSetDrawBuffer; + ctx->Driver.SetReadBuffer = radeonDDSetReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = radeonDDColorMask; + ctx->Driver.LogicOp = NULL; + ctx->Driver.Dither = NULL; + + ctx->Driver.NearFar = NULL; + + ctx->Driver.RenderStart = radeonDDUpdateHWState; + ctx->Driver.RenderFinish = NULL; + ctx->Driver.RasterSetup = NULL; + + ctx->Driver.RenderVBClippedTab = NULL; + ctx->Driver.RenderVBCulledTab = NULL; + ctx->Driver.RenderVBRawTab = NULL; + + ctx->Driver.ReducedPrimitiveChange = radeonDDReducedPrimitiveChange; + ctx->Driver.MultipassFunc = NULL; + + ctx->Driver.AlphaFunc = radeonDDAlphaFunc; + ctx->Driver.BlendEquation = radeonDDBlendEquation; + ctx->Driver.BlendFunc = radeonDDBlendFunc; + ctx->Driver.BlendFuncSeparate = radeonDDBlendFuncSeparate; + ctx->Driver.ClearDepth = radeonDDClearDepth; + ctx->Driver.CullFace = radeonDDCullFace; + ctx->Driver.FrontFace = radeonDDFrontFace; + ctx->Driver.DepthFunc = radeonDDDepthFunc; + ctx->Driver.DepthMask = radeonDDDepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = radeonDDEnable; + ctx->Driver.Fogfv = radeonDDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = radeonDDLightModelfv; + ctx->Driver.LogicOpcode = radeonDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = radeonDDPolygonStipple; + ctx->Driver.Scissor = radeonDDScissor; + ctx->Driver.ShadeModel = radeonDDShadeModel; + ctx->Driver.ClearStencil = NULL; + ctx->Driver.StencilFunc = NULL; + ctx->Driver.StencilMask = NULL; + ctx->Driver.StencilOp = NULL; + ctx->Driver.Viewport = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h new file mode 100644 index 000000000..1be2977af --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h @@ -0,0 +1,55 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_STATE_H__ +#define __RADEON_STATE_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_context.h" + +extern void radeonDDInitState( radeonContextPtr rmesa ); +extern void radeonDDInitStateFuncs( GLcontext *ctx ); + +extern void radeonDDUpdateState( GLcontext *ctx ); +extern void radeonDDUpdateHWState( GLcontext *ctx ); + +extern void radeonUpdateWindow( GLcontext *ctx ); + +extern void radeonEmitHwStateLocked( radeonContextPtr rmesa ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c new file mode 100644 index 000000000..5cc4aabef --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -0,0 +1,2248 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "simple_list.h" +#include "enums.h" +#include "mem.h" + + +static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) +{ + t->setup.pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK); + + switch ( swrap ) { + case GL_REPEAT: + t->setup.pp_txfilter |= RADEON_CLAMP_S_WRAP; + break; + case GL_CLAMP: + t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; + break; + case GL_CLAMP_TO_EDGE: + t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; + break; + } + + switch ( twrap ) { + case GL_REPEAT: + t->setup.pp_txfilter |= RADEON_CLAMP_T_WRAP; + break; + case GL_CLAMP: + t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; + break; + case GL_CLAMP_TO_EDGE: + t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; + break; + } +} + +static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) +{ + t->setup.pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK); + + switch ( minf ) { + case GL_NEAREST: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST; + break; + case GL_LINEAR: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR; + break; + } + + switch ( magf ) { + case GL_NEAREST: + t->setup.pp_txfilter |= RADEON_MAG_FILTER_NEAREST; + break; + case GL_LINEAR: + t->setup.pp_txfilter |= RADEON_MAG_FILTER_LINEAR; + break; + } +} + +static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) +{ + t->setup.pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); +} + + +/* Allocate and initialize hardware state associated with texture `t'. + */ +static radeonTexObjPtr radeonCreateTexObj( radeonContextPtr rmesa, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t; + struct gl_texture_image *image; + GLint log2Width, log2Height, log2Size, log2MinSize; + GLint totalSize; + GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; + GLint x, y, width, height; + GLint i; + GLuint txformat, txalpha; + + image = tObj->Image[0]; + if ( !image ) + return NULL; + + t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); + if ( !t ) + return NULL; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj ); + + switch ( image->Format ) { + case GL_RGBA: + if ( image->IntFormat != GL_RGBA4 && + ( image->IntFormat == GL_RGBA8 || + rmesa->radeonScreen->cpp == 4 ) ) { + t->texelBytes = 4; + txformat = RADEON_TXF_32BPP_ARGB8888; + } else { + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_ARGB4444; + } + txalpha = RADEON_TXF_ALPHA_IN_MAP; + break; + + case GL_RGB: + if ( image->IntFormat != GL_RGB5 && + ( image->IntFormat == GL_RGB8 || + rmesa->radeonScreen->cpp == 4 ) ) { + t->texelBytes = 4; + txformat = RADEON_TXF_32BPP_ARGB8888; + } else { + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_RGB565; + } + txalpha = 0; + break; + + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_AI88; + txalpha = RADEON_TXF_ALPHA_IN_MAP; + break; + + case GL_LUMINANCE: + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_AI88; + txalpha = 0; + break; + + case GL_INTENSITY: + t->texelBytes = 1; + txformat = RADEON_TXF_8BPP_I; + txalpha = 0; + break; + + case GL_COLOR_INDEX: + default: + fprintf( stderr, "%s: bad image->Format\n", __FUNCTION__ ); + FREE( t ); + return NULL; + } + + /* Calculate dimensions in log domain. + */ + for ( i = 1, log2Height = 0 ; i < image->Height ; i *= 2 ) { + log2Height++; + } + for ( i = 1, log2Width = 0 ; i < image->Width ; i *= 2 ) { + log2Width++; + } + if ( image->Width > image->Height ) { + log2Size = log2Width; + } else { + log2Size = log2Height; + } + + t->dirty_images = 0; + + /* The Radeon has a 64-byte minimum pitch for all blits. We + * calculate the equivalent number of texels to simplify the + * calculation of the texture image area. + */ + switch ( t->texelBytes ) { + case 1: + texelsPerDword = 4; + blitPitch = 64; + break; + case 2: + texelsPerDword = 2; + blitPitch = 32; + break; + case 4: + texelsPerDword = 1; + blitPitch = 16; + break; + } + + /* Select the larger of the two widths for our global texture image + * coordinate space. As the Radeon has very strict offset rules, we + * can't upload mipmaps directly and have to reference their location + * from the aligned start of the whole image. + */ + blitWidth = MAX2( image->Width, blitPitch ); + + /* Calculate mipmap offsets and dimensions. + */ + totalSize = 0; + x = 0; + y = 0; + + for ( i = 0 ; i <= log2Size ; i++ ) { + GLuint size; + + image = tObj->Image[i]; + if ( !image ) + break; + + width = image->Width; + height = image->Height; + + /* Texture images have a minimum pitch of 32 bytes (half of the + * 64-byte minimum pitch for blits). For images that have a + * width smaller than this, we must pad each texture image + * scanline out to this amount. + */ + if ( width < blitPitch / 2 ) { + width = blitPitch / 2; + } + + size = width * height * t->texelBytes; + totalSize += size; + + t->dirty_images |= (1 << i); + + while ( width < blitWidth && height > 1 ) { + width *= 2; + height /= 2; + } + + t->image[i].x = x; + t->image[i].y = y; + + t->image[i].width = width; + t->image[i].height = height; + + t->image[i].dwords = size / sizeof(CARD32); + + /* While blits must have a pitch of at least 64 bytes, mipmaps + * must be aligned on a 32-byte boundary (just like each texture + * image scanline). + */ + if ( width >= blitWidth ) { + y += height; + } else { + x += width; + if ( x >= blitWidth ) { + x = 0; + y++; + } + } + + if ( 0 ) + fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d) %d dwords\n", + i, blitWidth, image->Width, image->Height, + t->image[i].width, t->image[i].height, + t->image[i].x, t->image[i].y, + t->image[i].dwords ); + } + + log2MinSize = log2Size - i + 1; + + /* Align the total size of texture memory block. + */ + totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + t->totalSize = totalSize; + + t->bound = 0; + t->heap = 0; + t->tObj = tObj; + + t->memBlock = NULL; + t->bufAddr = 0; + + /* Hardware state: + */ + t->setup.pp_txfilter = ((log2Size << RADEON_MAX_MIP_LEVEL_SHIFT) | + RADEON_BORDER_MODE_OGL); + + t->setup.pp_txformat = (txformat | txalpha | + (log2Width << RADEON_TXF_WIDTH_SHIFT) | + (log2Height << RADEON_TXF_HEIGHT_SHIFT) | + RADEON_TXF_ENDIAN_NO_SWAP | + RADEON_TXF_PERSPECTIVE_ENABLE); + + t->setup.pp_txoffset = 0x00000000; + t->setup.pp_txcblend = 0x00000000; + t->setup.pp_txablend = 0x00000000; + t->setup.pp_tfactor = 0x00000000; + t->setup.pp_border_color = 0x00000000; + + radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); + radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + radeonSetTexBorderColor( t, tObj->BorderColor ); + + tObj->DriverData = t; + + make_empty_list( t ); + + return t; +} + +/* Destroy hardware state associated with texture `t'. + */ +void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureSwaps++; +#endif + if ( !t ) return; + + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + if ( t->tObj ) + t->tObj->DriverData = NULL; + if ( t->bound ) + rmesa->CurrentTexObj[t->bound-1] = NULL; + + remove_from_list( t ); + FREE( t ); +} + +/* Keep track of swapped out texture objects. + */ +static void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureSwaps++; +#endif + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + t->dirty_images = ~0; + move_to_tail( &rmesa->SwappedOut, t ); +} + +/* Print out debugging information about texture LRU. + */ +void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ) +{ + radeonTexObjPtr t; + int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]); + + fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); + + foreach ( t, &rmesa->TexObjList[heap] ) { + if (!t->tObj) { + fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size ); + } else { + fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", + t->bound, + t->memBlock->ofs, + t->memBlock->size ); + } + } + + fprintf( stderr, "\n" ); +} + +void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int i, j; + + fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); + + for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + j, list[j].age, list[j].next, list[j].prev ); + j = list[j].next; + if ( j == RADEON_NR_TEX_REGIONS ) break; + } + + if ( j != RADEON_NR_TEX_REGIONS ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + i, list[i].age, list[i].next, list[i].prev ); + } + } + + fprintf( stderr, "\n" ); +} + +/* Reset the global texture LRU. + */ +static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; + int i; + + /* + * (Re)initialize the global circular LRU list. The last element in + * the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at + * the end of the array allows it to be addressed rationally when + * looking up objects at a particular location in texture memory. + */ + for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = RADEON_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = RADEON_NR_TEX_REGIONS; + list[RADEON_NR_TEX_REGIONS].prev = i; + list[RADEON_NR_TEX_REGIONS].next = 0; + rmesa->sarea->texAge[heap] = 0; +} + +/* Update the local and glock texture LRUs. + */ +static void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t ) +{ + int heap = t->heap; + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = rmesa->radeonScreen->logTexGranularity[heap]; + int start = t->memBlock->ofs >> sz; + int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; + int i; + + rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; + + if ( !t->memBlock ) { + fprintf( stderr, "no memblock\n\n" ); + return; + } + + /* Update our local LRU */ + move_to_head( &rmesa->TexObjList[heap], t ); + + /* Update the global LRU */ + for ( i = start ; i <= end ; i++ ) { + list[i].in_use = 1; + list[i].age = rmesa->lastTexAge[heap]; + + /* remove_from_list(i) */ + list[(CARD32)list[i].next].prev = list[i].prev; + list[(CARD32)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) */ + list[i].prev = RADEON_NR_TEX_REGIONS; + list[i].next = list[RADEON_NR_TEX_REGIONS].next; + list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; + list[RADEON_NR_TEX_REGIONS].next = i; + } + + if ( 0 ) { + radeonPrintGlobalLRU( rmesa, t->heap ); + radeonPrintLocalLRU( rmesa, t->heap ); + } +} + +/* Update our notion of what textures have been changed since we last + * held the lock. This pertains to both our local textures and the + * textures belonging to other clients. Keep track of other client's + * textures by pushing a placeholder texture onto the LRU list -- these + * are denoted by (tObj == NULL). + */ +static void radeonTexturesGone( radeonContextPtr rmesa, int heap, + int offset, int size, int in_use ) +{ + radeonTexObjPtr t, tmp; + + foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) { + if ( t->memBlock->ofs >= offset + size || + t->memBlock->ofs + t->memBlock->size <= offset ) + continue; + + /* It overlaps - kick it out. Need to hold onto the currently + * bound objects, however. + */ + if ( t->bound ) { + radeonSwapOutTexObj( rmesa, t ); + } else { + radeonDestroyTexObj( rmesa, t ); + } + } + + if ( in_use ) { + t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); + if ( !t ) return; + + t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); + if ( !t->memBlock ) { + fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", + (int)size, (int)offset ); + mmDumpMemInfo( rmesa->texHeap[heap] ); + return; + } + insert_at_head( &rmesa->TexObjList[heap], t ); + } +} + +/* Update our client's shared texture state. If another client has + * modified a region in which we have textures, then we need to figure + * out which of our textures has been removed, and update our global + * LRU. + */ +void radeonAgeTextures( radeonContextPtr rmesa, int heap ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + + if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { + int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; + int nr = 0; + int idx; + + for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; + idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++ ) + { + /* If switching texturing schemes, then the SAREA might not + * have been properly cleared, so we need to reset the + * global texture LRU. + */ + if ( idx * sz > rmesa->radeonScreen->texSize[heap] ) { + nr = RADEON_NR_TEX_REGIONS; + break; + } + + if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { + radeonTexturesGone( rmesa, heap, idx * sz, sz, + sarea->texList[heap][idx].in_use ); + } + } + + if ( nr == RADEON_NR_TEX_REGIONS ) { + radeonTexturesGone( rmesa, heap, 0, + rmesa->radeonScreen->texSize[heap], 0 ); + radeonResetGlobalLRU( rmesa, heap ); + } + + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES); + rmesa->lastTexAge[heap] = sarea->texAge[heap]; + } +} + + +/* ================================================================ + * Texture image conversions + */ + +/* Convert a block of Mesa-formatted texture to an 8bpp hardware format. + */ +static void radeonConvertTexture8bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + if ( width < 4 ) { + width = 4; + } + +#define ALIGN_DST \ + do { \ + if ( width < 32 ) { \ + dst += ((32 - width) / 4); \ + } \ + } while (0) + + switch ( image->Format ) { + case GL_INTENSITY: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 2 ; j ; j-- ) { + *dst++ = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + src += 4; + } + ALIGN_DST; + } + break; + + case GL_COLOR_INDEX: + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} +#undef ALIGN_DST + +/* Convert a block of Mesa-formatted texture to a 16bpp hardware format. + */ +static void radeonConvertTexture16bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + if ( width < 2 ) { + width = 2; + } + +#define ALIGN_DST \ + do { \ + if ( width < 16 ) { \ + dst += ((16 - width) / 2); \ + } \ + } while (0) + + switch ( image->Format ) { + case GL_RGBA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR4444( src[0], src[1], src[2], src[3] )) | + (RADEONPACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16)); + src += 8; + } + ALIGN_DST; + } + break; + + case GL_RGB: + { + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR565( src[0], src[1], src[2] )) | + (RADEONPACKCOLOR565( src[3], src[4], src[5] ) << 16)); + src += 6; + } + ALIGN_DST; + } + } + break; + + case GL_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR88( 0x00, src[0] )) | + (RADEONPACKCOLOR88( 0x00, src[1] ) << 16)); + src += 2; + } + ALIGN_DST; + } + break; + + case GL_LUMINANCE: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR88( src[0], 0xff )) | + (RADEONPACKCOLOR88( src[1], 0xff ) << 16)); + src += 2; + } + ALIGN_DST; + } + break; + + case GL_LUMINANCE_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR88( src[0], src[1] )) | + (RADEONPACKCOLOR88( src[2], src[3] ) << 16)); + src += 4; + } + ALIGN_DST; + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} +#undef ALIGN_DST + +/* Convert a block of Mesa-formatted texture to a 32bpp hardware format. + */ +static void radeonConvertTexture32bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + +#define ALIGN_DST \ + do { \ + if ( width < 8 ) { \ + dst += (8 - width); \ + } \ + } while (0) + + switch ( image->Format ) { + case GL_RGBA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], src[3] ); + src += 4; + } + ALIGN_DST; + } + break; + + case GL_RGB: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], 0xff ); + src += 3; + } + ALIGN_DST; + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} + +/* Upload the texture image associated with texture `t' at level `level' + * at the address relative to `start'. + */ +static void radeonUploadSubImage( radeonContextPtr rmesa, + radeonTexObjPtr t, GLint level, + GLint x, GLint y, GLint width, GLint height ) +{ + struct gl_texture_image *image; + GLint texelsPerDword = 0; + GLint imageX, imageY, imageWidth, imageHeight; + GLint blitX, blitY, blitWidth, blitHeight; + GLint imageRows, blitRows; + GLint remaining ; + GLint format, dwords; + CARD32 pitch, offset; + drmBufPtr buffer; + CARD32 *dst; + + /* Ensure we have a valid texture to upload */ + if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) ) + return; + + image = t->tObj->Image[level]; + if ( !image ) + return; + + switch ( t->texelBytes ) { + case 1: + texelsPerDword = 4; + break; + case 2: + texelsPerDword = 2; + break; + case 4: + texelsPerDword = 1; + break; + } + + format = t->setup.pp_txformat & RADEON_TXF_FORMAT_MASK; + + imageX = 0; + imageY = 0; + imageWidth = image->Width; + imageHeight = image->Height; + + blitX = t->image[level].x; + blitY = t->image[level].y; + blitWidth = t->image[level].width; + blitHeight = t->image[level].height; + + dwords = t->image[level].dwords; + offset = t->bufAddr; + pitch = (t->image[0].width * t->texelBytes) / 64; + +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureBytes += (dwords << 2); +#endif + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, " upload image: %d,%d at %d,%d\n", + imageWidth, imageHeight, imageX, imageY ); + fprintf( stderr, " upload blit: %d,%d at %d,%d\n", + blitWidth, blitHeight, blitX, blitY ); + fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d " + "level: %d format: %x\n", + (GLuint)offset, (GLuint)pitch, dwords, level, format ); + } + + /* Subdivide the texture if required */ + if ( dwords <= RADEON_BUFFER_MAX_DWORDS / 2 ) { + imageRows = imageHeight; + blitRows = blitHeight; + } else { + imageRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword)/(2 * imageWidth); + blitRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * blitWidth); + } + + for ( remaining = imageHeight ; + remaining > 0 ; + remaining -= imageRows, imageY += imageRows, blitY += blitRows ) + { + if ( remaining >= imageRows ) { + imageHeight = imageRows; + blitHeight = blitRows; + } else { + imageHeight = remaining; + blitHeight = blitRows; + } + dwords = blitWidth * blitHeight / texelsPerDword; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, " blitting: %d,%d at %d,%d\n", + imageWidth, imageHeight, imageX, imageY ); + fprintf( stderr, " %d,%d at %d,%d - %d dwords\n", + blitWidth, blitHeight, blitX, blitY, dwords ); + } + + /* Grab the indirect buffer for the texture blit */ + buffer = radeonGetBufferLocked( rmesa ); + + dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET); + + /* Actually do the texture conversion */ + switch ( t->texelBytes ) { + case 1: + radeonConvertTexture8bpp( dst, image, + imageX, imageY, imageWidth, imageHeight, + imageWidth ); + break; + case 2: + radeonConvertTexture16bpp( dst, image, + imageX, imageY, imageWidth, imageHeight, + imageWidth ); + break; + case 4: + radeonConvertTexture32bpp( dst, image, + imageX, imageY, imageWidth, imageHeight, + imageWidth ); + break; + } + + radeonFireBlitLocked( rmesa, buffer, + offset, pitch, format, + blitX, blitY, blitWidth, blitHeight ); + } + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; +} + +/* Upload the texture images associated with texture `t'. This might + * require removing our own and/or other client's texture objects to + * make room for these images. + */ +/* NOTE: This function is only called while holding the hardware lock */ +int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ + int i; + int heap; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %p )\n", + __FUNCTION__, rmesa->glCtx, t ); + } + + if ( !t ) + return 0; + + /* Choose the heap appropriately */ + heap = t->heap = RADEON_CARD_HEAP; +#if 0 + if ( !rmesa->radeonScreen->IsPCI && + t->totalSize > rmesa->radeonScreen->texSize[heap] ) { + heap = t->heap = RADEON_AGP_HEAP; + } +#endif + + /* Do we need to eject LRU texture objects? */ + if ( !t->memBlock ) { + /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ + t->memBlock = mmAllocMem( rmesa->texHeap[heap], + t->totalSize, 12, 0 ); + +#if 0 + /* Try AGP before kicking anything out of local mem */ + if ( !t->memBlock && heap == RADEON_CARD_HEAP ) { + t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP], + t->totalSize, 12, 0 ); + + if ( t->memBlock ) + heap = t->heap = RADEON_AGP_HEAP; + } +#endif + + /* Kick out textures until the requested texture fits */ + while ( !t->memBlock ) { + if ( rmesa->TexObjList[heap].prev->bound ) { + fprintf( stderr, + "radeonUploadTexImages: ran into bound texture\n" ); + return -1; + } + if ( rmesa->TexObjList[heap].prev == + &rmesa->TexObjList[heap] ) { + if ( rmesa->radeonScreen->IsPCI ) { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on local texture heaps, sz=%d\n", + t->totalSize ); + return -1; +#if 0 + } else if ( heap == RADEON_CARD_HEAP ) { + heap = t->heap = RADEON_AGP_HEAP; + continue; +#endif + } else { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize ); + return -1; + } + } + + radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev ); + + t->memBlock = mmAllocMem( rmesa->texHeap[heap], + t->totalSize, 12, 0 ); + } + + /* Set the base offset of the texture image */ + t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs; + + t->setup.pp_txoffset = t->bufAddr; +#if 0 + /* Fix AGP texture offsets */ + if ( heap == RADEON_AGP_HEAP ) { + t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET + + rmesa->radeonScreen->agpTexOffset; + } +#endif + + /* Force loading the new state into the hardware */ + switch ( t->bound ) { + case 1: + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0; + break; + + case 2: + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1; + break; + + default: + return -1; + } + } + + /* Let the world know we've used this memory recently */ + radeonUpdateTexLRU( rmesa, t ); + + /* Upload any images that are new */ + if ( t->dirty_images ) { + int num_levels = ((t->setup.pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >> + RADEON_MAX_MIP_LEVEL_SHIFT); + + for ( i = 0 ; i <= num_levels ; i++ ) { + if ( t->dirty_images & (1 << i) ) { + radeonUploadSubImage( rmesa, t, i, 0, 0, + t->image[i].width, t->image[i].height ); + } + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + + t->dirty_images = 0; + return 0; +} + + +/* ================================================================ + * Texture combine functions + */ + +#define RADEON_DISABLE 0 +#define RADEON_REPLACE 1 +#define RADEON_MODULATE 2 +#define RADEON_DECAL 3 +#define RADEON_BLEND 4 +#define RADEON_ADD 5 +#define RADEON_MAX_COMBFUNC 6 + +static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00802800 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800142 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T0_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c2d42 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T0_COLOR | + RADEON_COLOR_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c2902 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00812802 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00803000 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800182 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T1_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c3582 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T1_COLOR | + RADEON_COLOR_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c3102 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00813002 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00803800 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x008001c2 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T2_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c3dc2 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T2_COLOR | + RADEON_COLOR_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c3902 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00813802 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + } +}; + +static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800500 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T0_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800600 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T1_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800700 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800071 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T2_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800071 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800021 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + } +}; + + +/* GL_EXT_texture_env_combine support + */ + +/* The color tables have combine functions for GL_SRC_COLOR, + * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] = +{ + { + RADEON_COLOR_ARG_A_T0_COLOR, + RADEON_COLOR_ARG_A_T1_COLOR, + RADEON_COLOR_ARG_A_T2_COLOR + }, + { + RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A + }, + { + RADEON_COLOR_ARG_A_T0_ALPHA, + RADEON_COLOR_ARG_A_T1_ALPHA, + RADEON_COLOR_ARG_A_T2_ALPHA + }, + { + RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A + }, +}; + +static GLuint radeon_tfactor_color[] = +{ + RADEON_COLOR_ARG_A_TFACTOR_COLOR, + RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_TFACTOR_ALPHA, + RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_primary_color[] = +{ + RADEON_COLOR_ARG_A_DIFFUSE_COLOR, + RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_DIFFUSE_ALPHA, + RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_previous_color[] = +{ + RADEON_COLOR_ARG_A_CURRENT_COLOR, + RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_CURRENT_ALPHA, + RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A +}; + +/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] = +{ + { + RADEON_ALPHA_ARG_A_T0_ALPHA, + RADEON_ALPHA_ARG_A_T1_ALPHA, + RADEON_ALPHA_ARG_A_T2_ALPHA + }, + { + RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, + RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, + RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A + }, +}; + +static GLuint radeon_tfactor_alpha[] = +{ + RADEON_ALPHA_ARG_A_TFACTOR_ALPHA, + RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_primary_alpha[] = +{ + RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA, + RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_previous_alpha[] = +{ + RADEON_ALPHA_ARG_A_CURRENT_ALPHA, + RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A +}; + + +/* Extract the arg from slot A, shift it into the correct argument slot + * and set the corresponding complement bit. + */ +#define RADEON_COLOR_ARG( n, arg ) \ +do { \ + color_combine |= \ + ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ + << RADEON_COLOR_ARG_##arg##_SHIFT); \ + color_combine |= \ + ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ +} while (0) + +#define RADEON_ALPHA_ARG( n, arg ) \ +do { \ + alpha_combine |= \ + ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ + << RADEON_ALPHA_ARG_##arg##_SHIFT); \ + alpha_combine |= \ + ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ +} while (0) + + +/* ================================================================ + * Texture unit state management + */ + +static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; + struct gl_texture_object *tObj; + struct gl_texture_unit *texUnit; + GLuint enabled; + GLuint color_combine, alpha_combine; + GLuint color_arg[3], alpha_arg[3]; + GLuint i, numColorArgs = 0, numAlphaArgs = 0; + GLuint op; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) + return; + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + texUnit = &ctx->Texture.Unit[source]; + tObj = texUnit->Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != texUnit->CurrentD[2] ) && + ( tObj != texUnit->CurrentD[1] ) ) + return; + + /* Set the texture environment state. Isn't this nice and clean? + * The Radeon will automagically set the texture alpha to 0xff when + * the texture format does not include an alpha component. This + * reduces the amount of special-casing we have to do, alpha-only + * textures being a notable exception. + */ + switch ( texUnit->EnvMode ) { + case GL_REPLACE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_REPLACE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_MODULATE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + color_combine = radeon_color_combine[unit][RADEON_DECAL]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_ADD]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_COMBINE_EXT: + /* Step 0: + * Calculate how many arguments we need to process. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + numColorArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + numColorArgs = 2; + break; + case GL_INTERPOLATE_EXT: + numColorArgs = 3; + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + numAlphaArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + numAlphaArgs = 2; + break; + case GL_INTERPOLATE_EXT: + numAlphaArgs = 3; + break; + default: + return; + } + + /* Step 1: + * Extract the color and alpha combine function arguments. + */ + for ( i = 0 ; i < numColorArgs ; i++ ) { + op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; + switch ( texUnit->CombineSourceRGB[i] ) { + case GL_TEXTURE: + color_arg[i] = radeon_texture_color[op][unit]; + break; + case GL_CONSTANT_EXT: + color_arg[i] = radeon_tfactor_color[op]; + break; + case GL_PRIMARY_COLOR_EXT: + color_arg[i] = radeon_primary_color[op]; + break; + case GL_PREVIOUS_EXT: + color_arg[i] = radeon_previous_color[op]; + break; + default: + return; + } + } + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; + switch ( texUnit->CombineSourceA[i] ) { + case GL_TEXTURE: + alpha_arg[i] = radeon_texture_alpha[op][unit]; + break; + case GL_CONSTANT_EXT: + alpha_arg[i] = radeon_tfactor_alpha[op]; + break; + case GL_PRIMARY_COLOR_EXT: + alpha_arg[i] = radeon_primary_alpha[op]; + break; + case GL_PREVIOUS_EXT: + alpha_arg[i] = radeon_previous_alpha[op]; + break; + default: + return; + } + } + + /* Step 2: + * Build up the color and alpha combine functions. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + color_combine = (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, C ); + break; + case GL_MODULATE: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + case GL_ADD: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_ADD_SIGNED_EXT: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_INTERPOLATE_EXT: + color_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, B ); + RADEON_COLOR_ARG( 1, A ); + RADEON_COLOR_ARG( 2, C ); + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_DOT3 | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, C ); + break; + case GL_MODULATE: + alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, B ); + break; + case GL_ADD: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_ADD_SIGNED_EXT: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_INTERPOLATE_EXT: + alpha_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, B ); + RADEON_ALPHA_ARG( 1, A ); + RADEON_ALPHA_ARG( 2, C ); + break; + default: + return; + } + + if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) { + alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; + } + + /* Step 3: + * Apply the scale factor. The EXT extension has a somewhat + * unnecessary restriction that the scale must be 4x. The ARB + * extension will likely drop this and we can just apply the + * scale factors regardless. + */ + if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT && + texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) { + color_combine |= (texUnit->CombineScaleShiftRGB << 21); + alpha_combine |= (texUnit->CombineScaleShiftA << 21); + } else { + color_combine |= RADEON_SCALE_4X; + alpha_combine |= RADEON_SCALE_4X; + } + + /* All done! + */ + break; + + default: + return; + } + + rmesa->color_combine[source] = color_combine; + rmesa->alpha_combine[source] = alpha_combine; +} + +static void radeonUpdateTextureObject( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; + struct gl_texture_object *tObj; + radeonTexObjPtr t; + GLuint enabled; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { + if ( enabled ) + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + tObj = ctx->Texture.Unit[source].Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && + ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) + return; + + if ( !tObj->DriverData ) { + /* If this is the first time the texture has been used, then create + * a new texture object for it. + */ + radeonCreateTexObj( rmesa, tObj ); + + if ( !tObj->DriverData ) { + /* Can't create a texture object... */ + fprintf( stderr, "%s: texture object creation failed!\n", + __FUNCTION__ ); + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + } + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + /* Force the texture unit state to be loaded into the hardware */ + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit); + + /* Force any texture images to be loaded into the hardware */ + if ( t->dirty_images ) + rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit); + + /* Bind to the given texture unit */ + rmesa->CurrentTexObj[unit] = t; + t->bound = unit + 1; + + if ( t->memBlock ) + radeonUpdateTexLRU( rmesa, t ); + + switch ( unit ) { + case 0: + rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE | + RADEON_TEX_BLEND_0_ENABLE); + break; + case 1: + rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE | + RADEON_TEX_BLEND_1_ENABLE); + break; + } +} + +void radeonUpdateTextureState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) en=0x%x\n", + __FUNCTION__, ctx, ctx->Texture.ReallyEnabled ); + } + + /* Clear any texturing fallbacks */ + rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE; + + /* Unbind any currently bound textures */ + if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0; + if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0; + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; + + if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) ) + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + + /* Disable all texturing until it is known to be good */ + rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK | + RADEON_TEX_BLEND_ENABLE_MASK); + + radeonUpdateTextureObject( ctx, 0 ); + radeonUpdateTextureEnv( ctx, 0 ); + + if ( rmesa->multitex ) { + radeonUpdateTextureObject( ctx, 1 ); + radeonUpdateTextureEnv( ctx, 1 ); + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; +} + + +/* ================================================================ + * DD interface texturing functions + * + * FIXME: Many of these are deprecated -- we should move to the new + * single-copy texture interface. + */ +#define SCALED_FLOAT_TO_BYTE( x, scale ) \ + ((((GLint)((256.0F / scale) * (x))) - 1) / 2) + +static void radeonDDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_unit *texUnit; + GLuint source; + GLubyte c[4]; + GLuint col; + GLfloat bias; + GLubyte b; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + switch ( pname ) { + case GL_TEXTURE_ENV_MODE: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_TEXTURE | RADEON_NEW_ALPHA; + break; + + case GL_TEXTURE_ENV_COLOR: + source = rmesa->tmu_source[ctx->Texture.CurrentUnit]; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + FLOAT_RGBA_TO_UBYTE_RGBA( c, texUnit->EnvColor ); + col = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); + if ( rmesa->env_color[source] != col ) { + FLUSH_BATCH( rmesa ); + rmesa->env_color[source] = col; + + rmesa->new_state |= RADEON_NEW_TEXTURE; + } + break; + + case GL_TEXTURE_LOD_BIAS_EXT: + /* The Radeon's LOD bias is a signed 2's complement value with a + * range of -1.0 <= bias < 4.0. We break this into two linear + * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping + * [0.0,4.0] to [0,127]. + */ + source = rmesa->tmu_source[ctx->Texture.CurrentUnit]; + bias = CLAMP( *param, -1.0, 4.0 ); + if ( bias == 0 ) { + b = 0; + } else if ( bias > 0 ) { + b = (GLubyte) SCALED_FLOAT_TO_BYTE( bias, 4.0 ); + } else { + b = (GLubyte) SCALED_FLOAT_TO_BYTE( bias, 1.0 ); + } + if ( rmesa->lod_bias[source] != (GLuint)b ) { + FLUSH_BATCH( rmesa ); + rmesa->lod_bias[source] = (GLuint)b; + + rmesa->new_state |= RADEON_NEW_TEXTURE; + } + break; + + default: + return; + } +} + +static void radeonDDTexImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint internalFormat, + const struct gl_texture_image *image ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level ); + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= RADEON_MAX_TEXTURE_LEVELS ) + return; + + t = (radeonTexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + + /* Destroy the old texture, and upload a new one. The actual + * uploading of the texture image occurs in the UploadSubImage + * function. + */ + radeonDestroyTexObj( rmesa, t ); + rmesa->new_state |= RADEON_NEW_TEXTURE; + } +} + +static void radeonDDTexSubImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLint internalFormat, + const struct gl_texture_image *image ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, level %d ) size: %d,%d of %d,%d\n", + __FUNCTION__, tObj, level, width, height, + image->Width, image->Height ); + } + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= RADEON_MAX_TEXTURE_LEVELS ) + return; + + t = (radeonTexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + radeonUploadSubImage( rmesa, t, level, + xoffset, yoffset, width, height ); + UNLOCK_HARDWARE( rmesa ); + + /* Update the context state */ + rmesa->new_state |= RADEON_NEW_TEXTURE; + } +} + +static void radeonDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + /* If we don't have a hardware texture, it will be automatically + * created with current state before it is used, so we don't have + * to do anything now. + */ + if ( !t || !t->bound ) + return; + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + switch ( pname ) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSetTexBorderColor( t, tObj->BorderColor ); + break; + + default: + return; + } + + rmesa->new_state |= RADEON_NEW_TEXTURE; +} + +static void radeonDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint unit = ctx->Texture.CurrentUnit; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) unit=%d\n", + __FUNCTION__, tObj, ctx->Texture.CurrentUnit ); + } + + FLUSH_BATCH( rmesa ); + + if ( rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit]->bound = 0; + rmesa->CurrentTexObj[unit] = NULL; + } + + rmesa->new_state |= RADEON_NEW_TEXTURE; +} + +static void radeonDDDeleteTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + if ( t ) { + if ( t->bound ) { + FLUSH_BATCH( rmesa ); + + rmesa->CurrentTexObj[t->bound-1] = 0; + rmesa->new_state |= RADEON_NEW_TEXTURE; + } + + radeonDestroyTexObj( rmesa, t ); + tObj->DriverData = NULL; + } +} + +static GLboolean radeonDDIsTextureResident( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + return ( t && t->memBlock ); +} + + + +void radeonDDInitTextureFuncs( GLcontext *ctx ) +{ + ctx->Driver.TexEnv = radeonDDTexEnv; + ctx->Driver.TexImage = radeonDDTexImage; + ctx->Driver.TexSubImage = radeonDDTexSubImage; + ctx->Driver.TexParameter = radeonDDTexParameter; + ctx->Driver.BindTexture = radeonDDBindTexture; + ctx->Driver.DeleteTexture = radeonDDDeleteTexture; + ctx->Driver.UpdateTexturePalette = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.IsTextureResident = radeonDDIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h new file mode 100644 index 000000000..6bf967761 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h @@ -0,0 +1,96 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_TEX_H__ +#define __RADEON_TEX_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonUpdateTextureState( GLcontext *ctx ); + +extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ); + +extern void radeonAgeTextures( radeonContextPtr rmesa, int heap ); +extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); + +extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ); +extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ); + +extern void radeonDDInitTextureFuncs( GLcontext *ctx ); + + +/* ================================================================ + * Color conversion macros: + */ + +#define RADEONPACKCOLOR332( r, g, b ) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) + +#define RADEONPACKCOLOR1555( r, g, b, a ) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define RADEONPACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define RADEONPACKCOLOR88( i, a ) \ + (((a) << 8) | (i)) + +#define RADEONPACKCOLOR888( r, g, b ) \ + (((r) << 16) | ((g) << 8) | (b)) + +#define RADEONPACKCOLOR8888( r, g, b, a ) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define RADEONPACKCOLOR4444( r, g, b, a ) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +static __inline__ CARD32 radeonPackColor( GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + switch ( cpp ) { + case 2: + return RADEONPACKCOLOR565( r, g, b ); + case 4: + return RADEONPACKCOLOR8888( r, g, b, a ); + default: + return 0; + } +} + +#endif +#endif /* __RADEON_TEX_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h new file mode 100644 index 000000000..b63d5c6a7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h @@ -0,0 +1,87 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_TEXOBJ_H__ +#define __RADEON_TEXOBJ_H__ + +#include "radeon_sarea.h" +#include "mm.h" + +/* Handle the Radeon's tightly packed mipmaps and strict offset, + * pitch rules for blits by assigning each mipmap a set of + * coordinates that can be used for a hostdata blit. + */ +typedef struct { + GLuint x; /* Blit coordinates */ + GLuint y; + GLuint width; /* Blit dimensions */ + GLuint height; + GLuint dwords; /* Size of image level */ +} radeonTexImage; + +typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; + +/* Texture object in locally shared texture space. + */ +struct radeon_tex_obj { + radeonTexObjPtr next, prev; + + struct gl_texture_object *tObj; /* Mesa texture object */ + + PMemBlock memBlock; /* Memory block containing texture */ + CARD32 bufAddr; /* Offset to start of locally + shared texture block */ + + CARD32 dirty_images; /* Flags for whether or not + images need to be uploaded to + local or AGP texture space */ + + GLint bound; /* Texture unit currently bound to */ + GLint heap; /* Texture heap currently stored in */ + + radeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; /* Image data for all + mipmap levels */ + + GLint totalSize; /* Total size of the texture + including all mipmap levels */ + GLint texelBytes; /* Number of bytes per texel */ + + GLboolean hasAlpha; + + radeon_texture_regs_t setup; /* Setup regs for texture */ +}; + +#endif /* __RADEON_TEXOBJ_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c new file mode 100644 index 000000000..71ed6910b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c @@ -0,0 +1,209 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tris.h" +#include "radeon_state.h" + +#include "pipeline.h" +#include "vbindirect.h" + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[RADEON_MAX_TRIFUNC]; + +#define RADEON_COLOR( to, from ) \ +do { \ + *(GLuint *)(to) = *(GLuint *)(from); \ +} while (0) + + +static void radeon_null_quad( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint v3, GLuint pv ) +{ +} +static void radeon_null_triangle( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint pv ) +{ +} +static void radeon_null_line( GLcontext *ctx, + GLuint v1, GLuint v2, GLuint pv ) +{ +} +static void radeon_null_points( GLcontext *ctx, GLuint first, GLuint last ) +{ +} + +static void radeonPrintRenderState( const char *msg, GLuint state ) +{ + fprintf( stderr, "%s: (0x%x) %s%s%s%s%s\n", + msg, state, + (state & RADEON_FLAT_BIT) ? "flat, " : "", + (state & RADEON_OFFSET_BIT) ? "offset, " : "", + (state & RADEON_TWOSIDE_BIT) ? "twoside, " : "", + (state & RADEON_NODRAW_BIT) ? "no-draw, " : "", + (state & RADEON_FALLBACK_BIT) ? "fallback" : "" ); +} + +#define IND (0) +#define TAG(x) x +#include "radeon_tritmp.h" + +#define IND (RADEON_FLAT_BIT) +#define TAG(x) x##_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_OFFSET_BIT) +#define TAG(x) x##_offset +#include "radeon_tritmp.h" + +#define IND (RADEON_OFFSET_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "radeon_tritmp.h" + + +void radeonDDTriangleFuncsInit( void ) +{ + GLint i; + + init(); + init_flat(); + init_offset(); + init_offset_flat(); + init_twoside(); + init_twoside_flat(); + init_twoside_offset(); + init_twoside_offset_flat(); + + for ( i = 0 ; i < RADEON_MAX_TRIFUNC ; i++ ) { + if ( i & RADEON_NODRAW_BIT ) { + rast_tab[i].points = radeon_null_points; + rast_tab[i].line = radeon_null_line; + rast_tab[i].triangle = radeon_null_triangle; + rast_tab[i].quad = radeon_null_quad; + } + } +} + + +/* FIXME: Only enable software fallback for stencil in 16 bpp mode after + * we have hardware stencil support. + */ +#define ALL_FALLBACK (DD_SELECT | DD_FEEDBACK | DD_STENCIL) +#define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH | DD_POINT_ATTEN) +#define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) +#define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED) +#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) + +/* Setup the Point, Line, Triangle and Quad functions based on the + * current rendering state. Wherever possible, use the hardware to + * render the primitive. Otherwise, fallback to software rendering. + */ +void radeonDDChooseRenderState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint flags = ctx->TriangleCaps; + GLuint index = 0; + + if ( rmesa->Fallback ) { + rmesa->RenderIndex = RADEON_FALLBACK_BIT; + return; + } + + if ( flags & ANY_RASTER_FLAGS ) { + if ( flags & DD_FLATSHADE ) index |= RADEON_FLAT_BIT; + if ( flags & DD_TRI_LIGHT_TWOSIDE ) index |= RADEON_TWOSIDE_BIT; + if ( flags & DD_TRI_OFFSET ) index |= RADEON_OFFSET_BIT; + if ( flags & DD_Z_NEVER ) index |= RADEON_NODRAW_BIT; + } + + rmesa->PointsFunc = rast_tab[index].points; + rmesa->LineFunc = rast_tab[index].line; + rmesa->TriangleFunc = rast_tab[index].triangle; + rmesa->QuadFunc = rast_tab[index].quad; + + rmesa->RenderIndex = index; + rmesa->IndirectTriangles = 0; + + if ( flags & ANY_FALLBACK ) { + if ( flags & POINT_FALLBACK ) { + rmesa->RenderIndex |= RADEON_FALLBACK_BIT; + rmesa->PointsFunc = 0; + rmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + } + + if ( flags & LINE_FALLBACK ) { + rmesa->RenderIndex |= RADEON_FALLBACK_BIT; + rmesa->LineFunc = 0; + rmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + } + + if ( flags & TRI_FALLBACK ) { + rmesa->RenderIndex |= RADEON_FALLBACK_BIT; + rmesa->TriangleFunc = 0; + rmesa->QuadFunc = 0; + rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); + } + } + + if ( 0 ) { + gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); + radeonPrintRenderState( "radeon render state", rmesa->RenderIndex ); + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h new file mode 100644 index 000000000..5694d5cf1 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h @@ -0,0 +1,316 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_TRIS_H__ +#define __RADEON_TRIS_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_vb.h" + +extern void radeonDDChooseRenderState( GLcontext *ctx ); +extern void radeonDDTriangleFuncsInit( void ); + +#define RADEON_ANTIALIAS_BIT 0x00 /* GH: Do we need this? */ +#define RADEON_FLAT_BIT 0x01 +#define RADEON_OFFSET_BIT 0x02 +#define RADEON_TWOSIDE_BIT 0x04 +#define RADEON_NODRAW_BIT 0x08 +#define RADEON_FALLBACK_BIT 0x10 +#define RADEON_MAX_TRIFUNC 0x20 + + +static __inline void radeon_draw_triangle( radeonContextPtr rmesa, + radeonVertexPtr v0, + radeonVertexPtr v1, + radeonVertexPtr v2 ) +{ + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 3 ); + GLuint j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v2) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v2->ui[j]; +#endif +} + +static __inline void radeon_draw_quad( radeonContextPtr rmesa, + radeonVertexPtr v0, + radeonVertexPtr v1, + radeonVertexPtr v2, + radeonVertexPtr v3 ) +{ + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 ); + GLuint j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v3) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v2) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v3) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v3->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v2->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v3->ui[j]; +#endif +} + +static __inline void radeon_draw_line( radeonContextPtr rmesa, + radeonVertexPtr tmp0, + radeonVertexPtr tmp1, + GLfloat width ) +{ +#if 1 + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 ); + GLfloat dx, dy, ix, iy; + GLuint j; + + dx = tmp0->v.x - tmp1->v.x; + dy = tmp0->v.y - tmp1->v.y; + + ix = width * .5; iy = 0; + + if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width + 0.5 also */ + + if (dx * dx > dy * dy) { + iy = ix; ix = 0; + } + + *(float *)&vb[0] = tmp0->v.x - ix; + *(float *)&vb[1] = tmp0->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x + ix; + *(float *)&vb[1] = tmp1->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp0->v.x + ix; + *(float *)&vb[1] = tmp0->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp0->v.x - ix; + *(float *)&vb[1] = tmp0->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x - ix; + *(float *)&vb[1] = tmp1->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x + ix; + *(float *)&vb[1] = tmp1->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; +#else + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, RADEON_LINES, 2 ); + GLuint j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)tmp1) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp1->ui[j]; +#endif +#endif +} + +static __inline void radeon_draw_point( radeonContextPtr rmesa, + radeonVertexPtr tmp, GLfloat sz ) +{ +#if 1 + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 ); + GLuint j; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + +#else + int vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, RADEON_3_VERTEX_POINTS, 1 ); + int j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp->ui[j]; +#endif +#endif +} + +#endif +#endif /* __RADEON_TRIS_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h new file mode 100644 index 000000000..ed5006ea2 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h @@ -0,0 +1,336 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +static __inline void TAG(triangle)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, + GLuint pv ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + radeonVertexPtr v[3]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[3]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + GLuint c[3]; +#endif + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; +#endif + +#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)) + { + GLfloat ex = v[0]->v.x - v[2]->v.x; + GLfloat ey = v[0]->v.y - v[2]->v.y; + GLfloat fx = v[1]->v.x - v[2]->v.x; + GLfloat fy = v[1]->v.y - v[2]->v.y; + GLfloat cc = ex*fy - ey*fx; + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if ( IND & RADEON_FLAT_BIT ) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + z[2] = v[2]->v.z; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + v[0]->v.z += offset; + v[1]->v.z += offset; + v[2]->v.z += offset; + } +#endif + } +#endif + + radeon_draw_triangle( rmesa, v[0], v[1], v[2] ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; + v[2]->ui[4] = c[2]; +#endif +} + + +static void TAG(quad)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, GLuint e3, + GLuint pv ) +{ +#if 0 + TAG(triangle)( ctx, e0, e1, e3, pv ); + TAG(triangle)( ctx, e1, e2, e3, pv ); +#else + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + radeonVertexPtr v[4]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[4]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + int c[4]; +#endif + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + v[3] = &verts[e3]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; + c[3] = v[3]->ui[4]; +#endif + +#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)) + { + GLfloat ex = v[0]->v.x - v[2]->v.x; + GLfloat ey = v[0]->v.y - v[2]->v.y; + GLfloat fx = v[1]->v.x - v[2]->v.x; + GLfloat fy = v[1]->v.y - v[2]->v.y; + GLfloat cc = ex*fy - ey*fx; + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if ( IND & RADEON_FLAT_BIT ) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + RADEON_COLOR( (char *)&v[3]->ui[4], vbcolor[e3] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + z[2] = v[2]->v.z; + z[3] = v[3]->v.z; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + v[0]->v.z += offset; + v[1]->v.z += offset; + v[2]->v.z += offset; + v[3]->v.z += offset; + } +#endif + } +#endif + + radeon_draw_quad( rmesa, v[0], v[1], v[2], v[3] ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; + v[3]->v.z = z[3]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; + v[2]->ui[4] = c[2]; + v[3]->ui[4] = c[3]; +#endif +#endif +} + + +static void TAG(line)( GLcontext *ctx, + GLuint e0, GLuint e1, + GLuint pv ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + GLfloat width = ctx->Line.Width; + radeonVertexPtr v[2]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[2]; +#endif +#if (IND & RADEON_TWOSIDE_BIT) + int c[2]; +#endif + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + if ( IND & RADEON_FLAT_BIT ) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + offset = ctx->LineZoffset * rmesa->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + v[0]->v.z += offset; + v[1]->v.z += offset; +#endif + + radeon_draw_line( rmesa, v[0], v[1], width ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; +#endif +} + + +static void TAG(points)( GLcontext *ctx, + GLuint first, GLuint last ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + GLfloat size = ctx->Point.Size * 0.5; + int i; + + for ( i = first ; i < last ; i++ ) { + if ( VB->ClipMask[i] == 0 ) { + if ( IND & (RADEON_TWOSIDE_BIT|RADEON_OFFSET_BIT) ) { + radeonVertex tmp0 = verts[i]; + + if ( IND & RADEON_TWOSIDE_BIT ) { + GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + RADEON_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); + } + if ( IND & RADEON_OFFSET_BIT ) { + GLfloat offset = ctx->PointZoffset * rmesa->depth_scale; + tmp0.v.z += offset; + } + radeon_draw_point( rmesa, &tmp0, size ); + } else { + radeon_draw_point( rmesa, &verts[i], size ); + } + } + } +} + + +static void TAG(init)( void ) +{ + rast_tab[IND].points = TAG(points); + rast_tab[IND].line = TAG(line); + rast_tab[IND].triangle = TAG(triangle); + rast_tab[IND].quad = TAG(quad); +} + +#undef IND +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c new file mode 100644 index 000000000..bf2255f74 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c @@ -0,0 +1,483 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_vb.h" + +#include "mem.h" +#include "stages.h" + +#define TEX0 \ +do { \ + v->v.tu0 = tc0[i][0]; \ + v->v.tv0 = tc0[i][1]; \ +} while (0) + +#define TEX1 \ +do { \ + v->v.tu1 = tc1[i][0]; \ + v->v.tv1 = tc1[i][1]; \ +} while (0) + +#define SPC \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.red = spec[0]; \ + v->v.specular.green = spec[1]; \ + v->v.specular.blue = spec[2]; \ +} while (0) + +#define FOG \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.alpha = spec[3]; \ +} while (0) + +#define COL \ +do { \ + GLubyte *col = &(VB->Color[0]->data[i][0]); \ + v->ui[4] = *(GLuint *)col; \ +} while (0) + +#define TEX0_4 \ +do { \ + if ( VB->TexCoordPtr[0]->size == 4 ) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + for ( i = start ; i < end ; i++, v++ ) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ + v->v.tu0 *= oow; \ + v->v.tv0 *= oow; \ + } \ + } \ +} while (0) + +#if USE_RHW2 + +#define TEX1_4 \ +do { \ + if ( VB->TexCoordPtr[1]->size == 4 ) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + for ( i = start ; i < end ; i++, v++ ) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw2 *= tc[i][3]; \ + v->v.tu1 *= oow; \ + v->v.tv1 *= oow; \ + } \ + } \ +} while (0) + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = - win[1]; \ + v->v.z = win[2]; \ + v->v.rhw = v->v.rhw2 = win[3]; \ +} while (0) + +#else /* USE_RHW2 */ + +#define TEX1_4 + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = - win[1]; \ + v->v.z = win[2]; \ + v->v.rhw = win[3]; \ +} while (0) \ + +#endif /* USE_RHW2 */ + +#define NOP + + +#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ +static void name( struct vertex_buffer *VB, GLuint start, GLuint end ) \ +{ \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + radeonVertexPtr v; \ + GLfloat (*tc0)[4]; \ + GLfloat (*tc1)[4]; \ + GLint i; \ + \ + gl_import_client_data( VB, VB->ctx->RenderFlags, \ + (VB->ClipOrMask \ + ? VEC_WRITABLE | VEC_GOOD_STRIDE \ + : VEC_GOOD_STRIDE) ); \ + \ + tc0 = VB->TexCoordPtr[rmesa->tmu_source[0]]->data; \ + tc1 = VB->TexCoordPtr[rmesa->tmu_source[1]]->data; \ + \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + \ + if ( VB->ClipOrMask == 0 ) { \ + for ( i = start ; i < end ; i++, v++ ) { \ + win; \ + col; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + } else { \ + for ( i = start ; i < end ; i++, v++ ) { \ + if ( VB->ClipMask[i] == 0 ) { \ + win; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + col; \ + } \ + } \ + tex0_4; \ + tex1_4; \ +} + + +SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + +SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + + +static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end ) +{ + fprintf( stderr, "radeonRasterSetup(): invalid setup function\n" ); +} + +typedef void (*setupFunc)( struct vertex_buffer *, GLuint, GLuint ); +static setupFunc setup_func[RADEON_MAX_SETUPFUNC]; + + +void radeonDDSetupInit( void ) +{ + GLint i; + + for ( i = 0 ; i < RADEON_MAX_SETUPFUNC ; i++ ) { + setup_func[i] = rs_invalid; + } + + /* Functions to build vertices from scratch + */ + setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT] = rs_wt0; + setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wt0t1; + setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wft0; + setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wft0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT] = rs_wg; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_wgs; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_wgt0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgt0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgst0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgst0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_wgf; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_wgfs; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wgft0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgft0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgfst0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgfst0t1; + + /* Repair functions + */ + setup_func[RADEON_TEX0_BIT] = rs_t0; + setup_func[RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_t0t1; + setup_func[RADEON_FOG_BIT] = rs_f; + setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_ft0; + setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_ft0t1; + setup_func[RADEON_RGBA_BIT] = rs_g; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_gs; + setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_gt0; + setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gt0t1; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gst0; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gst0t1; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_gf; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_gfs; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_gft0; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gft0t1; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gfst0; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gfst0t1; +} + + +void radeonPrintSetupFlags( char *msg, GLuint flags ) +{ + fprintf( stderr, "%s: %d %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & RADEON_WIN_BIT) ? " xyzw," : "", + (flags & RADEON_RGBA_BIT) ? " rgba," : "", + (flags & RADEON_SPEC_BIT) ? " spec," : "", + (flags & RADEON_FOG_BIT) ? " fog," : "", + (flags & RADEON_TEX0_BIT) ? " tex-0," : "", + (flags & RADEON_TEX1_BIT) ? " tex-1," : "" ); +} + + +/* Initialize the vertex buffer setup functions based on the current + * rendering state. + */ +void radeonDDChooseRasterSetupFunc( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + GLint index = RADEON_WIN_BIT | RADEON_RGBA_BIT; + + rmesa->vertsize = 8; + rmesa->vc_format = RADEON_TEX0_VERTEX_FORMAT; + rmesa->tmu_source[0] = 0; + rmesa->tmu_source[1] = 1; + rmesa->tex_dest[0] = RADEON_TEX0_BIT; + rmesa->tex_dest[1] = RADEON_TEX1_BIT; + rmesa->multitex = 0; + + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { + index |= RADEON_TEX0_BIT; + } + + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) { + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = RADEON_TEX1_VERTEX_FORMAT; + index |= RADEON_TEX1_BIT; + } else { + /* Just a funny way of doing single texturing. + */ + rmesa->tmu_source[0] = 1; + rmesa->tex_dest[1] = RADEON_TEX0_BIT; + index |= RADEON_TEX0_BIT; + } + } + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) + index |= RADEON_SPEC_BIT; + + if ( ctx->Fog.Enabled ) + index |= RADEON_FOG_BIT; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + radeonPrintSetupFlags( "full setup function", index ); + } + + rmesa->new_state |= RADEON_NEW_TEXTURE; + rmesa->SetupIndex = index; + + ctx->Driver.RasterSetup = setup_func[index]; +} + +/* Check to see if any updates of the vertex buffer entries are needed. + */ +void radeonDDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint tmp = rmesa->SetupDone; + + s->type = 0; + rmesa->SetupDone = 0; + + if ( (ctx->Array.Summary & VERT_OBJ_ANY) == 0 ) + return; + + if ( ctx->IndirectTriangles ) + return; + + rmesa->SetupDone = tmp; +} + +/* Repair existing precalculated vertices with new data. + */ +void radeonDDPartialRasterSetup( struct vertex_buffer *VB ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); + GLuint new = VB->pipeline->new_outputs; + GLuint available = VB->pipeline->outputs; + GLuint index = 0; + + if ( new & VERT_WIN ) { + new = available; + index |= RADEON_WIN_BIT | RADEON_FOG_BIT; + } + + if ( new & VERT_RGBA ) + index |= RADEON_RGBA_BIT | RADEON_SPEC_BIT; + + if ( new & VERT_TEX0_ANY ) + index |= RADEON_TEX0_BIT; + + if ( new & VERT_TEX1_ANY ) + index |= rmesa->tex_dest[1]; + + if ( new & VERT_FOG_COORD ) + index |= RADEON_FOG_BIT; + + rmesa->SetupDone &= ~index; + index &= rmesa->SetupIndex; + rmesa->SetupDone |= index; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) + radeonPrintSetupFlags( "partial setup function", index ); + + if ( index ) + setup_func[index]( VB, VB->Start, VB->Count ); +} + +void radeonDDDoRasterSetup( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + + if ( VB->Type == VB_CVA_PRECALC ) { + radeonDDPartialRasterSetup( VB ); + } else if ( ctx->Driver.RasterSetup ) { + ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count ); + } +} + + +/* ================================================================ + * Hardware-format vertex buffers + */ + +void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size ) +{ + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + + while ( rvb->size < size ) + rvb->size *= 2; + + ALIGN_FREE( rvb->vert_store ); + rvb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + rvb->verts = (radeonVertexPtr)rvb->vert_store; + + gl_vector1ui_free( &rvb->clipped_elements ); + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { + fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); + exit( 1 ); + } + + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } +} + +void radeonDDRegisterVB( struct vertex_buffer *VB ) +{ + radeonVertexBufferPtr rvb; + + rvb = (radeonVertexBufferPtr)CALLOC( sizeof(*rvb) ); + + rvb->size = VB->Size * 2; + rvb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + rvb->verts = (radeonVertexPtr)rvb->vert_store; + + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { + fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); + exit( 1 ); + } + + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } + + VB->driver_data = rvb; +} + +void radeonDDUnregisterVB( struct vertex_buffer *VB ) +{ + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + + if ( rvb ) { + if ( rvb->vert_store ) ALIGN_FREE( rvb->vert_store ); + gl_vector1ui_free( &rvb->clipped_elements ); + FREE( rvb ); + VB->driver_data = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h new file mode 100644 index 000000000..42329c002 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h @@ -0,0 +1,136 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_VB_H__ +#define __RADEON_VB_H__ + +#ifdef GLX_DIRECT_RENDERING + +/* FIXME: This is endian-specific */ +typedef struct { + GLubyte red; + GLubyte green; + GLubyte blue; + GLubyte alpha; +} radeon_color_t; + +/* The vertex structure. The final tu1/tv1 values are only used in + * multitexture modes, and the rhw2 value is currently never used. + */ +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + radeon_color_t color; /* Diffuse color */ + radeon_color_t specular; /* Specular color (alpha is fog) */ + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ + GLfloat rhw2; /* Reciprocal homogeneous w2 */ +} radeon_vertex; + +/* Format of vertices in radeon_vertex struct: + */ +#define RADEON_TEX0_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0) + +#define RADEON_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1) + +#if 0 +#define RADEON_PROJ_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1 | \ + RADEON_CP_VC_FRMT_Q1) +#endif + + +/* The fastpath code still expects a 16-float stride vertex. + */ +union radeon_vertex_t { + radeon_vertex v; + GLfloat f[16]; + GLuint ui[16]; +}; + +typedef union radeon_vertex_t radeonVertex; +typedef union radeon_vertex_t *radeonVertexPtr; + +typedef struct { + radeonVertexPtr verts; + GLvector1ui clipped_elements; + GLint last_vert; + void *vert_store; + GLuint size; +} *radeonVertexBufferPtr; + +#define RADEON_DRIVER_DATA(vb) ((radeonVertexBufferPtr)((vb)->driver_data)) + +#define RADEON_WIN_BIT 0x01 +#define RADEON_RGBA_BIT 0x02 +#define RADEON_FOG_BIT 0x04 +#define RADEON_SPEC_BIT 0x08 +#define RADEON_TEX0_BIT 0x10 +#define RADEON_TEX1_BIT 0x20 +#define RADEON_MAX_SETUPFUNC 0x40 + +extern void radeonDDChooseRasterSetupFunc( GLcontext *ctx ); +extern void radeonPrintSetupFlags( char *msg, GLuint flags ); + +extern void radeonDDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ); +extern void radeonDDPartialRasterSetup( struct vertex_buffer *VB ); +extern void radeonDDDoRasterSetup( struct vertex_buffer *VB ); + +extern void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size ); +extern void radeonDDRegisterVB( struct vertex_buffer *VB ); +extern void radeonDDUnregisterVB( struct vertex_buffer *VB ); + +extern void radeonDDSetupInit( void ); + +#endif +#endif /* __RADEON_VB_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c new file mode 100644 index 000000000..e4ff4301f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c @@ -0,0 +1,280 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifdef GLX_DIRECT_RENDERING + +/* Radeon Mesa driver includes */ +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_tex.h" + +/* Mesa src includes */ +#include "context.h" +#include "simple_list.h" +#include "mmath.h" + +extern void __driRegisterExtensions( void ); + +static radeonContextPtr radeonCtx = NULL; + + +/* Initialize the driver specific screen private data. + */ +GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) +{ + sPriv->private = (void *) radeonCreateScreen( sPriv ); + if ( !sPriv->private ) { + radeonDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + +/* Reset the driver specific screen private data. + */ +void XMesaResetDriver( __DRIscreenPrivate *sPriv ) +{ + radeonDestroyScreen( sPriv ); +} + +/* Create and initialize the Mesa and driver specific visual data. + */ +GLvisual *XMesaCreateVisual( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config ) +{ + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount( visinfo->red_mask ), + _mesa_bitcount( visinfo->green_mask ), + _mesa_bitcount( visinfo->blue_mask ), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */); +} + +/* Create and initialize the Mesa and driver specific context data. + */ +GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) +{ + return radeonCreateContext( dpy, mesaVis, driContextPriv ); +} + +/* Destroy the Mesa and driver specific context data. + */ +void XMesaDestroyContext( __DRIcontextPrivate *driContextPriv ) +{ + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + + if ( rmesa == (void *)radeonCtx) radeonCtx = NULL; + radeonDestroyContext( rmesa ); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis ) +{ + return gl_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + GL_FALSE /* software alpha buffer? */ ); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis ) +{ +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 ); +#else + return NULL; /* not implemented yet */ +#endif +} + +/* Copy the back color buffer to the front color buffer. + */ +void XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) +{ + /* FIXME: This assumes buffer is currently bound to a context. This + * needs to be able to swap buffers when not currently bound. Also, + * this needs to swap according to buffer, and NOT according to + * context! + */ + if ( radeonCtx == NULL ) return; + + /* Only swap buffers when a back buffer exists. + */ + if ( radeonCtx->glCtx->Visual->DBflag ) { + FLUSH_VB( radeonCtx->glCtx, "swap buffers" ); + if ( !radeonCtx->doPageFlip ) { + radeonSwapBuffers( radeonCtx ); + } else { + radeonPageFlip( radeonCtx ); + } + } +} + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + + radeonCtx = radeonMakeCurrent( radeonCtx, rmesa, driDrawPriv ); + + gl_make_current2( radeonCtx->glCtx, + driDrawPriv->mesaBuffer, + driReadPriv->mesaBuffer ); + + if ( radeonCtx->driDrawable != driDrawPriv ) { + radeonCtx->driDrawable = driDrawPriv; + radeonCtx->dirty = RADEON_UPLOAD_ALL; + } + + /* GH: We need this to correctly calculate the window offset + * and aux scissor rects. + */ + radeonCtx->new_state = RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + + if ( !radeonCtx->glCtx->Viewport.Width ) { + gl_Viewport( radeonCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); + } + } else { + gl_make_current( 0, 0 ); + radeonCtx = NULL; + } + + return GL_TRUE; +} + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void __driRegisterExtensions( void ) +{ +} + +/* Initialize the fullscreen mode. + */ +GLboolean +XMesaOpenFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + GLint ret; + + /* FIXME: Do we need to check this? + */ + if ( !radeonCtx->glCtx->Visual->DBflag ) + return GL_TRUE; + + LOCK_HARDWARE( rmesa ); + radeonWaitForIdleLocked( rmesa ); + + /* Ignore errors. If this fails, we simply don't do page flipping. + */ + ret = drmRadeonFullScreen( rmesa->driFd, GL_TRUE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = ( ret == 0 ); + + return GL_TRUE; +} + +/* Shut down the fullscreen mode. + */ +GLboolean +XMesaCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + + LOCK_HARDWARE( rmesa ); + radeonWaitForIdleLocked( rmesa ); + + /* Don't care if this fails, we're not page flipping anymore. + */ + drmRadeonFullScreen( rmesa->driFd, GL_FALSE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = GL_FALSE; + rmesa->currentPage = 0; + + return GL_TRUE; +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c index 1caa57200..e166aa96f 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c @@ -40,7 +40,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(XFree86Server) && !defined(XF86DRI) # include "xf86fbman.h" #else +# define CONFIG_DRM_SIS # include "drm.h" +# undef CONFIG_DRM_SIS # include "sis_drm.h" # include <sys/ioctl.h> #endif |