diff options
author | dawes <dawes> | 2000-12-05 16:38:19 +0000 |
---|---|---|
committer | dawes <dawes> | 2000-12-05 16:38:19 +0000 |
commit | de862f7f2c68c12cbfdb72a72c4ea6e97c968f90 (patch) | |
tree | dd8e73c0ad0f1ad5a9929f858bd69b975751ec5c /xc/lib/GL | |
parent | 978cb1e87ff7bfba913e89cc87b302be078c7348 (diff) |
Import of XFree86 4.0.1gX_4_0_1h
Diffstat (limited to 'xc/lib/GL')
34 files changed, 7101 insertions, 4957 deletions
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index b01e433ff..88b259502 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/Imakefile,v 1.15 2000/08/24 22:20:06 tsi Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/Imakefile,v 1.16 2000/12/04 18:54:13 dawes Exp $ #define DoNormalLib NormalLibGlx #define DoSharedLib SharedLibGlx @@ -33,29 +33,42 @@ DRIVER += sis #endif SUBDIRS = $(DRIVER) -#else + +#else /* GlxUseBuiltInDRIDriver */ + #if defined(i386Architecture) || defined(ia64Architecture) -SUBDIRS += gamma -#if HasGlide3 -SUBDIRS += tdfx -#endif + SUBDIRS += common +SUBDIRS += gamma SUBDIRS += mga SUBDIRS += i810 SUBDIRS += r128 SUBDIRS += sis -#elif defined(AlphaArchitecture) -SUBDIRS += gamma #if HasGlide3 SUBDIRS += tdfx #endif + +#elif defined(AlphaArchitecture) + SUBDIRS += common +SUBDIRS += gamma SUBDIRS += mga SUBDIRS += r128 +#if HasGlide3 +SUBDIRS += tdfx +#endif + #elif defined(SparcArchitecture) + SUBDIRS += ffb -#endif -#endif + +#else + +SUBDIRS = + +#endif /* architecture */ + +#endif /* GlxUseBuiltInDRIDriver */ MakeSubdirs($(SUBDIRS)) DependSubdirs($(SUBDIRS)) diff --git a/xc/lib/GL/mesa/src/drv/common/depthtmp.h b/xc/lib/GL/mesa/src/drv/common/depthtmp.h index 3aa307904..0c10eae19 100644 --- a/xc/lib/GL/mesa/src/drv/common/depthtmp.h +++ b/xc/lib/GL/mesa/src/drv/common/depthtmp.h @@ -1,12 +1,20 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/common/depthtmp.h,v 1.4 2000/12/04 22:43:20 dawes Exp $ */ + #ifndef DBG #define DBG 0 #endif +#ifndef HAVE_HW_DEPTH_SPANS +#define HAVE_HW_DEPTH_SPANS 0 +#endif +#ifndef HAVE_HW_DEPTH_PIXELS +#define HAVE_HW_DEPTH_PIXELS 0 +#endif static void TAG(WriteDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLdepth *depth, + const GLdepth *depth, const GLubyte mask[] ) { HW_LOCK() @@ -15,39 +23,45 @@ static void TAG(WriteDepthSpan)( GLcontext *ctx, GLint n1; LOCAL_DEPTH_VARS; - y = Y_FLIP(y); + y = Y_FLIP( y ); - HW_CLIPLOOP() +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n", + (int)n, (int)x ); + + WRITE_DEPTH_SPAN(); +#else + HW_CLIPLOOP() { GLint i = 0; - CLIPSPAN(x,y,n,x1,n1,i); + CLIPSPAN( x, y, n, x1, n1, i ); - if (DBG) fprintf(stderr, "WriteDepthSpan %d..%d (x1 %d)\n", - (int)i, (int)n1, (int)x1); + if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1 ); - if (mask) - { - for (;i<n1;i++,x1++) - if (mask[i]) - WRITE_DEPTH( x1, y, depth[i] ); - } - else - { - for (;i<n1;i++,x1++) + if ( mask ) { + for ( ; i < n1 ; i++, x1++ ) { + if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] ); + } + } else { + for ( ; i < n1 ; i++, x1++ ) { WRITE_DEPTH( x1, y, depth[i] ); + } } } HW_ENDCLIPLOOP(); +#endif } HW_UNLOCK(); } - static void TAG(WriteDepthPixels)( GLcontext *ctx, - GLuint n, - const GLint x[], + GLuint n, + const GLint x[], const GLint y[], - const GLdepth depth[], + const GLdepth depth[], const GLubyte mask[] ) { HW_LOCK() @@ -55,55 +69,64 @@ static void TAG(WriteDepthPixels)( GLcontext *ctx, GLint i; LOCAL_DEPTH_VARS; - if (DBG) fprintf(stderr, "WriteDepthPixels\n"); + if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + WRITE_DEPTH_PIXELS(); +#else HW_CLIPLOOP() { - for (i=0;i<n;i++) - { - if (mask[i]) { - const int fy = Y_FLIP(y[i]); - if (CLIPPIXEL(x[i],fy)) + for ( i = 0 ; i < n ; i++ ) { + if ( mask[i] ) { + const int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) WRITE_DEPTH( x[i], fy, depth[i] ); } } } HW_ENDCLIPLOOP(); +#endif } HW_UNLOCK(); } - - /* Read depth spans and pixels */ static void TAG(ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, - GLdepth depth[]) + GLdepth depth[] ) { HW_LOCK() { - GLint x1,n1; + GLint x1, n1; LOCAL_DEPTH_VARS; - y = Y_FLIP(y); + y = Y_FLIP( y ); - if (DBG) fprintf(stderr, "ReadDepthSpan\n"); + if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" ); - HW_CLIPLOOP() +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + READ_DEPTH_SPAN(); +#else + HW_CLIPLOOP() { GLint i = 0; - CLIPSPAN(x,y,n,x1,n1,i); - for (;i<n1;i++) + CLIPSPAN( x, y, n, x1, n1, i ); + for ( ; i < n1 ; i++ ) READ_DEPTH( depth[i], (x1+i), y ); } HW_ENDCLIPLOOP(); +#endif } HW_UNLOCK(); } -static void TAG(ReadDepthPixels)( GLcontext *ctx, GLuint n, +static void TAG(ReadDepthPixels)( GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLdepth depth[] ) { @@ -112,22 +135,34 @@ static void TAG(ReadDepthPixels)( GLcontext *ctx, GLuint n, GLint i; LOCAL_DEPTH_VARS; - if (DBG) fprintf(stderr, "ReadDepthPixels\n"); - + if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + READ_DEPTH_PIXELS(); +#else HW_CLIPLOOP() { - for (i=0;i<n;i++) { + for ( i = 0 ; i < n ;i++ ) { int fy = Y_FLIP( y[i] ); - if (CLIPPIXEL( x[i], fy )) + if ( CLIPPIXEL( x[i], fy ) ) READ_DEPTH( depth[i], x[i], fy ); } } HW_ENDCLIPLOOP(); +#endif } HW_UNLOCK(); } - +#if HAVE_HW_DEPTH_SPANS +#undef WRITE_DEPTH_SPAN +#undef WRITE_DEPTH_PIXELS +#undef READ_DEPTH_SPAN +#undef READ_DEPTH_PIXELS +#else #undef WRITE_DEPTH #undef READ_DEPTH +#endif #undef TAG diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tris.h b/xc/lib/GL/mesa/src/drv/i810/i810tris.h index ae7f906b2..a83adad95 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tris.h +++ b/xc/lib/GL/mesa/src/drv/i810/i810tris.h @@ -15,14 +15,14 @@ * 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 + * 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. * * */ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.7 2000/11/13 23:31:27 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.8 2000/12/04 19:21:43 dawes Exp $ */ #ifndef I810TRIS_INC #define I810TRIS_INC @@ -37,7 +37,7 @@ extern void i810DDTrifuncInit( void ); #define I810_FLAT_BIT 0x1 -#define I810_OFFSET_BIT 0x2 +#define I810_OFFSET_BIT 0x2 #define I810_TWOSIDE_BIT 0x4 #define I810_FALLBACK_BIT 0x8 @@ -45,13 +45,13 @@ extern void i810DDTrifuncInit( void ); static void __inline__ i810_draw_triangle( i810ContextPtr imesa, - i810VertexPtr v0, - i810VertexPtr v1, + i810VertexPtr v0, + i810VertexPtr v1, i810VertexPtr v2 ) { GLuint vertsize = imesa->vertsize; GLuint *vb = i810AllocDwordsInline( imesa, 3 * vertsize ); - int j; + int j; #if defined(USE_X86_ASM) __asm__ __volatile__( "rep ; movsl" @@ -67,23 +67,22 @@ static void __inline__ i810_draw_triangle( i810ContextPtr imesa, : "0" (vertsize), "S" ((long)v2) : "memory" ); #else + for (j = 0 ; j < vertsize ; j++) + vb[j] = v0->ui[j]; - 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] = 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] = v2->ui[j]; #endif } static __inline__ void i810_draw_point( i810ContextPtr imesa, - i810VertexPtr tmp, + i810VertexPtr tmp, float sz ) { int vertsize = imesa->vertsize; @@ -127,8 +126,8 @@ static __inline__ void i810_draw_point( i810ContextPtr imesa, } -static __inline__ void i810_draw_line( i810ContextPtr imesa, - i810VertexPtr v0, +static __inline__ void i810_draw_line( i810ContextPtr imesa, + i810VertexPtr v0, i810VertexPtr v1 ) { GLuint vertsize = imesa->vertsize; @@ -136,21 +135,21 @@ static __inline__ void i810_draw_line( i810ContextPtr imesa, int j; #if defined(USE_X86_ASM) - __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), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); #else - for (j = 0 ; j < vertsize ; j++) - vb[j] = v0->ui[j]; + 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] = v1->ui[j]; #endif } diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile index f73c0477d..fac037986 100644 --- a/xc/lib/GL/mesa/src/drv/r128/Imakefile +++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.9 2000/11/13 23:31:30 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.10 2000/12/04 19:21:44 dawes Exp $ #include <Threads.tmpl> @@ -45,31 +45,31 @@ MESA_INCLUDES = -I. -I.. -I../../include \ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFINES) INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) - R128SRCS = r128_cce.c \ - r128_clear.c \ - r128_context.c \ + R128SRCS = r128_context.c \ r128_dd.c \ r128_fastpath.c \ + r128_eltpath.c \ + r128_ioctl.c \ + r128_lock.c \ r128_pipeline.c \ r128_screen.c \ r128_span.c \ r128_state.c \ - r128_swap.c \ r128_tex.c \ r128_tris.c \ r128_vb.c \ r128_xmesa.c - R128OBJS = r128_cce.o \ - r128_clear.o \ - r128_context.o \ + R128OBJS = r128_context.o \ r128_dd.o \ r128_fastpath.o \ + r128_eltpath.o \ + r128_ioctl.o \ + r128_lock.o \ r128_pipeline.o \ r128_screen.o \ r128_span.o \ r128_state.o \ - r128_swap.o \ r128_tex.o \ r128_tris.o \ r128_vb.o \ 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 169cf212b..e7be00853 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.2 2000/08/25 13:42:28 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.3 2000/12/04 19:21:44 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,16 +28,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ #include <stdlib.h> -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_cce.h" +#include "r128_ioctl.h" #include "r128_dd.h" #include "r128_state.h" #include "r128_span.h" @@ -47,6 +46,19 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "context.h" #include "simple_list.h" +#include "mem.h" + +#ifndef R128_DEBUG +int R128_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 r128CreateContext(Display *dpy, GLvisual *glVisual, @@ -54,21 +66,30 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, { r128ContextPtr r128ctx; r128ScreenPtr r128scrn; - GLcontext *glCtx = driContextPriv->mesaContext; + GLcontext *ctx = driContextPriv->mesaContext; int i; char *v; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - r128ctx = (r128ContextPtr)Xmalloc(sizeof(*r128ctx)); + r128ctx = (r128ContextPtr)Xcalloc(1, sizeof(*r128ctx)); if (!r128ctx) return GL_FALSE; /* Initialize r128Context */ - r128ctx->glCtx = glCtx; - r128ctx->display = dpy; - r128ctx->driContext = driContextPriv; - r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + 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; + + r128scrn = r128ctx->r128Screen = (r128ScreenPtr)(sPriv->private); - r128scrn = r128ctx->r128Screen = - (r128ScreenPtr)(driContextPriv->driScreenPriv->private); + r128ctx->sarea = (R128SAREAPriv *)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); r128ctx->CurrentTexObj[0] = NULL; r128ctx->CurrentTexObj[1] = NULL; @@ -78,16 +99,27 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, r128ctx->texHeap[i] = mmInit(0, r128scrn->texSize[i]); r128ctx->lastTexAge[i] = -1; } + r128ctx->lastTexHeap = r128scrn->NRTexHeaps; - r128ctx->lastSwapAge = 0; + r128ctx->BufferSize = glVisual->DepthBits; + r128ctx->DepthSize = glVisual->DepthBits; + r128ctx->StencilSize = glVisual->StencilBits; - r128ctx->useFastPath = GL_FALSE; + r128ctx->useFastPath = GL_FALSE; + r128ctx->lod_bias = 0x3f; - r128ctx->vert_buf = NULL; + r128ctx->num_verts = 0; + r128ctx->vert_buf = NULL; - r128ctx->CCEbuf = (CARD32 *)malloc(sizeof(*r128ctx->CCEbuf) * - r128scrn->ringEntries); - r128ctx->CCEcount = 0; + r128ctx->elt_buf = NULL; + r128ctx->retained_buf = NULL; + r128ctx->vert_heap = r128ctx->r128Screen->buffers->list->address; + +#if 0 + r128ctx->CCEbuf= (CARD32 *)MALLOC(sizeof(*r128ctx->CCEbuf) * + r128scrn->ringEntries); + r128ctx->CCEcount = 0; +#endif if ((v = getenv("LIBGL_CCE_TIMEOUT"))) r128ctx->CCEtimeout = strtoul(v, NULL, 10); @@ -97,45 +129,27 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, if (r128ctx->CCEtimeout <= 0) r128ctx->CCEtimeout = 1; /* Initialize GLcontext */ - glCtx->DriverCtx = (void *)r128ctx; + ctx->DriverCtx = (void *)r128ctx; - r128DDInitExtensions(glCtx); + r128DDInitExtensions(ctx); - r128DDInitDriverFuncs(glCtx); - r128DDInitStateFuncs(glCtx); - r128DDInitSpanFuncs(glCtx); - r128DDInitTextureFuncs(glCtx); + r128DDInitDriverFuncs(ctx); + r128DDInitIoctlFuncs(ctx); + r128DDInitStateFuncs(ctx); + r128DDInitSpanFuncs(ctx); + r128DDInitTextureFuncs(ctx); - /* Do this after initialization of r128ctx->Fallback in InitState(). - */ - if (getenv("LIBGL_SOFTWARE_RENDERING")) - r128ctx->Fallback |= R128_FALLBACK_SWONLY; - - /* KW: No vertex buffer code for PCI cards -- for now fallback to - * software always. - * GTH: There is support there, but I'm seeing strange behaviour - * with it enabled. I'll leave the software fallbacks in place - * for now. - */ - if (r128scrn->IsPCI) - r128ctx->Fallback |= R128_FALLBACK_SWONLY; - - if (getenv("LIBGL_NO_SOFTWARE_FALLBACKS")) - r128ctx->SWfallbackDisable = GL_TRUE; - else - r128ctx->SWfallbackDisable = GL_FALSE; - - glCtx->Driver.TriangleCaps = (DD_TRI_CULL - | DD_TRI_LIGHT_TWOSIDE - | DD_TRI_OFFSET); + ctx->Driver.TriangleCaps = (DD_TRI_CULL + | DD_TRI_LIGHT_TWOSIDE + | DD_TRI_OFFSET); /* Ask Mesa to clip fog coordinates for us */ - glCtx->TriangleCaps |= DD_CLIP_FOG_COORD; + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; /* Reset Mesa's current 2D texture pointers to the driver's textures */ - glCtx->Shared->DefaultD[2][0].DriverData = NULL; - glCtx->Shared->DefaultD[2][1].DriverData = NULL; + 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 @@ -143,17 +157,17 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, * Gareth: Please check these numbers are OK) */ if (r128scrn->texSize[0] < 2*1024*1024) { - glCtx->Const.MaxTextureLevels = 9; - glCtx->Const.MaxTextureSize = 1<<8; + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = 1<<8; } else if (r128scrn->texSize[0] < 8*1024*1024) { - glCtx->Const.MaxTextureLevels = 10; - glCtx->Const.MaxTextureSize = 1<<9; + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = 1<<9; } else { - glCtx->Const.MaxTextureLevels = 11; - glCtx->Const.MaxTextureSize = 1<<10; + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = 1<<10; } - glCtx->Const.MaxTextureUnits = 2; + ctx->Const.MaxTextureUnits = 2; #if ENABLE_PERF_BOXES if (getenv("LIBGL_PERFORMANCE_BOXES")) @@ -164,14 +178,14 @@ GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, /* If Mesa has current a vertex buffer, make sure the driver's VB data is up to date */ - if (glCtx->VB) r128DDRegisterVB(glCtx->VB); + if (ctx->VB) r128DDRegisterVB(ctx->VB); /* Register the fast path */ - if (glCtx->NrPipelineStages) - glCtx->NrPipelineStages = - r128DDRegisterPipelineStages(glCtx->PipelineStage, - glCtx->PipelineStage, - glCtx->NrPipelineStages); + if (ctx->NrPipelineStages) + ctx->NrPipelineStages = + r128DDRegisterPipelineStages(ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages); r128DDInitState(r128ctx); @@ -187,7 +201,9 @@ void r128DestroyContext(r128ContextPtr r128ctx) r128TexObjPtr t, next_t; int i; - free(r128ctx->CCEbuf); +#if 0 + FREE( r128ctx->CCEbuf ); +#endif for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) { foreach_s (t, next_t, &r128ctx->TexObjList[i]) @@ -199,6 +215,10 @@ void r128DestroyContext(r128ContextPtr r128ctx) Xfree(r128ctx); } + +#if 0 + glx_fini_prof(); +#endif } /* Load the device specific context into the hardware. The actual @@ -209,16 +229,17 @@ r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, { if (oldCtx) { if (!R128CCE_USE_RING_BUFFER(newCtx->r128Screen->CCEMode)) - newCtx->dirty |= R128_REQUIRE_QUIESCENCE; + newCtx->dirty |= R128_REQUIRE_QUIESCENCE; if (oldCtx != newCtx) { - newCtx->dirty |= R128_UPDATE_CONTEXT; - newCtx->dirty_context |= R128_CTX_ALL_DIRTY; + newCtx->new_state |= R128_NEW_CONTEXT; + newCtx->dirty = R128_UPLOAD_ALL; + } + if (oldCtx->driDrawable != dPriv) { + newCtx->new_state |= R128_NEW_WINDOW; } - if (oldCtx->driDrawable != dPriv) - newCtx->dirty |= R128_UPDATE_WINPOS; } else { - newCtx->dirty |= R128_UPDATE_CONTEXT; - newCtx->dirty_context |= R128_CTX_ALL_DIRTY; + newCtx->new_state |= R128_NEW_CONTEXT; + newCtx->dirty = R128_UPLOAD_ALL; } newCtx->driDrawable = dPriv; 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 5d80eb0a5..1b62681eb 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.2 2000/08/25 13:42:28 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.3 2000/12/04 19:21:44 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -37,197 +38,203 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING +#include <X11/Xlibint.h> + +#include "dri_mesaint.h" +#include "dri_tmm.h" + +#include "xf86drm.h" +#include "xf86drmR128.h" + +#include "types.h" + +#include "r128_sarea.h" +#include "r128_reg.h" + struct r128_context; typedef struct r128_context r128ContextRec; typedef struct r128_context *r128ContextPtr; +#include "r128_lock.h" #include "r128_texobj.h" +#include "r128_screen.h" -/* Flags for what needs to be updated before a new primitive is rendered */ -#define R128_CLEAN 0x0000 -#define R128_REQUIRE_QUIESCENCE 0x0001 -#define R128_UPDATE_CONTEXT 0x0002 -#define R128_UPDATE_WINPOS 0x0004 -#define R128_UPDATE_TEX0IMAGES 0x0008 -#define R128_UPDATE_TEX1IMAGES 0x0010 -#define R128_UPDATE_TEXSTATE 0x0020 -#define R128_ALL_DIRTY 0xffff - -/* Flags for what context state needs to be updated */ -#define R128_CTX_CLEAN 0x0000 -#define R128_CTX_MISC 0x0001 -#define R128_CTX_ENGINESTATE 0x0002 -#define R128_CTX_TEX0STATE 0x0004 -#define R128_CTX_TEX1STATE 0x0008 -#define R128_CTX_TEXENVSTATE 0x0010 -#define R128_CTX_FOGSTATE 0x0020 -#define R128_CTX_ZSTENSTATE 0x0080 -#define R128_CTX_SCISSORS 0x0100 -#define R128_CTX_ALPHASTATE 0x0200 -#define R128_CTX_SETUPSTATE 0x0400 -#define R128_CTX_WIN_Z_POS 0x0800 -#define R128_CTX_FLUSH_PIX_CACHE 0x1000 -#define R128_CTX_ALL_DIRTY 0xffff - -/* Flags for software fallback cases */ -#define R128_FALLBACK_TEXTURE 0x0001 -#define R128_FALLBACK_DRAW_BUFFER 0x0002 -#define R128_FALLBACK_READ_BUFFER 0x0004 -#define R128_FALLBACK_COLORMASK 0x0008 -#define R128_FALLBACK_STIPPLE 0x0010 -#define R128_FALLBACK_SWONLY 0x0020 -#define R128_FALLBACK_RENDER_MODE 0x0040 -#define R128_FALLBACK_MULTIDRAW 0x0080 -#define R128_FALLBACK_LOGICOP 0x0100 - -typedef void (*r128InterpFunc)( GLfloat t, - GLfloat *result, - const GLfloat *in, - const GLfloat *out ); - -/* NOTE: The groups below need to be kept together so that a single - memcpy can be used to transfer data to the ring buffer */ -typedef struct { - CARD32 scale_3d_cntl; /* 0x1a00 */ - - CARD32 aux_sc_cntl; /* 0x1660 */ - CARD32 aux1_sc_left; - CARD32 aux1_sc_right; - CARD32 aux1_sc_top; - CARD32 aux1_sc_bottom; - CARD32 aux2_sc_left; - CARD32 aux2_sc_right; - CARD32 aux2_sc_top; - CARD32 aux2_sc_bottom; - CARD32 aux3_sc_left; - CARD32 aux3_sc_right; - CARD32 aux3_sc_top; - CARD32 aux3_sc_bottom; /* 0x1690 */ - - CARD32 dst_pitch_offset_c; /* 0x1c80 */ - CARD32 dp_gui_master_cntl; - CARD32 sc_top_left_c; - CARD32 sc_bottom_right_c; - CARD32 z_offset_c; - CARD32 z_pitch_c; - CARD32 z_sten_cntl_c; - CARD32 tex_cntl_c; - CARD32 misc_3d_state_cntl_reg; - CARD32 texture_clr_cmp_clr_c; - CARD32 texture_clr_cmp_msk_c; - CARD32 fog_color_c; - CARD32 prim_tex_cntl_c; - CARD32 prim_texture_combine_cntl_c; - CARD32 tex_size_pitch_c; - CARD32 prim_tex_offset[R128_TEX_MAXLEVELS]; /* 0x1ce4 */ - - CARD32 sec_tex_cntl_c; /* 0x1d00 */ - CARD32 sec_tex_combine_cntl_c; - CARD32 sec_tex_offset[R128_TEX_MAXLEVELS]; - CARD32 constant_color_c; - CARD32 prim_texture_border_color_c; - CARD32 sec_texture_border_color_c; - CARD32 sten_ref_mask_c; - CARD32 plane_3d_mask_c; /* 0x1d44 */ - - CARD32 setup_cntl; /* 0x1bc4 */ - - CARD32 pm4_vc_fpu_setup; /* 0x071c */ - - CARD32 window_xy_offset; /* 0x1bcc */ - - CARD32 dp_write_mask; /* 0x16cc */ - - CARD32 pc_gui_ctlstat; /* 0x1748 */ -} r128ContextRegs; - -struct r128_context { - GLcontext *glCtx; /* Mesa context */ - int dirty; /* Hardware state to be updated */ - int dirty_context; /* Context state to be updated */ - - int vertsize; /* Size of current vertices */ - CARD32 vc_format; /* Format of current vertices */ - int multitex; - GLfloat depth_scale; +/* Flags for what context state needs to be updated: + */ +#define R128_NEW_ALPHA 0x0001 +#define R128_NEW_DEPTH 0x0002 +#define R128_NEW_FOG 0x0004 +#define R128_NEW_CLIP 0x0008 +#define R128_NEW_CULL 0x0010 +#define R128_NEW_MASKS 0x0020 +#define R128_NEW_RENDER 0x0040 +#define R128_NEW_WINDOW 0x0080 +#define R128_NEW_TEXTURE 0x0100 +#define R128_NEW_CONTEXT 0x0200 +#define R128_NEW_ALL 0x03ff + +/* Flags for software fallback cases: + */ +#define R128_FALLBACK_TEXTURE 0x0001 +#define R128_FALLBACK_DRAW_BUFFER 0x0002 +#define R128_FALLBACK_READ_BUFFER 0x0004 +#define R128_FALLBACK_STENCIL 0x0008 +#define R128_FALLBACK_RENDER_MODE 0x0010 +#define R128_FALLBACK_MULTIDRAW 0x0020 +#define R128_FALLBACK_LOGICOP 0x0040 + +/* Reasons why the GL_BLEND fallback mightn't work: + */ +#define R128_BLEND_ENV_COLOR 0x1 +#define R128_BLEND_MULTITEX 0x2 - int SWfallbackDisable; /* Disable software fallbacks */ +/* Subpixel offsets for window coordinates: + */ +#define SUBPIXEL_X (-0.5F) +#define SUBPIXEL_Y (-0.5F + 0.125) - r128TexObjPtr CurrentTexObj[2]; /* Ptr to current texture - object associated with - each texture unit */ - /* List of tex swapped in per heap*/ - r128TexObj TexObjList[R128_NR_TEX_HEAPS]; - r128TexObj SwappedOut; /* List of textures swapped out */ - memHeap_t *texHeap[R128_NR_TEX_HEAPS]; /* Global tex heaps */ - /* Last known global tex heap ages */ - int lastTexAge[R128_NR_TEX_HEAPS]; +typedef void (*r128_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); - CARD32 lastSwapAge; /* Last known swap age */ +struct r128_elt_tab { + void (*emit_unclipped_verts)( struct vertex_buffer *VB ); - int Scissor; - XF86DRIClipRectRec ScissorRect; /* Current software scissor */ + void (*build_tri_verts)( r128ContextPtr r128ctx, + struct vertex_buffer *VB, + GLfloat *O, GLuint *elt ); - int useFastPath; /* Currently using Fast Path code */ - int SetupIndex; /* Raster setup function index */ - int SetupDone; /* Partial raster setup done? */ - int RenderIndex; /* Render state function index */ - r128InterpFunc interp; /* Current vert interp function */ + void (*interp)( GLfloat t, GLfloat *O, + const GLfloat *I, const GLfloat *J ); - drmBufPtr vert_buf; /* VB currently being filled */ + void (*project_and_emit_verts)( r128ContextPtr r128ctx, + const GLfloat *verts, + GLuint *elts, + int nr ); +}; +struct r128_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 vertsize; + CARD32 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[2]; + GLint tex_dest[2]; + GLuint blend_flags; + CARD32 env_color; + GLint lod_bias; + + /* 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; + + /* Current rendering state, fallbacks + */ + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + + CARD32 IndirectTriangles; + CARD32 Fallback; + + /* Fast path + */ + GLuint useFastPath; + GLuint SetupIndex; + GLuint SetupDone; + GLuint RenderIndex; + r128_interp_func interp; + + /* Vertex buffers + */ + 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 + */ #if 0 - drmBufPtr elt_buf, retained_buf, index_buf; - GLushort *first_elt, *next_elt, *last_elt; - GLfloat *next_vert, *last_vert; - CARD32 next_vert_index; - CARD32 first_vert_index; - struct r128_elt_tab *elt_tab; - GLfloat device_matrix[16]; + CARD32 *CCEbuf; /* buffer to submit to CCE */ + GLuint CCEcount; /* number of dwords in CCEbuf */ #endif - - points_func PointsFunc; /* Current Points, Line, Triangle */ - line_func LineFunc; /* and Quad rendering functions */ - triangle_func TriangleFunc; - quad_func QuadFunc; - - CARD32 IndirectTriangles; /* Flags for point, line, - tri and quad software - fallbacks */ - CARD32 Fallback; /* Need software fallback */ - - r128ContextRegs regs; /* Hardware state */ - CARD32 Color; /* Current draw color */ - CARD32 ClearColor; /* Color used to clear color buffer */ - CARD32 ClearDepth; /* Value used to clear depth buffer */ - - int drawX; /* x-offset to current draw buffer */ - int drawY; /* y-offset to current draw buffer */ - - int readX; /* x-offset to current read buffer */ - int readY; /* y-offset to current read buffer */ - - CARD32 *CCEbuf; /* buffer to submit to CCE */ - int CCEcount; /* number of dwords in CCEbuf */ - - int CCEtimeout; /* number of times to loop + GLint CCEtimeout; /* number of times to loop before exiting */ - Display *display; /* X server display */ - - __DRIcontextPrivate *driContext; /* DRI context */ - __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ - - r128ScreenPtr r128Screen; /* Screen private DRI data */ - - /* Performance counters: */ - int boxes; /* Draw performance boxes */ - int hardwareWentIdle; - int c_clears; - int c_drawWaits; - int c_textureSwaps; - int c_textureBytes; - int c_vertexBuffers; + /* Visual, drawable, cliprect and scissor information + */ + GLint BufferSize; /* Bits in color buffer */ + 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; + + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + + GLuint scissor; + XF86DRIClipRectRec ScissorRect; /* 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; + + r128ScreenPtr r128Screen; /* Screen private DRI data */ + R128SAREAPriv *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 R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) @@ -236,6 +243,14 @@ struct r128_context { #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) + + extern GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, __DRIcontextPrivate *driContextPriv); extern void r128DestroyContext(r128ContextPtr r128ctx); @@ -243,5 +258,27 @@ extern r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, r128ContextPtr newCtx, __DRIdrawablePrivate *dPriv); + +/* ================================================================ + * Debugging: + */ +#define DEBUG 0 +#define DEBUG_LOCKING 0 +#define ENABLE_PERF_BOXES 0 + +#if DEBUG +extern int R128_DEBUG; +#else +#define R128_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 /* _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 f0698e21b..636b712a8 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.2 2000/08/25 13:42:28 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.3 2000/12/04 19:21:45 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,174 +28,184 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_lock.h" -#include "r128_cce.h" -#include "r128_clear.h" +#include "r128_ioctl.h" #include "r128_state.h" -#include "r128_swap.h" #include "r128_vb.h" #include "r128_pipeline.h" #include "r128_dd.h" #include "extensions.h" - -/* Driver entry point for clearing color and ancillary buffers */ -static GLbitfield r128DDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - - if (mask & DD_FRONT_LEFT_BIT) { - r128ClearColorBuffer(r128ctx, all, x, y, width, height, - r128ctx->r128Screen->fbX, - r128ctx->r128Screen->fbY); - mask &= ~DD_FRONT_LEFT_BIT; - } - - if (mask & DD_BACK_LEFT_BIT) { - r128ClearColorBuffer(r128ctx, all, x, y, width, height, - r128ctx->r128Screen->backX, - r128ctx->r128Screen->backY); - mask &= ~DD_BACK_LEFT_BIT; - } - - if (mask & DD_DEPTH_BIT) { - r128ClearDepthBuffer(r128ctx, all, x, y, width, height); - mask &= ~DD_DEPTH_BIT; - } - -#if 0 - /* FIXME: Add stencil support */ - if (mask & DD_STENCIL_BIT) { - r128ClearStencilBuffer(r128ctx, all, x, y, width, height); - mask &= ~DD_STENCIL_BIT; - } +#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM) +#include "X86/common_x86_asm.h" #endif - return mask; -} +#define R128_DATE "20001201" /* Return the current color buffer size */ -static void r128DDGetBufferSize(GLcontext *ctx, GLuint *width, GLuint *height) +static void r128DDGetBufferSize( GLcontext *ctx, + GLuint *width, GLuint *height ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - *width = r128ctx->driDrawable->w; - *height = r128ctx->driDrawable->h; + *width = r128ctx->driDrawable->w; + *height = r128ctx->driDrawable->h; } /* Return various strings for glGetString() */ -static const GLubyte *r128DDGetString(GLcontext *ctx, GLenum name) +static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) { - switch (name) { - case GL_VENDOR: - return (GLubyte *)"Precision Insight, Inc."; - case GL_RENDERER: - return (GLubyte *)"Mesa DRI Rage128 20000630"; - default: - return NULL; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + static GLubyte buffer[128]; + + switch ( name ) { + case GL_VENDOR: + return "VA Linux Systems, Inc."; + + case GL_RENDERER: + sprintf( buffer, "Mesa DRI Rage128 " R128_DATE ); + + /* Append any chipset-specific information. + */ + if ( R128_IS_PRO( r128ctx ) ) { + strncat( buffer, " Pro", 4 ); + } + if ( R128_IS_MOBILITY( r128ctx ) ) { + strncat( buffer, " M3", 3 ); + } + + /* Append any AGP-specific information. + */ + switch ( r128ctx->r128Screen->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 r128DDFlush(GLcontext *ctx) + * 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 r128DDFlush( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - FLUSH_BATCH(r128ctx); + FLUSH_BATCH( r128ctx ); #if ENABLE_PERF_BOXES - if (r128ctx->boxes) { - LOCK_HARDWARE(r128ctx); - r128PerformanceBoxesLocked(r128ctx); - UNLOCK_HARDWARE(r128ctx); - } - - /* Log the performance counters if necessary */ - r128PerformanceCounters(r128ctx); + if ( r128ctx->boxes ) { + LOCK_HARDWARE( r128ctx ); + r128PerformanceBoxesLocked( r128ctx ); + UNLOCK_HARDWARE( r128ctx ); + } + + /* Log the performance counters if necessary */ + r128PerformanceCounters( r128ctx ); #endif } /* Make sure all commands have been sent to the hardware and have - completed processing. */ -static void r128DDFinish(GLcontext *ctx) + * completed processing. + */ +static void r128DDFinish( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); #if ENABLE_PERF_BOXES - /* Bump the performance counter */ - r128ctx->c_drawWaits++; + /* Bump the performance counter */ + r128ctx->c_drawWaits++; #endif - r128DDFlush(ctx); - r128WaitForIdle(r128ctx); + r128DDFlush( ctx ); + r128WaitForIdle( r128ctx ); } /* Return various parameters requested by Mesa (this is deprecated) */ -static GLint r128DDGetParameteri(const GLcontext *ctx, GLint param) +static GLint r128DDGetParameteri( const GLcontext *ctx, GLint param ) { - switch (param) { - /* Hardware fog isn't working yet -- however returning zero - * here means that it looks like fog is working in some cases. - * It is less confusing to simply have it never work until it - * is actually fixed. - */ - case DD_HAVE_HARDWARE_FOG: return 1; - default: return 0; - } + switch (param) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + return 0; + } } /* Initialize the extensions supported by this driver */ -void r128DDInitExtensions(GLcontext *ctx) +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_EXT_blend_logic_op"); - gl_extensions_disable(ctx, "GL_EXT_blend_subtract"); - gl_extensions_disable(ctx, "GL_INGR_blend_func_separate"); - - if (getenv("LIBGL_NO_MULTITEXTURE")) - gl_extensions_disable(ctx, "GL_ARB_multitexture"); - - 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" ); + /* 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_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + + if ( getenv( "LIBGL_NO_MULTITEXTURE" ) ) + gl_extensions_disable( ctx, "GL_ARB_multitexture" ); + + 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 */ -void r128DDInitDriverFuncs(GLcontext *ctx) +void r128DDInitDriverFuncs( GLcontext *ctx ) { - ctx->Driver.Clear = r128DDClear; - - 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 f58dbd39a..447745c43 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h @@ -1,8 +1,8 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.h,v 1.1 2000/06/17 00:03:05 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.h,v 1.2 2000/12/04 19:21:45 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., - Cedar Park, Texas. + Cedar Park, Texas. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c new file mode 100644 index 000000000..c02196ef9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c @@ -0,0 +1,552 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c,v 1.1 2000/12/04 19:21:46 dawes Exp $ */ +/* + * 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. + * + */ + +#include <stdio.h> + +#include "r128_context.h" +#include "r128_pipeline.h" +#include "r128_ioctl.h" +#include "r128_tris.h" +#include "r128_state.h" +#include "r128_vb.h" + +#include "types.h" +#include "enums.h" +#include "cva.h" +#include "vertices.h" +#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 ) +{ + int vertsize = r128ctx->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 ); + + /* Fire queued elements and discard that buffer if its contents + * won't be referenced by future elements. + */ + if ( r128ctx->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), + !retain ); + } else if ( !retain ) { + r128ReleaseBufLocked( r128ctx, r128ctx->elt_buf ); + } + + r128ctx->elt_buf = 0; + } + else if ( r128ctx->vert_buf ) + { + r128FlushVerticesLocked( r128ctx ); + } + + r128GetEltBufLocked( r128ctx ); + + UNLOCK_HARDWARE( r128ctx ); + + /* Give the compiler a chance to optimize the divisions. + */ + switch ( vertsize ) { + case 8: + r128ctx->next_vert_index = (GLushort) + (((r128ctx->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)); + break; + + case 10: + r128ctx->next_vert_index = (GLushort) + (((r128ctx->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)); + break; + } + + r128ctx->first_elt = r128ctx->next_elt = (GLushort *) + ((GLubyte *)r128ctx->elt_buf->address + R128_INDEX_PRIM_OFFSET); + + r128ctx->elt_vertsize = vertsize; + + 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 ); +} + + +static void release_bufs( r128ContextPtr r128ctx ) +{ + 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 ) + { + 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), + 0 ); + + ALIGN_NEXT_ELT( r128ctx ); + r128ctx->first_elt = r128ctx->next_elt; + } + + r128ReleaseBufLocked( r128ctx, r128ctx->retained_buf ); + UNLOCK_HARDWARE( r128ctx ); + } + + r128ctx->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) { \ + 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 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; \ +} + + +static void r128_tri_clip( r128ContextPtr r128ctx, + struct vertex_buffer *VB, + GLuint *elt, + GLubyte mask ) +{ + struct r128_elt_tab *tab = r128ctx->elt_tab; + r128_interp_func interp = tab->interp; + int vertsize = r128ctx->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( r128ctx, 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)r128ctx->next_vert - + (GLuint)r128ctx->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, n * (vertsize + 2) * sizeof(GLuint), + space < n * (vertsize + 2) * sizeof(GLuint) ); + + if ( space < n * (vertsize + 2) * sizeof(GLuint) ) { + fire_elts( r128ctx ); + } + + /* 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 ); + + /* 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; + } + } +} + + + + +/* 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)(r128ctx->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 ); \ + } \ + 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; \ +} 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; \ + r128_tri_clip( r128ctx, VB, out, ormask ); \ + } \ +} while (0) + +#define LOCAL_VARS \ + r128ContextPtr r128ctx = 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; + + + +#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) r128_##x##_elt +#include "render_tmp.h" + + + +#define LOCAL_VARS \ + r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); \ + GLuint *elt = VB->EltPtr->data; \ + (void) elt; (void) r128ctx; + +#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) r128_##x##_elt_unclipped +#include "render_tmp.h" + + + + +static void refresh_projection_matrix( GLcontext *ctx ) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + GLmatrix *mat = &ctx->Viewport.WindowMap; + GLfloat *m = r128ctx->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; +} + +#define CLIP_UBYTE_B 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_R 2 +#define CLIP_UBYTE_A 3 + + +#define TYPE (0) +#define TAG(x) x +#include "r128_elttmp.h" + +#define TYPE (R128_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "r128_elttmp.h" + +#define TYPE (R128_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "r128_elttmp.h" + +#define TYPE (R128_RGBA_BIT|R128_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "r128_elttmp.h" + +#define TYPE (R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "r128_elttmp.h" + +#define TYPE (R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "r128_elttmp.h" + + +/* Very sparsely popluated array - fix the indices. + */ +static struct r128_elt_tab r128EltTab[0x80]; + +void r128DDEltPathInit( void ) +{ + r128_render_init_elt(); + r128_render_init_elt_unclipped(); + + r128_init_eltpath( &r128EltTab[0] ); + r128_init_eltpath_RGBA( &r128EltTab[R128_RGBA_BIT] ); + 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] ); +} + +#define VALID_SETUP (R128_RGBA_BIT|R128_TEX0_BIT|R128_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 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; + GLint space; + + if ( DEBUG_ELTPATH ) + fprintf( stderr, "\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 ); + + 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 ) { + if ( DEBUG_ELTPATH ) + fprintf( stderr, " clipped, returning...\n" ); + return; + } + if ( r128ctx->vert_buf ) { + r128FlushVertices( r128ctx ); + } + if ( r128ctx->new_state ) { + r128DDUpdateHWState( ctx ); + } + + space = (GLint)((GLuint)r128ctx->next_vert - + (GLuint)r128ctx->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, + 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 < VB->Count * vertsize * sizeof(GLuint) || + space < 0 || r128ctx->vertsize != r128ctx->elt_vertsize ) { + fire_elts( r128ctx ); + } + + r128ctx->retained_buf = r128ctx->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 ) { + r128ctx->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 ); + } + + /* Send to hardware and release the elt buffer. + */ + release_bufs( r128ctx ); + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; + + if ( 0 ) { + 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 new file mode 100644 index 000000000..ba82a261f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h @@ -0,0 +1,274 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h,v 1.1 2000/12/04 19:21:46 dawes Exp $ */ +/* + * 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. + * + */ + +/* 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 ) +{ + GLuint i; + r128ContextPtr r128ctx = R128_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 = r128ctx->vertsize; + + GLfloat *f = r128ctx->next_vert; + GLuint count = VB->Count; + GLubyte *clipmask = VB->ClipMask; + + const GLfloat *m = r128ctx->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + + 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; + + 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 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" ); +#else + GLubyte *b = (GLubyte *)&f[4]; + b[CLIP_UBYTE_B] = color[2]; + b[CLIP_UBYTE_G] = color[1]; + b[CLIP_UBYTE_R] = color[0]; + b[CLIP_UBYTE_A] = color[3]; +#endif + } + + if (TYPE & R128_TEX0_BIT) { + *(int*)&f[6] = *(int*)&tex0_data[0]; + *(int*)&f[7] = *(int*)&tex0_data[1]; + } + + if (TYPE & R128_TEX1_BIT) { + *(int*)&f[8] = *(int*)&tex1_data[0]; + *(int*)&f[9] = *(int*)&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); + } + + r128ctx->next_vert = f; + r128ctx->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)( r128ContextPtr r128ctx, + struct vertex_buffer *VB, + GLfloat *O, + GLuint *elt ) +{ + int 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 & 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]; + b[CLIP_UBYTE_B] = col[2]; + 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]); + *(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]); + *(int*)&O[8] = *(int*)&tex1_data[0]; + *(int*)&O[9] = *(int*)&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 & 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_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)( r128ContextPtr r128ctx, + const GLfloat *verts, + GLuint *elt, + int nr) +{ + GLfloat *O = r128ctx->next_vert; + GLushort index = r128ctx->next_vert_index; + GLuint buffer_stride = r128ctx->vertsize; + + const GLfloat *m = r128ctx->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 (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]; + + 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 & R128_RGBA_BIT) { + *(int*)&O[4] = *(int*)&I[4]; + } + + if (TYPE & R128_TEX0_BIT) { + *(int*)&O[6] = *(int*)&I[6]; + *(int*)&O[7] = *(int*)&I[7]; + } + + if (TYPE & R128_TEX1_BIT) { + *(int*)&O[8] = *(int*)&I[8]; + *(int*)&O[9] = *(int*)&I[9]; + } + + O -= buffer_stride; + } + if (0) fprintf(stderr, "0x%x\n", elt[i]); + } + + r128ctx->next_vert = O; + r128ctx->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); +} + +#undef TYPE +#undef TAG +#undef STRIDE 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 2bcf901d0..57dab53a9 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c,v 1.3 2000/11/13 23:31:30 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c,v 1.4 2000/12/04 19:21:46 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,21 +28,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" #include "r128_state.h" #include "r128_vb.h" -#include "r128_cce.h" -#include "r128_tris.h" #include "r128_pipeline.h" +#include "r128_ioctl.h" +#include "r128_tris.h" #include "mmath.h" #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. @@ -51,59 +55,57 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. isn't necesary here. */ -typedef void (*r128BuildVerticesFunc)( struct vertex_buffer *VB, - GLuint do_cliptest ); +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 ); +}; -typedef struct r128_fast_table { - r128BuildVerticesFunc build_vertices; - r128InterpFunc interp; -} r128FastPathTable; +#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) r128DrawPointVB(r128ctx, &vert[x], psize) -#define LINE(x,y) r128DrawLineVB(r128ctx, &vert[x], &vert[y], lwidth) -#define TRI(x,y,z) r128DrawTriangleVB(r128ctx, &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]); \ +#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); \ +#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); \ +#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); \ +#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 \ - 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; \ - (void) lwidth; (void)psize; (void) vert; +#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; \ + (void) lwidth; (void) psize; (void) vert; #define TAG(x) r128_##x##_smooth_indirect #include "render_tmp.h" @@ -115,196 +117,196 @@ do { \ #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); \ - } \ +#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; \ - } \ +#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; \ - } \ +#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 void r128TriClip(GLuint **p_elts, - r128Vertex *verts, - GLubyte *clipmask, - GLuint *p_next_vert, - GLubyte mask, - r128InterpFunc interp) +static __inline void r128_tri_clip( GLuint **p_elts, + r128Vertex *verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + r128_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; + 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 void r128LineClip(GLuint **p_elts, - r128Vertex *verts, - GLubyte *clipmask, - GLuint *p_next_vert, - GLubyte mask, - r128InterpFunc interp) +static __inline void r128_line_clip( GLuint **p_elts, + r128Vertex *verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + r128_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; + 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; \ +#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])) { \ - r128LineClip(&out, verts, mask, &next_vert, ormask, interp); \ - } \ - } \ +#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])) { \ + r128_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])) { \ - r128TriClip(&out, verts, mask, &next_vert, ormask, interp); \ - } \ - } \ +#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])) { \ + r128_tri_clip(&out, verts, mask, &next_vert, ormask, interp); \ + } \ + } \ } while (0) @@ -314,64 +316,65 @@ 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; \ - r128InterpFunc interp = r128ctx->interp; \ - (void) interp; (void) verts; - -#define POSTFIX \ - r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \ - r128VB->last_vert = next_vert; +#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; \ + (void) interp; (void) verts; + +#define POSTFIX \ + r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \ + r128VB->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]); \ +#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 #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_B 0 -#define CLIP_UBYTE_G 1 -#define CLIP_UBYTE_R 2 -#define CLIP_UBYTE_A 3 -#define CLIP_S0 6 -#define CLIP_T0 7 -#define CLIP_S1 8 -#define CLIP_T1 9 +#define CLIP_UBYTE_COLOR 4 +#define CLIP_UBYTE_B 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_R 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 @@ -404,135 +407,136 @@ do { \ /* Render elements directly from original list of vertices. */ -static void r128RenderElementsDirect(struct vertex_buffer *VB) +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->dirty) r128UpdateHWState(r128ctx); - - do { - func(VB, 0, nr, 0); - } while (ctx->Driver.MultipassFunc && - ctx->Driver.MultipassFunc(VB, ++p)); + 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 ) + r128DDUpdateHWState( ctx ); + + do { + func( VB, 0, nr, 0 ); + } while ( ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc( VB, ++p ) ); } /* Project vertices from clip to device space */ -static void r128ProjectVertices(struct vertex_buffer *VB) +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); - GLfloat m[16]; - - 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; - - gl_project_v16(r128VB->verts[VB->CopyStart].f, + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + + 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; + + gl_project_v16( r128VB->verts[VB->CopyStart].f, r128VB->verts[r128VB->last_vert].f, m, - 16 * 4); + 16 * 4 ); } /* Project clipped vertices from clip to device space */ -static void r128ProjectClippedVertices(struct vertex_buffer *VB) +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); - GLfloat m[16]; - - 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; - - gl_project_clipped_v16(r128VB->verts[VB->CopyStart].f, + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + + 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; + + gl_project_clipped_v16( r128VB->verts[VB->CopyStart].f, r128VB->verts[r128VB->last_vert].f, m, 16 * 4, - VB->ClipMask + VB->CopyStart); + VB->ClipMask + VB->CopyStart ); } -static r128FastPathTable r128FastTab[0x80]; +static struct r128_fast_tab r128FastTab[0x80]; /* Initialize the table of fast path support functions */ -void r128DDFastPathInit(void) +void r128DDFastPathInit( void ) { r128_render_init_clip_elt(); r128_render_init_smooth_indirect(); - r128_init_fastpath(&r128FastTab[0]); - r128_init_fastpath_RGBA(&r128FastTab[R128_RGBA_BIT]); - 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( &r128FastTab[0] ); + r128_init_fastpath_RGBA( &r128FastTab[R128_RGBA_BIT] ); + 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] ); } #define VALID_SETUP (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT) -void r128DDFastPath(struct vertex_buffer *VB) +void r128DDFastPath( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - GLenum prim = ctx->CVA.elt_mode; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128FastPathTable *tab = &r128FastTab[r128ctx->SetupIndex & VALID_SETUP]; - GLuint do_cliptest = 1; - - gl_prepare_arrays_cva(VB); /* still need this */ - -#if 0 - if ((gl_reduce_prim[prim] == GL_TRIANGLES) && - (VB->Count < (r128ctx->r128Screen->vbBufSize / 48)) && - (ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL| - MAT_FLAG_PERSPECTIVE))) - { - r128EltPath( VB ); - return; - } -#endif - - /* Reserve enough space for the pathological case */ - if (VB->EltPtr->count * 12 > R128_DRIVER_DATA(VB)->size) { - r128DDResizeVB(VB, VB->EltPtr->count * 12); - do_cliptest = 1; - } - - tab->build_vertices(VB, do_cliptest); /* object->clip space */ - - if (r128ctx->dirty) r128UpdateHWState(r128ctx); - - if (VB->ClipOrMask) { - if (!VB->ClipAndMask) { - render_func *clip = r128_render_tab_clip_elt; - - r128ctx->interp = tab->interp; - clip[prim](VB, 0, VB->EltPtr->count, 0); /* build new elts */ - ctx->CVA.elt_mode = gl_reduce_prim[prim]; - VB->EltPtr = &(R128_DRIVER_DATA(VB)->clipped_elements); - r128ProjectClippedVertices(VB); /* clip->device space */ - r128RenderElementsDirect(VB); /* render using new list */ - } - } else { - r128ProjectVertices(VB); /* clip->device space */ - r128RenderElementsDirect(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; + 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]; + 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| + MAT_FLAG_PERSPECTIVE) ) ) + { + r128DDEltPath( VB ); + return; + } + + /* Reserve enough space for the pathological case */ + if ( VB->EltPtr->count * 12 > R128_DRIVER_DATA(VB)->size ) { + r128DDResizeVB( VB, VB->EltPtr->count * 12 ); + do_cliptest = 1; + } + + tab->build_vertices( VB, do_cliptest ); /* object->clip space */ + + if ( r128ctx->new_state ) + r128DDUpdateHWState( ctx ); + + if ( VB->ClipOrMask ) { + if ( !VB->ClipAndMask ) { + render_func *clip = r128_render_tab_clip_elt; + + r128ctx->interp = tab->interp; + + clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ + + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(R128_DRIVER_DATA(VB)->clipped_elements); + + r128_project_clipped_vertices( VB ); /* clip->device space */ + r128_render_elements_direct( VB ); /* render using new list */ + } + } else { + r128_project_vertices( VB ); /* clip->device space */ + r128_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/r128/r128_fasttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h index 8f0350e12..8f51fe74c 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h,v 1.1 2000/06/17 00:03:05 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h,v 1.2 2000/12/04 19:21:46 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Keith Whitwell <keithw@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -181,7 +182,7 @@ static void TAG(r128_interp_vert)(GLfloat t, } -static void TAG(r128_init_fastpath)(r128FastPathTable *tab) +static void TAG(r128_init_fastpath)(struct r128_fast_tab *tab) { tab->build_vertices = TAG(r128_setup_full); tab->interp = TAG(r128_interp_vert); diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c new file mode 100644 index 000000000..067beff4e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c @@ -0,0 +1,763 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "r128_context.h" +#include "r128_state.h" +#include "r128_ioctl.h" + +#include "mem.h" + +#define R128_TIMEOUT 2000000 + + +/* ============================================================= + * Hardware vertex buffer handling + */ + +/* Get a new VB from the pool of vertex buffers in AGP space. + */ +drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) +{ + int fd = r128ctx->r128Screen->driScreen->fd; + int index = 0; + int size = 0; + drmDMAReq dma; + drmBufPtr buf = NULL; + int to = 0; + int ret; + + dma.context = r128ctx->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = R128_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; + + while ( !buf && ( to++ < r128ctx->CCEtimeout ) ) { + ret = drmDMA( fd, &dma ); + + if ( ret == 0 ) { + buf = &r128ctx->r128Screen->buffers->list[index]; + buf->used = 0; +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + r128ctx->c_vertexBuffers++; +#endif + return buf; + } + } + + if ( !buf ) { + drmR128EngineReset( fd ); + fprintf( stderr, "Error: Could not get new VB... exiting\n" ); + exit( -1 ); + } + + return buf; +} + +void r128FlushVerticesLocked( r128ContextPtr r128ctx ) +{ + XF86DRIClipRectPtr pbox = r128ctx->pClipRects; + int nbox = r128ctx->numClipRects; + drmBufPtr buffer = r128ctx->vert_buf; + int count = r128ctx->num_verts; + int prim = R128_TRIANGLES; + int fd = r128ctx->driScreen->fd; + int i; + + if ( 0 ) + fprintf( stderr, "%s: buf=%d count=%d\n", + __FUNCTION__, buffer ? buffer->idx : -1, count ); + + r128ctx->num_verts = 0; + r128ctx->vert_buf = NULL; + + if ( !buffer ) { + return; + } + + if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128EmitHwStateLocked( r128ctx ); + } + + if ( !nbox ) { + count = 0; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !count || !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + r128ctx->sarea->nbox = 0; + } else { + r128ctx->sarea->nbox = nbox; + } + + drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + int discard = 0; + + r128ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + discard = 1; + } + + r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, discard ); + } + } + + r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + + + +/* ================================================================ + * Indexed vertex buffer handling + */ + +void r128GetEltBufLocked( r128ContextPtr r128ctx ) +{ + r128ctx->elt_buf = r128GetBufferLocked( r128ctx ); +} + +void r128FireEltsLocked( r128ContextPtr r128ctx, + GLuint start, GLuint end, + GLuint discard ) +{ + XF86DRIClipRectPtr pbox = r128ctx->pClipRects; + int nbox = r128ctx->numClipRects; + drmBufPtr buffer = r128ctx->elt_buf; + int prim = R128_TRIANGLES; + int fd = r128ctx->driScreen->fd; + int i; + + if ( 0 ) + fprintf( stderr, "%s: start=%d end=%d discard=%d\n", + __FUNCTION__, start, end, discard ); + + if ( !buffer ) { + return; + } + + if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128EmitHwStateLocked( r128ctx ); + } + + 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 < 3 ) { + r128ctx->sarea->nbox = 0; + } else { + r128ctx->sarea->nbox = nbox; + } + + drmR128FlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + int d = 0; + + r128ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + d = discard; + } + + r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + drmR128FlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + } + + if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { + drmR128WaitForIdleCCE( r128ctx->driFd ); + } + + r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128FlushEltsLocked( r128ContextPtr 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), + 0 ); + + ALIGN_NEXT_ELT( r128ctx ); + r128ctx->first_elt = r128ctx->next_elt; + } +} + +void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ) +{ + int fd = r128ctx->driScreen->fd; + + if ( 0 ) + fprintf( stderr, "%s: buffer=%p\n", + __FUNCTION__, buffer ); + + if ( !buffer ) { + return; + } + drmR128FlushVertexBuffer( fd, R128_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 *r128AllocVertices( r128ContextPtr r128ctx, int count ) +{ + return r128AllocVerticesInline( r128ctx, count ); +} + + + +/* ================================================================ + * Texture uploads + */ + +void r128FireBlitLocked( r128ContextPtr r128ctx, drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, GLint width, GLint height ) +{ + GLint ret; + + ret = drmR128TextureBlit( r128ctx->driFd, buffer->idx, + offset, pitch, format, + x, y, width, height ); + + if ( ret ) { + fprintf( stderr, "drmR128TextureBlit: return = %d\n", ret ); + exit( 1 ); + } +} + + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +static void delay( void ) { +/* Prevent an optimizing compiler from removing a spin loop */ +} + +#define R128_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. + */ +static int r128WaitForFrameCompletion( r128ContextPtr r128ctx ) +{ + unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + CARD32 frame; + int i; + int wait = 0; + + while ( 1 ) { + frame = INREG( R128_LAST_FRAME_REG ); + if ( r128ctx->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) { + break; + } + + /* Spin in place a bit so we aren't hammering the register */ + wait++; + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } + + return wait; +} + +/* Copy the back color buffer to the front color buffer */ +void r128SwapBuffers( r128ContextPtr r128ctx ) +{ + GLint nbox = r128ctx->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 ); + fflush( stderr ); + } + + /* Flush any outstanding vertex buffers */ + FLUSH_BATCH( r128ctx ); + + LOCK_HARDWARE( r128ctx ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !r128WaitForFrameCompletion( r128ctx ) ) { + r128ctx->hardwareWentIdle = 1; + } else { + r128ctx->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; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + r128ctx->sarea->nbox = n; + + ret = drmR128SwapBuffers( r128ctx->driFd ); + + if ( ret ) { + fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); + exit( 1 ); + } + } + + if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { + drmR128WaitForIdleCCE( r128ctx->driFd ); + } + + UNLOCK_HARDWARE( r128ctx ); + + r128ctx->new_state |= R128_NEW_CONTEXT; + r128ctx->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS | + R128_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + r128PerformanceCounters( r128ctx ); +#endif +} + + +/* ================================================================ + * Buffer clear + */ + +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; + GLuint flags = 0; + GLint i; + GLint ret; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s:\n", __FUNCTION__ ); + } + + FLUSH_BATCH( r128ctx ); + + /* 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 ) + r128DDUpdateHWState( ctx ); + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= DRM_R128_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= DRM_R128_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) { + flags |= DRM_R128_DEPTH; + mask &= ~DD_DEPTH_BIT; + } +#if 0 + /* FIXME: Add stencil support */ + if ( mask & DD_STENCIL_BIT ) { + flags |= DRM_R128_DEPTH; + mask &= ~DD_STENCIL_BIT; + } +#endif + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( r128ctx ); + + if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128EmitHwStateLocked( r128ctx ); + } + + 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; + 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++; + } + } + + r128ctx->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 ); + } + + ret = drmR128Clear( r128ctx->driFd, flags, + cx, cy, cw, ch, + r128ctx->ClearColor, r128ctx->ClearDepth, + 0xffffffff, 0xffffffff ); + + if ( ret ) { + fprintf( stderr, "drmR128Clear: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( r128ctx ); + + r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + + return mask; +} + + +/* ================================================================ + * Depth spans, pixels + */ + +void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, + 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; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + r128ctx->sarea->nbox = 0; + } else { + r128ctx->sarea->nbox = nbox; + } + + drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + + r128ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); + } + } + + r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, 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; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + r128ctx->sarea->nbox = 0; + } else { + r128ctx->sarea->nbox = nbox; + } + + drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + + r128ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); + } + } + + r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, + GLuint n, GLint x, GLint y ) +{ + XF86DRIClipRectPtr pbox = r128ctx->pClipRects; + int nbox = r128ctx->numClipRects; + int fd = r128ctx->driScreen->fd; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + r128ctx->sarea->nbox = 0; + } else { + r128ctx->sarea->nbox = nbox; + } + + drmR128ReadDepthSpan( fd, n, x, y ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + + r128ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + drmR128ReadDepthSpan( fd, n, x, y ); + } + } + + r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, + const GLint x[], const GLint y[] ) +{ + XF86DRIClipRectPtr pbox = r128ctx->pClipRects; + int nbox = r128ctx->numClipRects; + int fd = r128ctx->driScreen->fd; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + r128ctx->sarea->nbox = 0; + } else { + r128ctx->sarea->nbox = nbox; + } + + drmR128ReadDepthPixels( fd, n, x, y ); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + + r128ctx->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + drmR128ReadDepthPixels( fd, n, x, y ); + } + } + + r128ctx->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 ) +{ + int fd = r128ctx->r128Screen->driScreen->fd; + int to = 0; + int ret; + + do { + ret = drmR128WaitForIdleCCE( fd ); + } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) ); + + if ( ret < 0 ) { + drmR128EngineReset( fd ); + fprintf( stderr, "Error: Rage 128 timed out... exiting\n" ); + exit( -1 ); + } +} + + +void r128DDInitIoctlFuncs( GLcontext *ctx ) +{ + 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 new file mode 100644 index 000000000..43b77659b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h @@ -0,0 +1,217 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __R128_IOCTL_H__ +#define __R128_IOCTL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_dri.h" +#include "r128_reg.h" +#include "r128_lock.h" + +#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 ); + + +#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, + 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) + + +/* Make this available as both a regular and an inline function. + */ +extern CARD32 *r128AllocVertices( r128ContextPtr r128ctx, int count ); + +static __inline CARD32 *r128AllocVerticesInline( r128ContextPtr r128ctx, + int count ) +{ + int bytes = count * r128ctx->vertsize * sizeof(CARD32); + CARD32 *head; + + if ( !r128ctx->vert_buf ) { + LOCK_HARDWARE( r128ctx ); + + if ( r128ctx->first_elt != r128ctx->next_elt ) { + r128FlushEltsLocked( r128ctx ); + } + + r128ctx->vert_buf = r128GetBufferLocked( r128ctx ); + + UNLOCK_HARDWARE( r128ctx ); + } else if ( r128ctx->vert_buf->used + bytes > r128ctx->vert_buf->total ) { + LOCK_HARDWARE( r128ctx ); + + r128FlushVerticesLocked( r128ctx ); + r128ctx->vert_buf = r128GetBufferLocked( r128ctx ); + + UNLOCK_HARDWARE( r128ctx ); + } + + head = (CARD32 *)((char *)r128ctx->vert_buf->address + + r128ctx->vert_buf->used); + + r128ctx->num_verts += count; + r128ctx->vert_buf->used += bytes; + return head; +} + + +extern void r128FireBlitLocked( r128ContextPtr r128ctx, drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, GLint width, GLint height ); + + +extern void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, + GLuint n, GLint x, GLint y, + const GLdepth depth[], + const GLubyte mask[] ); +extern void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth depth[], + const GLubyte mask[] ); +extern void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, + GLuint n, GLint x, GLint y ); +extern void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, + const GLint x[], const GLint y[] ); + + +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 r128DDInitIoctlFuncs( GLcontext *ctx ); + + + +/* ================================================================ + * Deprecated functions: + */ + +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++; \ +} 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++; \ +} 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 R128CCE_SUBMIT_PACKET() \ +do { \ + r128SubmitPacketLocked( r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount ); \ + r128ctx->CCEcount = 0; \ +} while (0) + +extern void r128SubmitPacketLocked( r128ContextPtr r128ctx, + CARD32 *buf, GLuint count ); + +#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 new file mode 100644 index 000000000..6c9331c74 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c @@ -0,0 +1,93 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.c,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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_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 r128GetLock( r128ContextPtr r128ctx, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; + __DRIscreenPrivate *sPriv = r128ctx->driScreen; + R128SAREAPriv *sarea = r128ctx->sarea; + int stamp = dPriv->lastStamp; + int i; + + drmGetLock( r128ctx->driFd, r128ctx->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( r128ctx->display, sPriv, dPriv ); + + if ( stamp != dPriv->lastStamp ) { + r128ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; + r128ctx->SetupDone = 0; + } + + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS; + + r128ctx->numClipRects = dPriv->numClipRects; + r128ctx->pClipRects = dPriv->pClipRects; + + if ( sarea->ctxOwner != r128ctx->hHWContext ) { + sarea->ctxOwner = r128ctx->hHWContext; + r128ctx->dirty = R128_UPLOAD_ALL; + } + + for ( i = 0 ; i < r128ctx->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != r128ctx->lastTexAge[i] ) { + r128AgeTextures( r128ctx, 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 82d27a91b..57ec768bb 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.h,v 1.1 2000/06/17 00:03:06 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.h,v 1.2 2000/12/04 19:21:46 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -37,6 +38,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING +extern void r128GetLock( r128ContextPtr r128ctx, GLuint flags ); + + /* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */ #if DEBUG_LOCKING extern char *prevLockFile; @@ -78,57 +82,28 @@ extern int prevLockLine; * do not do any drawing !!! */ -/* Lock the hardware using the current context */ -#define LOCK_HARDWARE(CC) \ - do { \ - char __ret = 0; \ - __DRIcontextPrivate *cPriv = CC->driContext; \ - __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \ - \ - DEBUG_CHECK_LOCK(); \ - DRM_CAS(&sPriv->pSAREA->lock, cPriv->hHWContext, \ - DRM_LOCK_HELD|cPriv->hHWContext, __ret); \ - if (__ret) { \ - /* We lost the context, so we need to request the lock from \ - the kernel and update our state. */ \ - drmGetLock(sPriv->fd, cPriv->hHWContext, 0); \ - XMesaUpdateState(cPriv); \ - } \ - DEBUG_LOCK(); \ - } while (0) - -/* Unlock the hardware using the current context */ -#define UNLOCK_HARDWARE(CC) \ - do { \ - __DRIcontextPrivate *cPriv = CC->driContext; \ - __DRIscreenPrivate *sPriv = CC->r128Screen->driScreen; \ - \ - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, cPriv->hHWContext); \ - DEBUG_RESET(); \ - } while (0) - -/* - * This pair of macros makes a loop over the drawing operations, so it - * is not self contained and does not have the nice single statement - * semantics of most macros. +/* Lock the hardware and validate our state. */ -#define BEGIN_CLIP_LOOP(CC) \ - do { \ - __DRIdrawablePrivate *_dPriv = CC->driDrawable; \ - XF86DRIClipRectPtr _pc = _dPriv->pClipRects; \ - int _nc, _sc; \ - \ - for (_nc = _dPriv->numClipRects; _nc > 0; _nc -= 3, _pc += 3) { \ - _sc = (_nc <= 3) ? _nc : 3; \ - r128SetClipRects(CC, _pc, _sc) - -/* FIXME: This should be a function call to turn off aux clipping */ -#define END_CLIP_LOOP(CC) \ - R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); \ - R128CCE(0x00000000); \ - R128CCE_SUBMIT_PACKET(); \ - } \ - } while (0) +#define LOCK_HARDWARE( r128ctx ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( r128ctx->driHwLock, r128ctx->hHWContext, \ + (DRM_LOCK_HELD | r128ctx->hHWContext), __ret ); \ + if ( __ret ) \ + r128GetLock( r128ctx, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware. + */ +#define UNLOCK_HARDWARE( r128ctx ) \ + do { \ + DRM_UNLOCK( r128ctx->driFd, \ + r128ctx->driHwLock, \ + r128ctx->hHWContext ); \ + DEBUG_RESET(); \ + } while (0) #endif #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 325c1978a..4b17e5636 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c,v 1.2 2000/08/25 13:42:29 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c,v 1.3 2000/12/04 19:21:46 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,11 +28,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" +#include "r128_context.h" #include "r128_vb.h" #include "r128_pipeline.h" @@ -95,6 +96,7 @@ GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ) return GL_FALSE; } + /* Still do the normal fixup and copy-to-current, so this isn't so * bad. */ @@ -120,6 +122,7 @@ static void r128DDCheckRasterSetup( GLcontext *ctx, d->type = PIPE_IMMEDIATE; } + /* Register the pipeline with our stages included */ GLuint r128DDRegisterPipelineStages( struct gl_pipeline_stage *out, const struct gl_pipeline_stage *in, 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 3afb0947c..84c667240 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h,v 1.2 2000/08/25 13:42:29 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h,v 1.3 2000/12/04 19:21:46 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -43,4 +44,7 @@ extern GLuint r128DDRegisterPipelineStages( struct gl_pipeline_stage *out, extern void r128DDFastPathInit( void ); extern void r128DDFastPath( struct vertex_buffer *VB ); +extern void r128DDEltPathInit( void ); +extern void r128DDEltPath( struct vertex_buffer *VB ); + #endif /* _R128_PIPELINE_H_ */ 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 315891274..139e7fbc3 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.2 2000/08/25 13:42:29 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.3 2000/12/04 19:21:46 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,28 +28,41 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ #include "r128_dri.h" -#include "r128_reg.h" -#include "r128_init.h" #include "r128_context.h" -#include "r128_xmesa.h" -#include "r128_cce.h" +#include "r128_ioctl.h" #include "r128_tris.h" #include "r128_vb.h" #include "r128_pipeline.h" #include <sys/mman.h> +#if 1 +/* Including xf86PciInfo.h introduces a bunch of errors... + */ +#define PCI_CHIP_RAGE128LE 0x4C45 +#define PCI_CHIP_RAGE128LF 0x4C46 +#define PCI_CHIP_RAGE128PF 0x5046 +#define PCI_CHIP_RAGE128PR 0x5052 +#define PCI_CHIP_RAGE128RE 0x5245 +#define PCI_CHIP_RAGE128RF 0x5246 +#define PCI_CHIP_RAGE128RK 0x524B +#define PCI_CHIP_RAGE128RL 0x524C +#endif + + /* 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)); @@ -93,29 +106,12 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) return NULL; } - r128Screen->vbRgn.handle = r128DRIPriv->vbHandle; - r128Screen->vbRgn.size = r128DRIPriv->vbMapSize; - r128Screen->vbOffset = r128DRIPriv->vbOffset; - if (drmMap(sPriv->fd, - r128Screen->vbRgn.handle, - r128Screen->vbRgn.size, - (drmAddressPtr)&r128Screen->vb)) { - 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->vbOffset = r128DRIPriv->vbOffset; - - r128Screen->indRgn.handle = r128DRIPriv->indHandle; - r128Screen->indRgn.size = r128DRIPriv->indMapSize; + r128Screen->bufRgn.handle = r128DRIPriv->bufHandle; + r128Screen->bufRgn.size = r128DRIPriv->bufMapSize; if (drmMap(sPriv->fd, - r128Screen->indRgn.handle, - r128Screen->indRgn.size, - (drmAddressPtr)&r128Screen->ind)) { - drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + r128Screen->bufRgn.handle, + r128Screen->bufRgn.size, + (drmAddressPtr)&r128Screen->buf)) { drmUnmap((drmAddress)r128Screen->ringReadPtr, r128Screen->ringReadRgn.size); drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); @@ -123,6 +119,7 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) Xfree(r128Screen); return NULL; } + r128Screen->bufOffset = r128DRIPriv->bufOffset; r128Screen->agpTexRgn.handle = r128DRIPriv->agpTexHandle; r128Screen->agpTexRgn.size = r128DRIPriv->agpTexMapSize; @@ -130,8 +127,7 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) r128Screen->agpTexRgn.handle, r128Screen->agpTexRgn.size, (drmAddressPtr)&r128Screen->agpTex)) { - drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size); - drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); drmUnmap((drmAddress)r128Screen->ringReadPtr, r128Screen->ringReadRgn.size); drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); @@ -141,11 +137,10 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) } r128Screen->agpTexOffset = r128DRIPriv->agpTexOffset; - if (!(r128Screen->vbBufs = drmMapBufs(sPriv->fd))) { + if (!(r128Screen->buffers = drmMapBufs(sPriv->fd))) { drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size); - drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size); - drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); drmUnmap((drmAddress)r128Screen->ringReadPtr, r128Screen->ringReadRgn.size); drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); @@ -159,37 +154,34 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) * the ring walker method, ie. the vertex buffer data is actually part * of the command stream. */ - r128Screen->vbMapSize = r128DRIPriv->vbMapSize; - r128Screen->vbBufSize = r128DRIPriv->vbBufSize; + r128Screen->bufMapSize = r128DRIPriv->bufMapSize; r128Screen->deviceID = r128DRIPriv->deviceID; - r128Screen->width = r128DRIPriv->width; - r128Screen->height = r128DRIPriv->height; 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->fbX = r128DRIPriv->fbX; - r128Screen->fbY = r128DRIPriv->fbY; - r128Screen->backX = r128DRIPriv->backX; - r128Screen->backY = r128DRIPriv->backY; - r128Screen->depthX = r128DRIPriv->depthX; - r128Screen->depthY = r128DRIPriv->depthY; + 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->textureY * - r128Screen->fbStride + - r128DRIPriv->textureX * - (r128Screen->bpp/8)); - r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize; - r128Screen->log2TexGran[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran; + 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; @@ -205,15 +197,7 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS; } -#if 1 - /* FIXME: For testing only */ - if (getenv("LIBGL_SHOW_BUFFERS")) { - r128Screen->backX = 0; - r128Screen->backY = r128DRIPriv->height/2; - r128Screen->depthX = r128DRIPriv->width/2; - r128Screen->depthY = r128DRIPriv->height/2; - } -#endif + r128Screen->AGPMode = r128DRIPriv->AGPMode; r128Screen->CCEMode = r128DRIPriv->CCEMode; r128Screen->CCEFifoSize = r128DRIPriv->CCEFifoSize; @@ -230,14 +214,29 @@ r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN; - r128Screen->SAREA = (R128SAREAPrivPtr)((char *)sPriv->pSAREA + - sizeof(XF86DRISAREARec)); - r128Screen->driScreen = sPriv; - r128InitVertexBuffers(r128Screen); + 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(); @@ -250,11 +249,10 @@ void r128DestroyScreen(__DRIscreenPrivate *sPriv) r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; if (!r128Screen->IsPCI) { - drmUnmapBufs(r128Screen->vbBufs); + drmUnmapBufs(r128Screen->buffers); drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size); - drmUnmap((drmAddress)r128Screen->ind, r128Screen->indRgn.size); - drmUnmap((drmAddress)r128Screen->vb, r128Screen->vbRgn.size); + drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); drmUnmap((drmAddress)r128Screen->ringReadPtr, r128Screen->ringReadRgn.size); drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); 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 b8a904043..4fd6b7ac7 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.2 2000/08/25 13:42:30 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -56,17 +57,12 @@ typedef struct { /* CCE ring read pointer data */ r128RegionRec ringReadRgn; - /* CCE vertex buffer data */ - r128RegionRec vbRgn; - unsigned char *vb; - int vbOffset; - int vbMapSize; - int vbBufSize; - drmBufMapPtr vbBufs; - - /* CCE indirect buffer data */ - r128RegionRec indRgn; - unsigned char *ind; + /* CCE vertex/indirect buffer data */ + r128RegionRec bufRgn; + unsigned char *buf; + int bufOffset; + int bufMapSize; + drmBufMapPtr buffers; /* CCE AGP Texture data */ r128RegionRec agpTexRgn; @@ -79,7 +75,17 @@ typedef struct { 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 */ @@ -93,19 +99,10 @@ typedef struct { /* DRI screen private data */ int deviceID; /* PCI device ID */ - int width; /* Width in pixels of display */ - int height; /* Height in scanlines of display */ 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 */ - int fbX; /* Start of frame buffer */ - int fbY; - int backX; /* Start of shared back buffer */ - int backY; - int depthX; /* Start of shared depth buffer */ - int depthY; - /* Shared texture data */ int NRTexHeaps; int texOffset[R128_NR_TEX_HEAPS]; @@ -118,8 +115,6 @@ typedef struct { int CCEFifoAddr; /* MMIO offset to write next CCE value (only used when CCE is in PIO mode). */ - R128SAREAPrivPtr SAREA; /* Pointer to SAREA private data */ - __DRIscreenPrivate *driScreen; } r128ScreenRec, *r128ScreenPtr; 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 8ac51c32c..925b874e4 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.2 2000/08/25 13:42:30 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,111 +28,109 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Keith Whitwell <keith@precisioninsight.com> - * Gareth Hughes <gareth@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_lock.h" +#include "r128_ioctl.h" #include "r128_state.h" -#include "r128_reg.h" -#include "r128_cce.h" #include "r128_span.h" -#define DBG 0 - -#define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ - GLuint pitch = r128scrn->fbStride; \ - GLuint height = dPriv->h; \ - char *buf = (char *)(r128scrn->fb + \ - (r128ctx->drawX + dPriv->x) * (r128scrn->bpp/8) + \ - (r128ctx->drawY + dPriv->y) * pitch); \ - char *read_buf = (char *)(r128scrn->fb + \ - (r128ctx->readX + dPriv->x) * (r128scrn->bpp/8)+\ - (r128ctx->readY + dPriv->y) * pitch); \ - GLushort p; \ - (void) read_buf; (void) buf; (void) p - -#define LOCAL_DEPTH_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ - GLuint pitch = r128scrn->fbStride; \ - GLuint height = dPriv->h; \ - char *buf = (char *)(r128scrn->fb + \ - (r128scrn->depthX + dPriv->x) * (r128scrn->bpp/8) + \ - (r128scrn->depthY + dPriv->y) * pitch); \ - (void) buf - -#define INIT_MONO_PIXEL(p) \ - p = R128_CONTEXT(ctx)->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) + 1; \ - } - -#define Y_FLIP(_y) (height - _y - 1) - - -#define HW_LOCK() \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - FLUSH_BATCH(r128ctx); \ - LOCK_HARDWARE(r128ctx); \ - r128WaitForIdleLocked(r128ctx); - -#define HW_CLIPLOOP() \ - do { \ - __DRIdrawablePrivate *dPriv = r128ctx->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(r128ctx) +#include "pb.h" +#define DBG 0 - -/* 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) \ +#define HAVE_HW_DEPTH_SPANS 1 +#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; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(r128scrn->fb + \ + r128ctx->drawOffset + \ + (dPriv->x * r128scrn->bpp/8) + \ + (dPriv->y * pitch)); \ + char *read_buf = (char *)(r128scrn->fb + \ + r128ctx->readOffset + \ + (dPriv->x * r128scrn->bpp/8) + \ + (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; \ + GLuint height = dPriv->h; \ + (void) height + +#define INIT_MONO_PIXEL( p ) \ + p = r128ctx->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) + 1; \ + } + +#define Y_FLIP( _y ) (height - _y - 1) + + +#define HW_LOCK() \ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ + FLUSH_BATCH( r128ctx ); \ + LOCK_HARDWARE( r128ctx ); \ + r128WaitForIdleLocked( r128ctx ); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = r128ctx->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( r128ctx ) \ + + + +/* 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; \ +#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) #define TAG(x) r128##x##_RGB565 @@ -141,22 +139,22 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* 15 bit, ARGB1555 color spanline and pixel functions */ -#define WRITE_RGBA(_x, _y, r, g, b, a) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ - ((g & 0xf8) << 2) | \ - ((b & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ + ((g & 0xf8) << 2) | \ + ((b & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) -#define WRITE_PIXEL(_x, _y, p) \ +#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 >> 7) & 0xf8; \ - rgba[1] = (p >> 2) & 0xf8; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = (p & 0x8000) ? 0xff : 0; \ +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 7) & 0xf8; \ + rgba[1] = (p >> 2) & 0xf8; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = (p & 0x8000) ? 0xff : 0; \ } while (0) #define TAG(x) r128##x##_ARGB1555 @@ -164,166 +162,339 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. -/* 16 bit depthbuffer functions */ -#define WRITE_DEPTH(_x, _y, d) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = d; - -#define READ_DEPTH(d, _x, _y) \ - d = *(GLushort *)(buf + _x*2 + _y*pitch) - -#define TAG(x) r128##x##_16 -#include "depthtmp.h" - - - /* 24 bit, RGB888 color spanline and pixel functions */ -#define WRITE_RGBA(_x, _y, r, g, b, a) \ - *(GLuint *)(buf + _x*3 + _y*pitch) = ((r << 16) | \ - (g << 8) | \ - (b << 0)) - -#define WRITE_PIXEL(_x, _y, p) \ - *(GLuint *)(buf + _x*3 + _y*pitch) = p - -#define READ_RGBA(rgba, _x, _y) \ - do { \ - GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \ - rgba[0] = (p >> 16) & 0xff; \ - rgba[1] = (p >> 8) & 0xff; \ - rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = 0xff; \ - } while (0) +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = 0xff; \ +} while (0) #define TAG(x) r128##x##_RGB888 #include "spantmp.h" -/* 24 bit depthbuffer functions */ -#define WRITE_DEPTH(_x, _y, d) \ - *(GLuint *)(buf + _x*3 + _y*pitch) = d +/* 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 READ_DEPTH(d, _x, _y) \ - d = *(GLuint *)(buf + _x*3 + _y*pitch) +#define TAG(x) r128##x##_ARGB8888 +#include "spantmp.h" -#define TAG(x) r128##x##_24 -#include "depthtmp.h" +/* 16-bit depth buffer functions */ + +#define WRITE_DEPTH_SPAN() \ + r128WriteDepthSpanLocked( r128ctx, n, x, y, depth, mask ); + +#define WRITE_DEPTH_PIXELS() \ +do { \ + GLint fy[PB_SIZE]; \ + for ( i = 0 ; i < n ; i++ ) { \ + fy[i] = Y_FLIP( y[i] ); \ + } \ + r128WriteDepthPixelsLocked( r128ctx, n, x, fy, depth, mask ); \ +} while (0) + +#define READ_DEPTH_SPAN() \ +do { \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + GLushort *buf = (GLushort *)((GLubyte *)r128scrn->fb + \ + r128scrn->spanOffset); \ + GLint i; \ + \ + r128ReadDepthSpanLocked( r128ctx, n, x, y ); \ + r128WaitForIdleLocked( r128ctx ); \ + \ + for ( i = 0 ; i < n ; i++ ) { \ + depth[i] = buf[i]; \ + } \ +} while (0) + +#define READ_DEPTH_PIXELS() \ +do { \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + GLushort *buf = (GLushort *)((GLubyte *)r128scrn->fb + \ + r128scrn->spanOffset); \ + GLint i, remaining = n; \ + \ + while ( remaining > 0 ) { \ + GLint fy[PB_SIZE]; \ + GLint count; \ + \ + if ( remaining <= 128 ) { \ + count = remaining; \ + } else { \ + count = 128; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + fy[i] = Y_FLIP( y[i] ); \ + } \ + \ + r128ReadDepthPixelsLocked( r128ctx, count, x, fy ); \ + r128WaitForIdleLocked( r128ctx ); \ + \ + for ( i = 0 ; i < count ; i++ ) { \ + depth[i] = buf[i]; \ + } \ + depth += count; \ + x += count; \ + y += count; \ + remaining -= count; \ + } \ +} while (0) -/* 32 bit, ARGB8888 color spanline and pixel functions */ -#define WRITE_RGBA(_x, _y, r, g, b, a) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \ - (g << 8) | \ - (b << 0) | \ - (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) r128##x##_16 +#include "depthtmp.h" -#define TAG(x) r128##x##_ARGB8888 -#include "spantmp.h" +/* 24-bit depth, 8-bit stencil buffer functions */ + +#define WRITE_DEPTH_SPAN() \ + r128WriteDepthSpanLocked( r128ctx, n, x, y, depth, mask ); + +#define WRITE_DEPTH_PIXELS() \ +do { \ + GLint fy[PB_SIZE]; \ + for ( i = 0 ; i < n ; i++ ) { \ + fy[i] = Y_FLIP( y[i] ); \ + } \ + r128WriteDepthPixelsLocked( r128ctx, n, x, fy, depth, mask ); \ +} while (0) + +#define READ_DEPTH_SPAN() \ +do { \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + r128scrn->spanOffset); \ + GLint i; \ + \ + r128ReadDepthSpanLocked( r128ctx, n, x, y ); \ + r128WaitForIdleLocked( r128ctx ); \ + \ + for ( i = 0 ; i < n ; i++ ) { \ + depth[i] = buf[i] & 0x00ffffff; \ + } \ +} while (0) + + +#define READ_DEPTH_PIXELS() \ +do { \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + r128scrn->spanOffset); \ + GLint i, remaining = n; \ + \ + while ( remaining > 0 ) { \ + GLint fy[PB_SIZE]; \ + GLint count; \ + \ + if ( remaining <= 128 ) { \ + count = remaining; \ + } else { \ + count = 128; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + fy[i] = Y_FLIP( y[i] ); \ + } \ + \ + r128ReadDepthPixelsLocked( r128ctx, count, x, fy ); \ + r128WaitForIdleLocked( r128ctx ); \ + \ + for ( i = 0 ; i < count ; i++ ) { \ + depth[i] = buf[i] & 0x00ffffff; \ + } \ + depth += count; \ + x += count; \ + y += count; \ + remaining -= count; \ + } \ +} while (0) + +#define TAG(x) r128##x##_24_8 +#include "depthtmp.h" + -/* 32 bit depthbuffer functions */ -#define WRITE_DEPTH(_x, _y, d) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = d -#define READ_DEPTH(d, _x, _y) \ - d = *(GLuint *)(buf + _x*4 + _y*pitch) +/* 32-bit depth buffer functions */ + +#define WRITE_DEPTH_SPAN() \ + r128WriteDepthSpanLocked( r128ctx, n, x, y, depth, mask ); + +#define WRITE_DEPTH_PIXELS() \ +do { \ + GLint fy[PB_SIZE]; \ + for ( i = 0 ; i < n ; i++ ) { \ + fy[i] = Y_FLIP( y[i] ); \ + } \ + r128WriteDepthPixelsLocked( r128ctx, n, x, fy, depth, mask ); \ +} while (0) + +#define READ_DEPTH_SPAN() \ +do { \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + r128scrn->spanOffset); \ + GLint i; \ + \ + r128ReadDepthSpanLocked( r128ctx, n, x, y ); \ + r128WaitForIdleLocked( r128ctx ); \ + \ + for ( i = 0 ; i < n ; i++ ) { \ + depth[i] = buf[i]; \ + } \ +} while (0) + +#define READ_DEPTH_PIXELS() \ +do { \ + r128ScreenPtr r128scrn = r128ctx->r128Screen; \ + GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + r128scrn->spanOffset); \ + GLint i, remaining = n; \ + \ + while ( remaining > 0 ) { \ + GLint fy[PB_SIZE]; \ + GLint count; \ + \ + if ( remaining <= 128 ) { \ + count = remaining; \ + } else { \ + count = 128; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + fy[i] = Y_FLIP( y[i] ); \ + } \ + \ + r128ReadDepthPixelsLocked( r128ctx, count, x, fy ); \ + r128WaitForIdleLocked( r128ctx ); \ + \ + for ( i = 0 ; i < count ; i++ ) { \ + depth[i] = buf[i]; \ + } \ + depth += count; \ + x += count; \ + y += count; \ + remaining -= count; \ + } \ +} while (0) #define TAG(x) r128##x##_32 #include "depthtmp.h" -void r128DDInitSpanFuncs(GLcontext *ctx) + +void r128DDInitSpanFuncs( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - - switch (r128ctx->r128Screen->pixel_code) { - case 8: /* Color Index mode not supported */ - break; - - case 15: - ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB1555; - ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB1555; - ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB1555; - ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB1555; - ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB1555; - ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB1555; - ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB1555; - - ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; - ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; - ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16; - ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16; - break; - - case 16: - ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565; - ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565; - ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565; - ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB565; - ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB565; - ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB565; - ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565; - - ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; - ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; - ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16; - ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16; - break; - - case 24: - ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB888; - ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB888; - ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB888; - ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB888; - ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB888; - ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB888; - ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB888; - - ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_24; - ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_24; - ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_24; - ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_24; - break; - - case 32: - ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888; - ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888; - ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888; - ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB8888; - ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB8888; - ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB8888; - ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB8888; - - ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_32; - ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_32; - ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_32; - ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_32; - 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; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + switch ( r128ctx->BufferSize ) { + case 8: /* Color Index mode not supported */ + break; + + case 15: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB1555; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB1555; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB1555; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB1555; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB1555; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB1555; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB1555; + break; + + case 16: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB565; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB565; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB565; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565; + break; + + case 24: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB888; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB888; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB888; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_RGB888; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB888; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_RGB888; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB888; + break; + + case 32: + ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888; + ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888; + ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888; + ctx->Driver.WriteRGBAPixels = r128WriteRGBAPixels_ARGB8888; + ctx->Driver.WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB8888; + ctx->Driver.ReadRGBASpan = r128ReadRGBASpan_ARGB8888; + ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_ARGB8888; + break; + + default: + break; + } + + switch ( r128ctx->DepthSize ) { + case 16: + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_16; + break; + + case 24: + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_24_8; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_24_8; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_24_8; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_24_8; + break; + + case 32: + ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_32; + ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_32; + ctx->Driver.ReadDepthPixels = r128ReadDepthPixels_32; + ctx->Driver.WriteDepthPixels = r128WriteDepthPixels_32; + 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/r128/r128_span.h b/xc/lib/GL/mesa/src/drv/r128/r128_span.h index e1cab0a48..486445d31 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.h,v 1.1 2000/06/17 00:03:07 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.h,v 1.2 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Gareth Hughes <gareth@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ 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 06584784a..0aa8fef33 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.4 2000/08/25 13:42:30 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.5 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,715 +28,537 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> * */ -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_lock.h" #include "r128_state.h" -#include "r128_reg.h" -#include "r128_cce.h" +#include "r128_ioctl.h" #include "r128_tris.h" #include "r128_vb.h" #include "r128_tex.h" #include "mmath.h" #include "pb.h" +#include "enums.h" -#define INTERESTED (~(NEW_MODELVIEW | \ - NEW_PROJECTION | \ - NEW_TEXTURE_MATRIX | \ - NEW_USER_CLIP | \ - NEW_CLIENT_STATE | \ - NEW_TEXTURE_ENABLE)) -static void r128DDUpdateState(GLcontext *ctx) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { - fprintf(stderr, "r128DDUpdateState(%p)\n", ctx); - } - - /* Need to do this here to detect texture fallbacks before - * setting triangle functions. - */ - if (r128ctx->dirty & R128_UPDATE_TEXSTATE) - r128UpdateHWState(r128ctx); - - if (ctx->NewState & INTERESTED) { - r128DDChooseRenderState(ctx); - r128DDChooseRasterSetupFunc(ctx); - } - - if (!r128ctx->Fallback) { - ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; - ctx->IndirectTriangles |= r128ctx->IndirectTriangles; - - ctx->Driver.PointsFunc = r128ctx->PointsFunc; - ctx->Driver.LineFunc = r128ctx->LineFunc; - ctx->Driver.TriangleFunc = r128ctx->TriangleFunc; - ctx->Driver.QuadFunc = r128ctx->QuadFunc; - ctx->Driver.RectFunc = NULL; - } -} +/* ============================================================= + * Alpha blending + */ -static void r128DDUpdateHWState(GLcontext *ctx) +static void r128UpdateAlphaMode( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - - /* FIXME: state is being updated too often */ - if (r128ctx->dirty) - r128UpdateHWState(r128ctx); -} - + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + CARD32 a = r128ctx->setup.misc_3d_state_cntl_reg; + CARD32 t = r128ctx->setup.tex_cntl_c; + + if ( ctx->Color.AlphaEnabled ) { + GLubyte ref = ctx->Color.AlphaRef; + + a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK); + + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: + a |= R128_ALPHA_TEST_NEVER; + ref = 0; + break; + case GL_LESS: + a |= R128_ALPHA_TEST_LESS; + break; + case GL_LEQUAL: + a |= R128_ALPHA_TEST_LESSEQUAL; + break; + case GL_EQUAL: + a |= R128_ALPHA_TEST_EQUAL; + break; + case GL_GEQUAL: + a |= R128_ALPHA_TEST_GREATEREQUAL; + break; + case GL_GREATER: + a |= R128_ALPHA_TEST_GREATER; + break; + case GL_NOTEQUAL: + a |= R128_ALPHA_TEST_NEQUAL; + break; + case GL_ALWAYS: + a |= R128_ALPHA_TEST_ALWAYS; + break; + } -/* 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 r128 uses triangles to render lines and points, it is - * necessary to turn off hardware culling when rendering these - * primitives. - */ -static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; + a |= ref & R128_REF_ALPHA_MASK; + t |= R128_ALPHA_TEST_ENABLE; + } else { + t &= ~R128_ALPHA_TEST_ENABLE; + } - f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; + if ( ctx->Color.BlendEnabled ) { + a &= ~(R128_ALPHA_BLEND_SRC_MASK | R128_ALPHA_BLEND_DST_MASK); + + switch ( ctx->Color.BlendSrcRGB ) { + case GL_ZERO: + a |= R128_ALPHA_BLEND_SRC_ZERO; + break; + case GL_ONE: + a |= R128_ALPHA_BLEND_SRC_ONE; + break; + case GL_DST_COLOR: + a |= R128_ALPHA_BLEND_SRC_DESTCOLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + a |= R128_ALPHA_BLEND_SRC_INVDESTCOLOR; + break; + case GL_SRC_ALPHA: + a |= R128_ALPHA_BLEND_SRC_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + a |= R128_ALPHA_BLEND_SRC_INVSRCALPHA; + break; + case GL_DST_ALPHA: + a |= R128_ALPHA_BLEND_SRC_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + a |= R128_ALPHA_BLEND_SRC_INVDESTALPHA; + break; + case GL_SRC_ALPHA_SATURATE: + a |= R128_ALPHA_BLEND_SRC_SRCALPHASAT; + break; + } - /* Should really use an intermediate value to hold this rather - * than recalculating all the time. - */ - if (prim == GL_POLYGON && ctx->Polygon.CullFlag) { - switch (ctx->Polygon.CullFaceMode) { - case GL_FRONT: f &= ~R128_FRONTFACE_SOLID; break; - case GL_BACK: f &= ~R128_BACKFACE_SOLID; break; - case GL_FRONT_AND_BACK: f &= ~(R128_BACKFACE_SOLID | - R128_FRONTFACE_SOLID); break; - default: break; + switch ( ctx->Color.BlendDstRGB ) { + case GL_ZERO: + a |= R128_ALPHA_BLEND_DST_ZERO; + break; + case GL_ONE: + a |= R128_ALPHA_BLEND_DST_ONE; + break; + case GL_SRC_COLOR: + a |= R128_ALPHA_BLEND_DST_SRCCOLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + a |= R128_ALPHA_BLEND_DST_INVSRCCOLOR; + break; + case GL_SRC_ALPHA: + a |= R128_ALPHA_BLEND_DST_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + a |= R128_ALPHA_BLEND_DST_INVSRCALPHA; + break; + case GL_DST_ALPHA: + a |= R128_ALPHA_BLEND_DST_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + a |= R128_ALPHA_BLEND_DST_INVDESTALPHA; + break; } - } - if (r128ctx->regs.pm4_vc_fpu_setup != f) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.pm4_vc_fpu_setup = f; + t |= R128_ALPHA_ENABLE; + } else { + t &= ~R128_ALPHA_ENABLE; + } - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_SETUPSTATE; - } + 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 ( r128ctx->setup.tex_cntl_c != t ) { + r128ctx->setup.tex_cntl_c = t; + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + } } -static void r128DDClearColor(GLcontext *ctx, - GLubyte r, GLubyte g, GLubyte b, GLubyte a) +static void r128DDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - r128ctx->ClearColor = r128PackColor(r128ctx->r128Screen->depth, - r, g, b, a); + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_ALPHA; } -static void r128DDColor(GLcontext *ctx, - GLubyte r, GLubyte g, GLubyte b, GLubyte a) +static void r128DDBlendEquation( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - r128ctx->Color = r128PackColor(r128ctx->r128Screen->depth, r, g, b, a); + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_ALPHA; } -static GLboolean r128DDSetDrawBuffer(GLcontext *ctx, GLenum mode) +static void r128DDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - int x = r128ctx->driDrawable->x; - int y = r128ctx->driDrawable->y; - int found; - - r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; - - switch (mode) { - case GL_FRONT_LEFT: - r128ctx->drawX = r128ctx->r128Screen->fbX; - r128ctx->drawY = r128ctx->r128Screen->fbY; - r128ctx->readX = r128ctx->r128Screen->fbX; - r128ctx->readY = r128ctx->r128Screen->fbY; - found = GL_TRUE; - break; - case GL_BACK_LEFT: - r128ctx->drawX = r128ctx->r128Screen->backX; - r128ctx->drawY = r128ctx->r128Screen->backY; - r128ctx->readX = r128ctx->r128Screen->fbX; - r128ctx->readY = r128ctx->r128Screen->fbY; - found = GL_TRUE; - break; - default: - r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER; - found = GL_FALSE; - break; - } - - x += r128ctx->drawX; - y += r128ctx->drawY; - - FLUSH_BATCH(r128ctx); - - r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | - (x << R128_WINDOW_X_SHIFT)); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - /* Recalculate the Z buffer offset since we might be drawing to the - back buffer and window_xy_offset affects both color buffer and - depth drawing */ - r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX - - r128ctx->drawX) * - (r128ctx->r128Screen->bpp/8) + - (r128ctx->r128Screen->depthY - - r128ctx->drawY) * - r128ctx->r128Screen->fbStride); - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_WIN_Z_POS; - return found; + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_ALPHA; } -static void r128DDSetReadBuffer(GLcontext *ctx, - GLframebuffer *colorBuffer, - GLenum mode) +static void r128DDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - - r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER; - - switch (mode) { - case GL_FRONT_LEFT: - r128ctx->readX = r128ctx->r128Screen->fbX; - r128ctx->readY = r128ctx->r128Screen->fbY; - break; - case GL_BACK_LEFT: - r128ctx->readX = r128ctx->r128Screen->backX; - r128ctx->readY = r128ctx->r128Screen->backY; - break; - default: - r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER; - break; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_ALPHA; } -static GLboolean r128DDColorMask(GLcontext *ctx, - GLboolean r, GLboolean g, - GLboolean b, GLboolean a) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - GLuint mask = r128PackColor(r128ctx->r128Screen->pixel_code, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP]); +/* ============================================================= + * Depth testing + */ - if (r128ctx->regs.plane_3d_mask_c != mask) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.plane_3d_mask_c = mask; +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; + + if ( ctx->Depth.Test ) { + z &= ~R128_Z_TEST_MASK; + + switch ( ctx->Depth.Func ) { + case GL_NEVER: + z |= R128_Z_TEST_NEVER; + break; + case GL_ALWAYS: + z |= R128_Z_TEST_ALWAYS; + break; + case GL_LESS: + z |= R128_Z_TEST_LESS; + break; + case GL_LEQUAL: + z |= R128_Z_TEST_LESSEQUAL; + break; + case GL_EQUAL: + z |= R128_Z_TEST_EQUAL; + break; + case GL_GEQUAL: + z |= R128_Z_TEST_GREATEREQUAL; + break; + case GL_GREATER: + z |= R128_Z_TEST_GREATER; + break; + case GL_NOTEQUAL: + z |= R128_Z_TEST_NEQUAL; + break; + } - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_MISC; - } + t |= R128_Z_ENABLE; + } else { + t &= ~R128_Z_ENABLE; + } - return GL_TRUE; -} + if ( ctx->Depth.Mask ) { + t |= R128_Z_WRITE_ENABLE; + } else { + 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 ( r128ctx->setup.tex_cntl_c != t ) { + r128ctx->setup.tex_cntl_c = t; + r128ctx->dirty |= R128_UPLOAD_CONTEXT; + } +} -static void r128DDDither(GLcontext *ctx, GLboolean enable) +static void r128DDDepthFunc( GLcontext *ctx, GLenum func ) { + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_DEPTH; } -static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) +static void r128DDDepthMask( GLcontext *ctx, GLboolean flag ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 a = r128ctx->regs.misc_3d_state_cntl_reg; - - a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK); - a |= ctx->Color.AlphaRef & R128_REF_ALPHA_MASK; - - switch (func) { - case GL_NEVER: a |= R128_ALPHA_TEST_NEVER; break; - case GL_LESS: a |= R128_ALPHA_TEST_LESS; break; - case GL_LEQUAL: a |= R128_ALPHA_TEST_LESSEQUAL; break; - case GL_EQUAL: a |= R128_ALPHA_TEST_EQUAL; break; - case GL_GEQUAL: a |= R128_ALPHA_TEST_GREATEREQUAL; break; - case GL_GREATER: a |= R128_ALPHA_TEST_GREATER; break; - case GL_NOTEQUAL: a |= R128_ALPHA_TEST_NEQUAL; break; - case GL_ALWAYS: a |= R128_ALPHA_TEST_ALWAYS; - break; - default: - /* ERROR!!! */ - return; - } - - if (r128ctx->regs.misc_3d_state_cntl_reg != a) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.misc_3d_state_cntl_reg = a; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ALPHASTATE; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_DEPTH; } -static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) +static void r128DDClearDepth( GLcontext *ctx, GLclampd d ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 b = r128ctx->regs.misc_3d_state_cntl_reg; - - b &= ~(R128_ALPHA_BLEND_SRC_MASK | R128_ALPHA_BLEND_DST_MASK); - - switch (sfactor) { - case GL_ZERO: b |= R128_ALPHA_BLEND_SRC_ZERO; - break; - case GL_ONE: b |= R128_ALPHA_BLEND_SRC_ONE; - break; - case GL_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_DESTCOLOR; - break; - case GL_ONE_MINUS_DST_COLOR: b |= R128_ALPHA_BLEND_SRC_INVDESTCOLOR; - break; - case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_SRCALPHA; - break; - case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVSRCALPHA; - break; - case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_DESTALPHA; - break; - case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_SRC_INVDESTALPHA; - break; - case GL_SRC_ALPHA_SATURATE: b |= R128_ALPHA_BLEND_SRC_SRCALPHASAT; - break; -#if 0 - /* FIXME: These are not supported directly by the Rage 128. - They could be emulated using something like the TexEnv - modes. */ - case GL_CONSTANT_COLOR: b |= 0; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0; - break; - case GL_CONSTANT_ALPHA: b |= 0; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0; - break; -#endif - default: - /* ERROR!!! */ - return; - } - - switch (dfactor) { - case GL_ZERO: b |= R128_ALPHA_BLEND_DST_ZERO; - break; - case GL_ONE: b |= R128_ALPHA_BLEND_DST_ONE; - break; - case GL_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_SRCCOLOR; - break; - case GL_ONE_MINUS_SRC_COLOR: b |= R128_ALPHA_BLEND_DST_INVSRCCOLOR; - break; - case GL_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_SRCALPHA; - break; - case GL_ONE_MINUS_SRC_ALPHA: b |= R128_ALPHA_BLEND_DST_INVSRCALPHA; - break; - case GL_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_DESTALPHA; - break; - case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_INVDESTALPHA; - break; -#if 0 - /* FIXME: These are not supported directly by the Rage 128. - They could be emulated using something like the TexEnv - modes. */ - case GL_CONSTANT_COLOR: b |= 0; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0; - break; - case GL_CONSTANT_ALPHA: b |= 0; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: b |= 0; - break; -#endif - default: - /* ERROR!!! */ - return; - } - - if (r128ctx->regs.misc_3d_state_cntl_reg != b) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.misc_3d_state_cntl_reg = b; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ALPHASTATE; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + switch ( r128ctx->DepthSize ) { + case 16: + r128ctx->ClearDepth = d * 0x0000ffff; + break; + case 24: + r128ctx->ClearDepth = d * 0x00ffffff; + break; + case 32: + r128ctx->ClearDepth = d * 0xffffffff; + break; + } } -static void r128DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, - GLenum dfactorRGB, GLenum sfactorA, - GLenum dfactorA) + +/* ============================================================= + * Fog + */ + +static void r128UpdateFogAttrib( GLcontext *ctx ) { - if (sfactorRGB != sfactorA || dfactorRGB != dfactorA) { - /* ERROR!!! */ - return; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + CARD32 t = r128ctx->setup.tex_cntl_c; + GLubyte c[4]; + CARD32 col; + + if ( ctx->FogMode == FOG_FRAGMENT ) { + t |= R128_FOG_ENABLE; + } else { + t &= ~R128_FOG_ENABLE; + } + + FLOAT_RGBA_TO_UBYTE_RGBA( c, ctx->Fog.Color ); + col = r128PackColor( 32, c[0], c[1], c[2], c[3] ); - r128DDBlendFunc(ctx, sfactorRGB, dfactorRGB); + if ( r128ctx->setup.fog_color_c != col ) { + r128ctx->setup.fog_color_c = col; + r128ctx->dirty |= R128_UPLOAD_CONTEXT; + } + if ( r128ctx->setup.tex_cntl_c != t ) { + r128ctx->setup.tex_cntl_c = t; + r128ctx->dirty |= R128_UPLOAD_CONTEXT; + } } -static void r128DDClearDepth(GLcontext *ctx, GLclampd d) +static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - - switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) { - case R128_Z_PIX_WIDTH_16: r128ctx->ClearDepth = d * 0x0000ffff; break; - case R128_Z_PIX_WIDTH_24: r128ctx->ClearDepth = d * 0x00ffffff; break; - case R128_Z_PIX_WIDTH_32: r128ctx->ClearDepth = d * 0xffffffff; break; - default: return; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_FOG; } -static void r128DDCullFace(GLcontext *ctx, GLenum mode) + +/* ============================================================= + * Clipping + */ + +static void r128UpdateClipping( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - if (!ctx->Polygon.CullFlag) return; + if ( r128ctx->driDrawable ) { + __DRIdrawablePrivate *drawable = r128ctx->driDrawable; + int x1 = 0; + int y1 = 0; + int x2 = r128ctx->driDrawable->w - 1; + int y2 = r128ctx->driDrawable->h - 1; + + if ( ctx->Scissor.Enabled ) { + if ( ctx->Scissor.X > x1 ) { + x1 = ctx->Scissor.X; + } + if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y1 ) { + y1 = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height; + } + if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < x2 ) { + x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; + } + if ( drawable->h - ctx->Scissor.Y - 1 < y2 ) { + y2 = drawable->h - ctx->Scissor.Y - 1; + } + } - f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK); + 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" ); + } - switch (mode) { - case GL_FRONT: f |= R128_BACKFACE_SOLID; break; - case GL_BACK: f |= R128_FRONTFACE_SOLID; break; - case GL_FRONT_AND_BACK: break; - default: return; - } + r128ctx->setup.sc_top_left_c = ((x1 << 0) | + (y1 << 16)); + r128ctx->setup.sc_bottom_right_c = ((x2 << 0) | + (y2 << 16)); - if (r128ctx->regs.pm4_vc_fpu_setup != f) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.pm4_vc_fpu_setup = f; + r128ctx->dirty |= R128_UPLOAD_CONTEXT; + } +} + +static void r128DDScissor( GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h ) +{ + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_SETUPSTATE; - } + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_CLIP; } -static void r128DDFrontFace(GLcontext *ctx, GLenum mode) + +/* ============================================================= + * Culling + */ + +static void r128UpdateCull( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + CARD32 f = r128ctx->setup.pm4_vc_fpu_setup; - f &= ~R128_FRONT_DIR_MASK; + f &= ~R128_FRONT_DIR_MASK; - switch (mode) { - case GL_CW: f |= R128_FRONT_DIR_CW; break; - case GL_CCW: f |= R128_FRONT_DIR_CCW; break; - default: return; - } + switch ( ctx->Polygon.FrontFace ) { + case GL_CW: + f |= R128_FRONT_DIR_CW; + break; + case GL_CCW: + f |= R128_FRONT_DIR_CCW; + break; + } - if (r128ctx->regs.pm4_vc_fpu_setup != f) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.pm4_vc_fpu_setup = f; + f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_SETUPSTATE; - } + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + f &= ~R128_FRONTFACE_SOLID; + break; + case GL_BACK: + f &= ~R128_BACKFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + f &= ~(R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID); + break; + } + } + + if ( r128ctx->setup.pm4_vc_fpu_setup != f ) { + r128ctx->setup.pm4_vc_fpu_setup = f; + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP; + } } -static void r128DDDepthFunc(GLcontext *ctx, GLenum func) +static void r128DDCullFace( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 z = r128ctx->regs.z_sten_cntl_c; - - z &= ~R128_Z_TEST_MASK; - - switch (func) { - case GL_NEVER: z |= R128_Z_TEST_NEVER; break; - case GL_LESS: z |= R128_Z_TEST_LESS; break; - case GL_LEQUAL: z |= R128_Z_TEST_LESSEQUAL; break; - case GL_EQUAL: z |= R128_Z_TEST_EQUAL; break; - case GL_GEQUAL: z |= R128_Z_TEST_GREATEREQUAL; break; - case GL_GREATER: z |= R128_Z_TEST_GREATER; break; - case GL_NOTEQUAL: z |= R128_Z_TEST_NEQUAL; break; - case GL_ALWAYS: z |= R128_Z_TEST_ALWAYS; break; - default: return; - } - - if (r128ctx->regs.z_sten_cntl_c != z) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.z_sten_cntl_c = z; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ZSTENSTATE; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_CULL; } -static void r128DDDepthMask(GLcontext *ctx, GLboolean flag) +static void r128DDFrontFace( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 t = r128ctx->regs.tex_cntl_c; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - if (flag) t |= R128_Z_WRITE_ENABLE; - else t &= ~R128_Z_WRITE_ENABLE; + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_CULL; +} - if (r128ctx->regs.tex_cntl_c != t) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.tex_cntl_c = t; - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ENGINESTATE; - } -} +/* ============================================================= + * Masks + */ -static void r128DDLightModelfv(GLcontext *ctx, GLenum pname, - const GLfloat *param) +static void r128UpdateMasks( GLcontext *ctx ) { - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) - { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 t = r128ctx->regs.tex_cntl_c; - - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - t |= R128_SPEC_LIGHT_ENABLE; - else - t &= ~R128_SPEC_LIGHT_ENABLE; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - if (r128ctx->regs.tex_cntl_c != t) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.tex_cntl_c = t; + GLuint mask = r128PackColor( r128ctx->BufferSize, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ENGINESTATE; - } + if ( r128ctx->setup.plane_3d_mask_c != mask ) { + r128ctx->setup.plane_3d_mask_c = mask; + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } } -static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode ) +static GLboolean r128DDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) { - if (ctx->Color.ColorLogicOpEnabled) - { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - FLUSH_BATCH( r128ctx ); - - if (opcode == GL_COPY) - r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; - else - r128ctx->Fallback |= R128_FALLBACK_LOGICOP; - } + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_MASKS; + + return GL_TRUE; } -static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) +/* ============================================================= + * 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 r128UpdateRenderAttrib( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - CARD32 t = r128ctx->regs.tex_cntl_c; - CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { - fprintf(stderr, "r128DDEnable( %p, 0x%x = %s )\n", - ctx, cap, state ? "GL_TRUE" : "GL_FALSE"); - } - - switch (cap) { - case GL_ALPHA_TEST: - if (state) t |= R128_ALPHA_TEST_ENABLE; - else t &= ~R128_ALPHA_TEST_ENABLE; - break; - - case GL_AUTO_NORMAL: return; - - case GL_BLEND: - if (state) t |= R128_ALPHA_ENABLE; - else t &= ~R128_ALPHA_ENABLE; - break; - - case GL_CLIP_PLANE0: - case GL_CLIP_PLANE1: - case GL_CLIP_PLANE2: - case GL_CLIP_PLANE3: - case GL_CLIP_PLANE4: - case GL_CLIP_PLANE5: - case GL_COLOR_MATERIAL: return; - - case GL_CULL_FACE: - if (ctx->PB->primitive == GL_POLYGON) { - f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK); - if (state) { - switch (ctx->Polygon.CullFaceMode) { - case GL_FRONT: f |= R128_BACKFACE_SOLID; break; - case GL_BACK: f |= R128_FRONTFACE_SOLID; break; - case GL_FRONT_AND_BACK: break; - default: return; - } - } else { - f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; - } - } - break; - - case GL_DEPTH_TEST: - if (state) t |= R128_Z_ENABLE; - else t &= ~R128_Z_ENABLE; - break; - - case GL_DITHER: - if (state) t |= R128_DITHER_ENABLE; - else t &= ~R128_DITHER_ENABLE; - break; - - case GL_FOG: - if (state) t |= R128_FOG_ENABLE; - else t &= ~R128_FOG_ENABLE; - break; - - case GL_INDEX_LOGIC_OP: - case GL_COLOR_LOGIC_OP: - FLUSH_BATCH( r128ctx ); - if (state && ctx->Color.LogicOp != GL_COPY) - r128ctx->Fallback |= R128_FALLBACK_LOGICOP; - else - r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; - break; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + CARD32 t = r128ctx->setup.tex_cntl_c; + CARD32 bias = r128ctx->lod_bias & 0xff;; - case GL_LIGHT0: - case GL_LIGHT1: - case GL_LIGHT2: - case GL_LIGHT3: - case GL_LIGHT4: - case GL_LIGHT5: - case GL_LIGHT6: - case GL_LIGHT7: - case GL_LIGHTING: - case GL_LINE_SMOOTH: - case GL_LINE_STIPPLE: - case GL_MAP1_COLOR_4: - case GL_MAP1_INDEX: - case GL_MAP1_NORMAL: - case GL_MAP1_TEXTURE_COORD_1: - case GL_MAP1_TEXTURE_COORD_2: - case GL_MAP1_TEXTURE_COORD_3: - case GL_MAP1_TEXTURE_COORD_4: - case GL_MAP1_VERTEX_3: - case GL_MAP1_VERTEX_4: - case GL_MAP2_COLOR_4: - case GL_MAP2_INDEX: - case GL_MAP2_NORMAL: - case GL_MAP2_TEXTURE_COORD_1: - case GL_MAP2_TEXTURE_COORD_2: - case GL_MAP2_TEXTURE_COORD_3: - case GL_MAP2_TEXTURE_COORD_4: - case GL_MAP2_VERTEX_3: - case GL_MAP2_VERTEX_4: - case GL_NORMALIZE: - case GL_POINT_SMOOTH: - case GL_POLYGON_SMOOTH: - case GL_POLYGON_STIPPLE: - case GL_POLYGON_OFFSET_POINT: - case GL_POLYGON_OFFSET_LINE: - case GL_POLYGON_OFFSET_FILL: - case GL_RESCALE_NORMAL_EXT: return; - - case GL_SCISSOR_TEST: - /* FIXME: Hook up the software scissor */ -#if 0 - r128ctx->Scissor = state; -#endif - break; - - case GL_SHARED_TEXTURE_PALETTE_EXT: - case GL_STENCIL_TEST: return; - - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* This is handled in r128UpdateTex[01]State() */ - r128ctx->dirty |= R128_UPDATE_TEXSTATE; - break; - - case GL_TEXTURE_GEN_Q: - case GL_TEXTURE_GEN_R: - case GL_TEXTURE_GEN_S: - case GL_TEXTURE_GEN_T: return; - - /* Client state */ - case GL_VERTEX_ARRAY: - case GL_NORMAL_ARRAY: - case GL_COLOR_ARRAY: - case GL_INDEX_ARRAY: - case GL_TEXTURE_COORD_ARRAY: - case GL_EDGE_FLAG_ARRAY: return; - - default: return; - } - - if (r128ctx->regs.tex_cntl_c != t) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.tex_cntl_c = t; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ENGINESTATE; - } - if (r128ctx->regs.pm4_vc_fpu_setup != f) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.pm4_vc_fpu_setup = f; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_SETUPSTATE; - } + 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; + } -static void r128DDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - GLubyte c[4]; - CARD32 col; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { - fprintf(stderr, "r128DDFogfv(%p, 0x%x)\n", ctx, pname); - } - - switch (pname) { - case GL_FOG_MODE: - case GL_FOG_DENSITY: - case GL_FOG_START: - case GL_FOG_END: - break; - - case GL_FOG_COLOR: - FLOAT_RGBA_TO_UBYTE_RGBA(c, ctx->Fog.Color); - col = r128PackColor(32, c[0], c[1], c[2], c[3]); - if (r128ctx->regs.fog_color_c != col) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.fog_color_c = col; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_FOGSTATE; - } - break; - - default: - return; - } + 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 r128DDScissor(GLcontext *ctx, - GLint x, GLint y, GLsizei w, GLsizei h) +static void r128DDLightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - r128ctx->ScissorRect.x1 = x; - r128ctx->ScissorRect.y1 = r128ctx->driDrawable->h - (y + h); - r128ctx->ScissorRect.x2 = x + w; - r128ctx->ScissorRect.y2 = r128ctx->driDrawable->h - y; + if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_RENDER; + } } static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) { r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 s = r128ctx->regs.pm4_vc_fpu_setup; + CARD32 s = r128ctx->setup.pm4_vc_fpu_setup; s &= ~R128_FPU_COLOR_MASK; @@ -751,636 +573,700 @@ static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) return; } - if ( r128ctx->regs.pm4_vc_fpu_setup != s ) { + if ( r128ctx->setup.pm4_vc_fpu_setup != s ) { FLUSH_BATCH( r128ctx ); - r128ctx->regs.pm4_vc_fpu_setup = s; + r128ctx->setup.pm4_vc_fpu_setup = s; - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_SETUPSTATE; + r128ctx->new_state |= R128_NEW_CONTEXT; + r128ctx->dirty |= R128_UPLOAD_SETUP; } } -/* Initialize the driver's state functions */ -void r128DDInitStateFuncs(GLcontext *ctx) + +/* ============================================================= + * Window position + */ + +void r128UpdateWindow( GLcontext *ctx ) { - ctx->Driver.UpdateState = r128DDUpdateState; - - ctx->Driver.ClearIndex = NULL; - ctx->Driver.ClearColor = r128DDClearColor; - ctx->Driver.Index = NULL; - ctx->Driver.Color = r128DDColor; - ctx->Driver.SetDrawBuffer = r128DDSetDrawBuffer; - ctx->Driver.SetReadBuffer = r128DDSetReadBuffer; - - ctx->Driver.IndexMask = NULL; - ctx->Driver.ColorMask = r128DDColorMask; - ctx->Driver.LogicOp = NULL; - ctx->Driver.Dither = r128DDDither; - - ctx->Driver.NearFar = NULL; - - ctx->Driver.RenderStart = r128DDUpdateHWState; - ctx->Driver.RenderFinish = NULL; - ctx->Driver.RasterSetup = NULL; - - ctx->Driver.RenderVBClippedTab = NULL; - ctx->Driver.RenderVBCulledTab = NULL; - ctx->Driver.RenderVBRawTab = NULL; - - ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange; - ctx->Driver.MultipassFunc = NULL; - - ctx->Driver.AlphaFunc = r128DDAlphaFunc; - ctx->Driver.BlendEquation = NULL; - ctx->Driver.BlendFunc = r128DDBlendFunc; - ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate; - ctx->Driver.ClearDepth = r128DDClearDepth; - ctx->Driver.CullFace = r128DDCullFace; - ctx->Driver.FrontFace = r128DDFrontFace; - ctx->Driver.DepthFunc = r128DDDepthFunc; - ctx->Driver.DepthMask = r128DDDepthMask; - ctx->Driver.DepthRange = NULL; - ctx->Driver.Enable = r128DDEnable; - ctx->Driver.Fogfv = r128DDFogfv; - ctx->Driver.Hint = NULL; - ctx->Driver.Lightfv = NULL; - ctx->Driver.LogicOpcode = r128DDLogicOpCode; - ctx->Driver.LightModelfv = r128DDLightModelfv; - ctx->Driver.PolygonMode = NULL; - ctx->Driver.Scissor = r128DDScissor; - ctx->Driver.ShadeModel = r128DDShadeModel; - ctx->Driver.ClearStencil = NULL; - ctx->Driver.StencilFunc = NULL; - ctx->Driver.StencilMask = NULL; - ctx->Driver.StencilOp = NULL; - ctx->Driver.Viewport = NULL; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + int x = r128ctx->driDrawable->x; + int y = r128ctx->driDrawable->y; + + r128ctx->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | + (x << R128_WINDOW_X_SHIFT)); + + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW; } -/* Initialize the context's hardware state */ -void r128DDInitState(r128ContextPtr r128ctx) + +/* ============================================================= + * Miscellaneous + */ + +static void r128DDClearColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - int dst_bpp, depth_bpp, pitch, i; - CARD32 depthClear; - - pitch = r128ctx->r128Screen->fbStride / r128ctx->r128Screen->bpp; - - switch (r128ctx->r128Screen->pixel_code) { - case 8: dst_bpp = R128_GMC_DST_8BPP_CI; break; - case 15: dst_bpp = R128_GMC_DST_15BPP; break; - case 16: dst_bpp = R128_GMC_DST_16BPP; break; - case 24: dst_bpp = R128_GMC_DST_24BPP; break; - case 32: dst_bpp = R128_GMC_DST_32BPP; break; - default: - fprintf(stderr, "Error: Unsupported pixel depth %d... exiting\n", - r128ctx->r128Screen->pixel_code); - exit(-1); - } - - /* FIXME: Figure out how to use 16bpp depth buffer in 32bpp mode */ - switch (r128ctx->glCtx->Visual->DepthBits) { - case 16: depthClear = 0x0000ffff; depth_bpp = R128_Z_PIX_WIDTH_16; break; - case 24: depthClear = 0x00ffffff; depth_bpp = R128_Z_PIX_WIDTH_24; break; - case 32: depthClear = 0xffffffff; depth_bpp = R128_Z_PIX_WIDTH_32; break; - default: - fprintf(stderr, "Error: Unsupported depth %d... exiting\n", - r128ctx->r128Screen->bpp); - exit(-1); - break; - } - - /* Precalculate the depth scale while we're here */ - switch (r128ctx->glCtx->Visual->DepthBits) { - case 16: r128ctx->depth_scale = 1.0 / 65536.0; break; - case 24: r128ctx->depth_scale = 1.0 / 16777216.0; break; - case 32: r128ctx->depth_scale = 1.0 / 4294967296.0; break; - default: r128ctx->depth_scale = 1.0 / 65536.0; break; - } - - r128ctx->dirty = R128_ALL_DIRTY; - r128ctx->dirty_context = R128_CTX_ALL_DIRTY; - - r128ctx->RenderIndex = R128_FALLBACK_BIT; - r128ctx->PointsFunc = NULL; - r128ctx->LineFunc = NULL; - r128ctx->TriangleFunc = NULL; - r128ctx->QuadFunc = NULL; - - r128ctx->IndirectTriangles = 0; - r128ctx->Fallback = 0; - - if (r128ctx->glCtx->Visual->DBflag) { - r128ctx->drawX = r128ctx->r128Screen->backX; - r128ctx->drawY = r128ctx->r128Screen->backY; - r128ctx->readX = r128ctx->r128Screen->backX; - r128ctx->readY = r128ctx->r128Screen->backY; - } else { - r128ctx->drawX = r128ctx->r128Screen->fbX; - r128ctx->drawY = r128ctx->r128Screen->fbY; - r128ctx->readX = r128ctx->r128Screen->fbX; - r128ctx->readY = r128ctx->r128Screen->fbY; - } - - r128ctx->ClearColor = 0x00000000; - r128ctx->ClearDepth = depthClear; - - r128ctx->regs.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_8QW; - - r128ctx->regs.dst_pitch_offset_c = pitch << R128_PITCH_SHIFT; - - r128ctx->regs.dp_gui_master_cntl = - 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->regs.sc_top_left_c = 0x00000000; - r128ctx->regs.sc_bottom_right_c = 0x1fff1fff; - - r128ctx->regs.aux_sc_cntl = 0x00000000; - - r128ctx->regs.aux1_sc_left = 0x00000000; - r128ctx->regs.aux1_sc_right = 0x00001fff; - r128ctx->regs.aux1_sc_top = 0x00000000; - r128ctx->regs.aux1_sc_bottom = 0x00001fff; - - r128ctx->regs.aux2_sc_left = 0x00000000; - r128ctx->regs.aux2_sc_right = 0x00001fff; - r128ctx->regs.aux2_sc_top = 0x00000000; - r128ctx->regs.aux2_sc_bottom = 0x00001fff; - - r128ctx->regs.aux3_sc_left = 0x00000000; - r128ctx->regs.aux3_sc_right = 0x00001fff; - r128ctx->regs.aux3_sc_top = 0x00000000; - r128ctx->regs.aux3_sc_bottom = 0x00001fff; - - r128ctx->regs.z_offset_c = (r128ctx->r128Screen->depthX * - (r128ctx->r128Screen->bpp/8) + - r128ctx->r128Screen->depthY * - r128ctx->r128Screen->fbStride); - r128ctx->regs.z_pitch_c = pitch; - - r128ctx->regs.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; - - r128ctx->regs.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 | - (0x0f << R128_LOD_BIAS_SHIFT); - - r128ctx->regs.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->regs.texture_clr_cmp_clr_c = 0x00000000; - r128ctx->regs.texture_clr_cmp_msk_c = 0xffffffff; - - r128ctx->regs.prim_tex_cntl_c = - R128_MIN_BLEND_NEAREST | - R128_MAG_BLEND_NEAREST | - R128_MIP_MAP_DISABLE | - R128_TEX_CLAMP_S_WRAP | - R128_TEX_CLAMP_T_WRAP; - - r128ctx->regs.prim_texture_combine_cntl_c = - R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA; - - r128ctx->regs.tex_size_pitch_c = - (0 << R128_TEX_PITCH_SHIFT) | - (0 << R128_TEX_SIZE_SHIFT) | - (0 << R128_TEX_HEIGHT_SHIFT) | - (0 << R128_TEX_MIN_SIZE_SHIFT) | - (0 << R128_SEC_TEX_PITCH_SHIFT) | - (0 << R128_SEC_TEX_SIZE_SHIFT) | - (0 << R128_SEC_TEX_HEIGHT_SHIFT) | - (0 << R128_SEC_TEX_MIN_SIZE_SHIFT); - - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.prim_tex_offset[i] = 0x00000000; - - r128ctx->regs.sec_tex_cntl_c = - R128_SEC_SELECT_PRIM_ST; - - r128ctx->regs.sec_tex_combine_cntl_c = - R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_DIS | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA; - - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.sec_tex_offset[i] = 0x00000000; - - r128ctx->regs.constant_color_c = 0x00ffffff; - r128ctx->regs.prim_texture_border_color_c = 0x00ffffff; - r128ctx->regs.sec_texture_border_color_c = 0x00ffffff; - r128ctx->regs.sten_ref_mask_c = 0xffff0000; - r128ctx->regs.plane_3d_mask_c = 0xffffffff; - - r128ctx->regs.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->regs.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->regs.fog_color_c = 0x00000000; - - r128ctx->regs.window_xy_offset = 0x00000000; - - r128ctx->regs.dp_write_mask = 0xffffffff; - - r128ctx->regs.pc_gui_ctlstat = R128_PC_FLUSH_GUI; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ALL_DIRTY; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + r128ctx->ClearColor = r128PackColor( r128ctx->r128Screen->depth, + r, g, b, a ); } -#if 0 -/* Upload the fog table for the current fog mode - * - * KW: I beleive that this can be made to work for all fog modes, - * given some constraints on the projection matrix. Please leave - * this code here for now... - */ -static void r128UploadFogTable(r128ContextPtr r128ctx) +static void r128DDColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - int i; - - R128CCE0(R128_CCE_PACKET0, R128_FOG_TABLE_INDEX, 0); - R128CCE(0x00000000); - - R128CCE0(R128_CCE_PACKET0_ONE_REG_WR, R128_FOG_TABLE_DATA, 255); - - - if (0) - fprintf(stderr, "uploading fog table for %s\n", - gl_lookup_enum_by_nr(r128ctx->FogMode)); - - - /* KW: I'm not sure we're doing enough here - shouldn't density - * play a role in calculating the exp and exp2 tables -- is the - * card really doing exponent calculations of its own? Need to - * see the spec... - */ - switch (r128ctx->FogMode) { - case GL_LINEAR: - for (i = 0; i < 256; i++) { - R128CCE(255 - i); - } - break; - case GL_EXP: - for (i = 0; i < 256; i++) { - float arg = (255 - i)/255.0; - float exparg = exp(arg); - int result; - FLOAT_COLOR_TO_UBYTE_COLOR(result, exparg); - R128CCE(result); - } - break; - case GL_EXP2: - for (i = 0; i < 256; i++) { - float arg = (255 - i)/255.0; - float exparg = (exp(arg*arg) - 1) / (M_E - 1); /* range [0,1] */ - int result; - FLOAT_COLOR_TO_UBYTE_COLOR(result, exparg); - R128CCE(result); - } - break; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + r128ctx->Color = r128PackColor( r128ctx->r128Screen->depth, + r, g, b, a ); } -#endif -/* Load the current context's state into the hardware */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128LoadContext(r128ContextPtr r128ctx) +static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode ) { - int i; - int tex_size_pitch_done = GL_FALSE; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { - fprintf(stderr, "r128LoadContext(%p)\n", r128ctx->glCtx); - } - -#if 0 - r128ctx->dirty_context = R128_CTX_ALL_DIRTY; -#endif - -#if 1 - /* FIXME: Why do these need to be updated even when they don't change? */ - r128ctx->dirty_context |= (R128_CTX_MISC | - R128_CTX_ENGINESTATE | - R128_CTX_ALPHASTATE); -#endif - -#if 1 - /* FIXME: Is this _really_ needed? */ - if (r128ctx->dirty_context) - if (!R128CCE_USE_RING_BUFFER(r128ctx->r128Screen->CCEMode)) - r128WaitForIdleLocked(r128ctx); -#endif - - if (r128ctx->dirty_context & R128_CTX_MISC) { - R128CCE1(R128_CCE_PACKET1, R128_SCALE_3D_CNTL, R128_DP_WRITE_MASK); - R128CCE(r128ctx->regs.scale_3d_cntl); - R128CCE(r128ctx->regs.dp_write_mask); - - R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 1); - R128CCE(r128ctx->regs.dst_pitch_offset_c); - R128CCE(r128ctx->regs.dp_gui_master_cntl); - - R128CCE0(R128_CCE_PACKET0, R128_TEXTURE_CLR_CMP_CLR_C, 1); - R128CCE(r128ctx->regs.texture_clr_cmp_clr_c); - R128CCE(r128ctx->regs.texture_clr_cmp_msk_c); - - R128CCE0(R128_CCE_PACKET0, R128_STEN_REF_MASK_C, 1); - R128CCE(r128ctx->regs.sten_ref_mask_c); - R128CCE(r128ctx->regs.plane_3d_mask_c); - } - - if (r128ctx->dirty_context & R128_CTX_ENGINESTATE) { - R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); - R128CCE(r128ctx->regs.tex_cntl_c); - } - - if (r128ctx->dirty_context & R128_CTX_TEX0STATE) { - R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEX_CNTL_C, 2+R128_TEX_MAXLEVELS); - R128CCE(r128ctx->regs.prim_tex_cntl_c); - R128CCE(r128ctx->regs.prim_texture_combine_cntl_c); - R128CCE(r128ctx->regs.tex_size_pitch_c); - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - R128CCE(r128ctx->regs.prim_tex_offset[i]); - - R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEXTURE_BORDER_COLOR_C, 0); - R128CCE(r128ctx->regs.prim_texture_border_color_c); - - tex_size_pitch_done = GL_TRUE; - } - - if (r128ctx->dirty_context & R128_CTX_TEX1STATE) { - if (!tex_size_pitch_done) { - R128CCE0(R128_CCE_PACKET0, R128_TEX_SIZE_PITCH_C, 0); - R128CCE(r128ctx->regs.tex_size_pitch_c); - } - - R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 1+R128_TEX_MAXLEVELS); - R128CCE(r128ctx->regs.sec_tex_cntl_c); - R128CCE(r128ctx->regs.sec_tex_combine_cntl_c); - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - R128CCE(r128ctx->regs.sec_tex_offset[i]); - - R128CCE0(R128_CCE_PACKET0, R128_SEC_TEXTURE_BORDER_COLOR_C, 0); - R128CCE(r128ctx->regs.sec_texture_border_color_c); - } - - if (r128ctx->dirty_context & R128_CTX_TEXENVSTATE) { - R128CCE0(R128_CCE_PACKET0, R128_CONSTANT_COLOR_C, 0); - R128CCE(r128ctx->regs.constant_color_c); - } - - if (r128ctx->dirty_context & R128_CTX_FOGSTATE) { - R128CCE1(R128_CCE_PACKET0, R128_FOG_COLOR_C, 0); - R128CCE(r128ctx->regs.fog_color_c); - } - - if (r128ctx->dirty_context & R128_CTX_ZSTENSTATE) { - R128CCE0(R128_CCE_PACKET0, R128_Z_STEN_CNTL_C, 0); - R128CCE(r128ctx->regs.z_sten_cntl_c); - } - - if (r128ctx->dirty_context & R128_CTX_SCISSORS) { - R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1); - R128CCE(r128ctx->regs.sc_top_left_c); - R128CCE(r128ctx->regs.sc_bottom_right_c); - } - - if (r128ctx->dirty_context & (R128_CTX_ALPHASTATE | - R128_CTX_FOGSTATE)) { - R128CCE0(R128_CCE_PACKET0, R128_MISC_3D_STATE_CNTL_REG, 0); - R128CCE(r128ctx->regs.misc_3d_state_cntl_reg); - } - - if (r128ctx->dirty_context & R128_CTX_SETUPSTATE) { - R128CCE1(R128_CCE_PACKET1, R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP); - R128CCE(r128ctx->regs.setup_cntl); - R128CCE(r128ctx->regs.pm4_vc_fpu_setup); - } - - if (r128ctx->dirty_context & R128_CTX_WIN_Z_POS) { - R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0); - R128CCE(r128ctx->regs.window_xy_offset); - - R128CCE0(R128_CCE_PACKET0, R128_Z_OFFSET_C, 1); - R128CCE(r128ctx->regs.z_offset_c); - R128CCE(r128ctx->regs.z_pitch_c); - } - -#if 0 - if (r128ctx->dirty_context & R128_CTX_FLUSH_PIX_CACHE) { - R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0); - R128CCE(r128ctx->regs.pc_gui_ctlstat); - } -#endif - - R128CCE_SUBMIT_PACKET(); - - /* Turn off the texture cache flushing */ - r128ctx->regs.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; - - /* Turn off the pixel cache flushing */ - r128ctx->regs.pc_gui_ctlstat &= ~R128_PC_FLUSH_ALL; - - r128ctx->dirty_context = R128_CTX_CLEAN; + if ( ctx->Color.ColorLogicOpEnabled ) { + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + FLUSH_BATCH( r128ctx ); + + if ( opcode == GL_COPY ) { + r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; + } else { + r128ctx->Fallback |= R128_FALLBACK_LOGICOP; + } + } } -/* Set the hardware clip rects for drawing to the current color buffer */ -/* NOTE: This function is only called while holding the hardware lock */ -void r128SetClipRects(r128ContextPtr r128ctx, - XF86DRIClipRectPtr pc, int nc) +static GLboolean r128DDSetDrawBuffer( GLcontext *ctx, GLenum mode ) { - if (!pc) return; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + int found = GL_TRUE; + + FLUSH_BATCH( r128ctx ); + + if ( r128ctx->DrawBuffer != mode ) { + r128ctx->DrawBuffer = mode; + r128ctx->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; + 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; + break; + default: + r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER; + found = GL_FALSE; + break; + } - /* Clear any previous auxiliary scissors */ - r128ctx->regs.aux_sc_cntl = 0x00000000; + r128ctx->setup.dst_pitch_offset_c = (((r128ctx->drawPitch/8) << 21) | + (r128ctx->drawOffset >> 5)); + r128ctx->new_state |= R128_NEW_WINDOW; + } - switch (nc) { - case 3: - R128CCE0(R128_CCE_PACKET0, R128_AUX3_SC_LEFT, 3); - R128CCE(pc[2].x1 + r128ctx->drawX); - R128CCE(pc[2].x2-1 + r128ctx->drawX); - R128CCE(pc[2].y1 + r128ctx->drawY); - R128CCE(pc[2].y2-1 + r128ctx->drawY); + return found; +} - r128ctx->regs.aux_sc_cntl |= R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR; +static void r128DDSetReadBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLenum mode ) +{ + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - case 2: - R128CCE0(R128_CCE_PACKET0, R128_AUX2_SC_LEFT, 3); - R128CCE(pc[1].x1 + r128ctx->drawX); - R128CCE(pc[1].x2-1 + r128ctx->drawX); - R128CCE(pc[1].y1 + r128ctx->drawY); - R128CCE(pc[1].y2-1 + r128ctx->drawY); + r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER; - r128ctx->regs.aux_sc_cntl |= R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR; + 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; + 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; + break; + default: + r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER; + break; + } +} - case 1: - R128CCE0(R128_CCE_PACKET0, R128_AUX1_SC_LEFT, 3); - R128CCE(pc[0].x1 + r128ctx->drawX); - R128CCE(pc[0].x2-1 + r128ctx->drawX); - R128CCE(pc[0].y1 + r128ctx->drawY); - R128CCE(pc[0].y2-1 + r128ctx->drawY); - r128ctx->regs.aux_sc_cntl |= R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR; - break; +/* ============================================================= + * Polygon stipple + */ - default: - return; - } +static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + GLuint *stipple = (GLuint *)mask; + + FLUSH_BATCH( r128ctx ); + ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; - R128CCE0(R128_CCE_PACKET0, R128_AUX_SC_CNTL, 0); - R128CCE(r128ctx->regs.aux_sc_cntl); + r128ctx->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; + } else { + r128ctx->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; + } - R128CCE_SUBMIT_PACKET(); + LOCK_HARDWARE( r128ctx ); + + drmR128PolygonStipple( r128ctx->driFd, stipple ); + + UNLOCK_HARDWARE( r128ctx ); + + r128ctx->new_state |= R128_NEW_CONTEXT; + r128ctx->dirty |= R128_UPLOAD_CONTEXT; } -/* Update the driver's notion of the window position */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UpdateWindowPosition(r128ContextPtr r128ctx) + +/* ============================================================= + * State enable/disable + */ + +static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) { - int x = r128ctx->driDrawable->x + r128ctx->drawX; - int y = r128ctx->driDrawable->y + r128ctx->drawY; - -#if 0 - /* FIXME: Is this _really_ needed? */ - R128CCE_FLUSH_VB(r128ctx); -#endif - r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | - (x << R128_WINDOW_X_SHIFT)); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s = %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( cap ), + state ? "GL_TRUE" : "GL_FALSE" ); + } - /* Recalculate the Z buffer offset since we might be drawing to the - back buffer and window_xy_offset affects both color buffer and - depth drawing */ - r128ctx->regs.z_offset_c = ((r128ctx->r128Screen->depthX - - r128ctx->drawX) * - (r128ctx->r128Screen->bpp/8) + - (r128ctx->r128Screen->depthY - - r128ctx->drawY) * - r128ctx->r128Screen->fbStride); - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_WIN_Z_POS; + switch ( cap ) { + case GL_ALPHA_TEST: + case GL_BLEND: + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_ALPHA; + break; + + case GL_CULL_FACE: + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_CULL; + break; + + case GL_DEPTH_TEST: + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_DEPTH; + break; + + case GL_DITHER: + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_RENDER; + break; + + case GL_FOG: + FLUSH_BATCH( r128ctx ); + r128ctx->new_state |= R128_NEW_FOG; + break; + + case GL_INDEX_LOGIC_OP: + case GL_COLOR_LOGIC_OP: + FLUSH_BATCH( r128ctx ); + if ( state && ctx->Color.LogicOp != GL_COPY ) { + r128ctx->Fallback |= R128_FALLBACK_LOGICOP; + } else { + r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; + } + break; + + case GL_SCISSOR_TEST: + FLUSH_BATCH( r128ctx ); + r128ctx->scissor = state; + r128ctx->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; + 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; + if ( state ) { + r128ctx->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; + } + r128ctx->new_state |= R128_NEW_CONTEXT; + r128ctx->dirty |= R128_UPLOAD_CONTEXT; + } + break; + + default: + return; + } } -/* Update the hardware state */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UpdateHWStateLocked(r128ContextPtr r128ctx) + +/* ============================================================= + * State initialization, management + */ + +static void r128DDPrintDirty( const char *msg, GLuint state ) { - if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE) - r128WaitForIdleLocked(r128ctx); - - /* Update any state that might have changed recently */ - - /* Update the clip rects */ - if (r128ctx->dirty & R128_UPDATE_WINPOS) - r128UpdateWindowPosition(r128ctx); - - /* Update texture state and then upload the images */ - /* Note: Texture images can only be updated after the state has been set */ - if (r128ctx->dirty & R128_UPDATE_TEXSTATE) - r128UpdateTextureState(r128ctx); - if (r128ctx->dirty & R128_UPDATE_TEX0IMAGES) - r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[0]); - if (r128ctx->dirty & R128_UPDATE_TEX1IMAGES) - r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[1]); - - /* Load the state into the hardware */ - /* Note: This must be done after all other state has been set */ - if (r128ctx->dirty & R128_UPDATE_CONTEXT) - r128LoadContext(r128ctx); - - r128ctx->dirty = R128_CLEAN; + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & R128_UPLOAD_CORE) ? "core, " : "", + (state & R128_UPLOAD_CONTEXT) ? "context, " : "", + (state & R128_UPLOAD_SETUP) ? "setup, " : "", + (state & R128_UPLOAD_TEX0) ? "tex0, " : "", + (state & R128_UPLOAD_TEX1) ? "tex1, " : "", + (state & R128_UPLOAD_TEX0IMAGES) ? "tex0 images, " : "", + (state & R128_UPLOAD_TEX1IMAGES) ? "tex1 images, " : "", + (state & R128_UPLOAD_MASKS) ? "masks, " : "", + (state & R128_UPLOAD_WINDOW) ? "window, " : "", + (state & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (state & R128_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 r128EmitHwStateLocked( r128ContextPtr r128ctx ) +{ + R128SAREAPrivPtr sarea = r128ctx->sarea; + r128_context_regs_t *regs = &(r128ctx->setup); + r128TexObjPtr t0 = r128ctx->CurrentTexObj[0]; + r128TexObjPtr t1 = r128ctx->CurrentTexObj[1]; + + if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) { + r128DDPrintDirty( "r128EmitHwStateLocked", r128ctx->dirty ); + } + + if ( r128ctx->dirty & R128_UPLOAD_TEX0IMAGES ) { + if ( t0 ) r128UploadTexImages( r128ctx, t0 ); + r128ctx->dirty &= ~R128_UPLOAD_TEX0IMAGES; + } + if ( r128ctx->dirty & R128_UPLOAD_TEX1IMAGES ) { + if ( t1 ) r128UploadTexImages( r128ctx, t1 ); + r128ctx->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) ) { + 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 ( (r128ctx->dirty & R128_UPLOAD_TEX1) && t1 ) { + memcpy( &sarea->TexState[1], &t1->setup, sizeof(sarea->TexState[1]) ); + } + + sarea->vertsize = r128ctx->vertsize; + sarea->vc_format = r128ctx->vc_format; + + /* Turn off the texture cache flushing */ + r128ctx->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + + sarea->dirty |= r128ctx->dirty; + r128ctx->dirty &= R128_UPLOAD_CLIPRECTS; +} + +static void r128DDPrintState( const char *msg, GLuint flags ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & R128_NEW_CONTEXT) ? "context, " : "", + (flags & R128_NEW_ALPHA) ? "alpha, " : "", + (flags & R128_NEW_DEPTH) ? "depth, " : "", + (flags & R128_NEW_FOG) ? "fog, " : "", + (flags & R128_NEW_CLIP) ? "clip, " : "", + (flags & R128_NEW_TEXTURE) ? "texture, " : "", + (flags & R128_NEW_CULL) ? "cull, " : "", + (flags & R128_NEW_MASKS) ? "masks, " : "", + (flags & R128_NEW_WINDOW) ? "window, " : "" ); } /* Update the hardware state */ -void r128UpdateHWState(r128ContextPtr r128ctx) +void r128DDUpdateHWState( GLcontext *ctx ) +{ + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + int new_state = r128ctx->new_state; + + if ( new_state ) + { + FLUSH_BATCH( r128ctx ); + + r128ctx->new_state = 0; + + if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) + r128DDPrintState( "r128UpdateHwState", new_state ); + + /* Update the various parts of the context's state. + */ + if ( new_state & R128_NEW_ALPHA ) + r128UpdateAlphaMode( ctx ); + + if ( new_state & R128_NEW_DEPTH ) + r128UpdateZMode( ctx ); + + if ( new_state & R128_NEW_FOG ) + r128UpdateFogAttrib( ctx ); + + if ( new_state & R128_NEW_CLIP ) + r128UpdateClipping( ctx ); + + if ( new_state & R128_NEW_CULL ) + r128UpdateCull( 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 ); + + if ( new_state & R128_NEW_TEXTURE ) + r128UpdateTextureState( 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 r128 uses triangles to render lines and points, it is + * necessary to turn off hardware culling when rendering these + * primitives. + */ +static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) +{ + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + CARD32 f = r128ctx->setup.pm4_vc_fpu_setup; + + f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + f &= ~R128_FRONTFACE_SOLID; + break; + case GL_BACK: + f &= ~R128_BACKFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + f &= ~(R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID); + break; + } + } + + if ( r128ctx->setup.pm4_vc_fpu_setup != f ) { + FLUSH_BATCH( r128ctx ); + r128ctx->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; + } +} + + +#define INTERESTED (~(NEW_MODELVIEW | \ + NEW_PROJECTION | \ + NEW_TEXTURE_MATRIX | \ + NEW_USER_CLIP | \ + NEW_CLIENT_STATE)) + +void r128DDUpdateState( GLcontext *ctx ) { - LOCK_HARDWARE(r128ctx); - r128UpdateHWStateLocked(r128ctx); - UNLOCK_HARDWARE(r128ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + if ( ctx->NewState & INTERESTED ) { + r128DDChooseRenderState( ctx ); + r128DDChooseRasterSetupFunc( ctx ); + } + + /* Need to do this here to detect texture fallbacks before + * setting triangle functions. + */ + if ( r128ctx->new_state & R128_NEW_TEXTURE ) { + r128DDUpdateHWState( ctx ); + } + + if ( !r128ctx->Fallback ) { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= r128ctx->IndirectTriangles; + + ctx->Driver.PointsFunc = r128ctx->PointsFunc; + ctx->Driver.LineFunc = r128ctx->LineFunc; + ctx->Driver.TriangleFunc = r128ctx->TriangleFunc; + ctx->Driver.QuadFunc = r128ctx->QuadFunc; + } } -/* Update the driver's state */ -/* NOTE: This function is only called while holding the hardware lock */ -void r128UpdateState(r128ContextPtr r128ctx, int winMoved) + +/* Initialize the context's hardware state */ +void r128DDInitState( r128ContextPtr r128ctx ) { - R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA; - int i; + int dst_bpp, depth_bpp; + CARD32 bias; + + switch ( r128ctx->BufferSize ) { + case 8: dst_bpp = R128_GMC_DST_8BPP_CI; break; + case 15: dst_bpp = R128_GMC_DST_15BPP; break; + case 16: dst_bpp = R128_GMC_DST_16BPP; break; + case 24: dst_bpp = R128_GMC_DST_24BPP; break; + case 32: dst_bpp = R128_GMC_DST_32BPP; break; + default: + fprintf( stderr, "Error: Unsupported pixel depth %d... exiting\n", + r128ctx->BufferSize ); + exit( -1 ); + } + + switch ( r128ctx->DepthSize ) { + case 16: + r128ctx->ClearDepth = 0x0000ffff; + depth_bpp = R128_Z_PIX_WIDTH_16; + r128ctx->depth_scale = 1.0 / 65536.0; + break; + case 24: + r128ctx->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; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + r128ctx->DepthSize ); + exit( -1 ); + } - if (sarea->ctxOwner != r128ctx->driContext->hHWContext) { - sarea->ctxOwner = r128ctx->driContext->hHWContext; - r128ctx->dirty_context = R128_CTX_ALL_DIRTY; - r128LoadContext(r128ctx); - } + r128ctx->ClearColor = 0x00000000; + + r128ctx->RenderIndex = R128_FALLBACK_BIT; + r128ctx->PointsFunc = NULL; + r128ctx->LineFunc = NULL; + r128ctx->TriangleFunc = NULL; + r128ctx->QuadFunc = NULL; + + 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; + } else { + r128ctx->DrawBuffer = GL_FRONT_LEFT; + r128ctx->drawOffset = r128ctx->readOffset = + r128ctx->r128Screen->frontOffset; + r128ctx->drawPitch = r128ctx->readPitch = + r128ctx->r128Screen->frontPitch; + } - for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) - r128AgeTextures(r128ctx, i); + /* 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_2BITS | + 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_2BITS); + + 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; +} - if (winMoved) r128ctx->dirty |= R128_UPDATE_WINPOS; +/* Initialize the driver's state functions */ +void r128DDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = r128DDUpdateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = r128DDClearColor; + ctx->Driver.Index = NULL; + ctx->Driver.Color = r128DDColor; + ctx->Driver.SetDrawBuffer = r128DDSetDrawBuffer; + ctx->Driver.SetReadBuffer = r128DDSetReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = r128DDColorMask; + ctx->Driver.LogicOp = NULL; + ctx->Driver.Dither = NULL; + + ctx->Driver.NearFar = NULL; + + ctx->Driver.RenderStart = r128DDUpdateHWState; + ctx->Driver.RenderFinish = NULL; + ctx->Driver.RasterSetup = NULL; + + ctx->Driver.RenderVBClippedTab = NULL; + ctx->Driver.RenderVBCulledTab = NULL; + ctx->Driver.RenderVBRawTab = NULL; + + ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange; + ctx->Driver.MultipassFunc = NULL; + + ctx->Driver.AlphaFunc = r128DDAlphaFunc; + ctx->Driver.BlendEquation = r128DDBlendEquation; + ctx->Driver.BlendFunc = r128DDBlendFunc; + ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate; + ctx->Driver.ClearDepth = r128DDClearDepth; + ctx->Driver.CullFace = r128DDCullFace; + ctx->Driver.FrontFace = r128DDFrontFace; + ctx->Driver.DepthFunc = r128DDDepthFunc; + ctx->Driver.DepthMask = r128DDDepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = r128DDEnable; + ctx->Driver.Fogfv = r128DDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = r128DDLightModelfv; + ctx->Driver.LogicOpcode = r128DDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = r128DDPolygonStipple; + ctx->Driver.Scissor = r128DDScissor; + ctx->Driver.ShadeModel = r128DDShadeModel; + 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/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h index faa182a86..6d122879d 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.h,v 1.1 2000/06/17 00:03:07 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.h,v 1.2 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -37,14 +38,19 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -extern void r128DDInitState(r128ContextPtr r128ctx); -extern void r128DDInitStateFuncs(GLcontext *ctx); +#include "r128_context.h" -extern void r128UpdateState(r128ContextPtr r128ctx, int winMoved); -extern void r128UpdateHWState(r128ContextPtr r128ctx); +extern void r128DDInitState( r128ContextPtr r128ctx ); +extern void r128DDInitStateFuncs( GLcontext *ctx ); -extern void r128SetClipRects(r128ContextPtr r128ctx, - XF86DRIClipRectPtr pc, int nc); +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 ); #endif #endif /* _R128_STATE_H_ */ 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 537a88d8f..ff619fa46 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.5 2000/11/08 05:02:51 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.6 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,23 +28,22 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Gareth Hughes <gareth@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_lock.h" #include "r128_state.h" -#include "r128_reg.h" -#include "r128_cce.h" +#include "r128_ioctl.h" #include "r128_vb.h" #include "r128_tex.h" #include "mmath.h" #include "simple_list.h" +#include "enums.h" +#include "mem.h" + static void r128SetTexWrap(r128TexObjPtr t, GLenum srwap, GLenum twrap); static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf); @@ -52,267 +51,309 @@ 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, - struct gl_texture_object *tObj) +static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, + struct gl_texture_object *tObj ) { - r128TexObjPtr t; - struct gl_texture_image *image; - int log2Pitch, log2Height, log2Size, log2MinSize; - int totalSize; - int i; - - image = tObj->Image[0]; - if (!image) return NULL; /* ERROR!!! */ - - t = (r128TexObjPtr)calloc(1,sizeof(*t)); - if (!t) return NULL; /* ERROR!!! */ - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) - fprintf(stderr, "r128CreateTexObj(%p)\n", tObj); - - switch (image->Format) { - case GL_RGBA: - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - if (r128ctx->r128Screen->bpp == 32) { - t->texelBytes = 4; - t->textureFormat = R128_DATATYPE_ARGB8888; - } else { - t->texelBytes = 2; - t->textureFormat = R128_DATATYPE_ARGB4444; - } - break; - - case GL_RGB: - if (r128ctx->r128Screen->bpp == 32) { - t->texelBytes = 4; - t->textureFormat = R128_DATATYPE_ARGB8888; - } else { - t->texelBytes = 2; - t->textureFormat = R128_DATATYPE_RGB565; - } - 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; - } - break; - - case GL_COLOR_INDEX: - t->texelBytes = 1; - t->textureFormat = R128_DATATYPE_CI8; - break; - - default: - /* ERROR!!! */ - fprintf(stderr, "r128CreateTexObj: bad image->Format\n"); - free(t); - return NULL; - } - - /* Calculate dimensions in log domain */ - for (i = 1, log2Height = 0; i < image->Height; i *= 2) log2Height++; - for (i = 1, log2Pitch = 0; i < image->Width; i *= 2) log2Pitch++; - if (image->Width > image->Height) log2Size = log2Pitch; - else log2Size = log2Height; - - t->dirty_images = 0; - - /* Calculate mipmap offsets and dimensions */ - totalSize = 0; - for (i = 0; i <= log2Size && tObj->Image[i]; i++) { - t->image[i].offset = totalSize; - t->image[i].width = tObj->Image[i]->Width; - t->image[i].height = tObj->Image[i]->Height; - t->dirty_images |= 1 << i; - totalSize += (tObj->Image[i]->Height * - tObj->Image[i]->Width * - t->texelBytes); - - /* Offsets must be 32-byte aligned for host data blits */ - totalSize = (totalSize + 31) & ~31; - } - log2MinSize = log2Size - i + 1; - - t->totalSize = totalSize; - t->internFormat = image->IntFormat; - - t->bound = 0; - t->heap = 0; /* This is set in r128UploadTexImages */ - t->tObj = tObj; - - t->memBlock = NULL; - t->bufAddr = 0; - - t->regs.tex_cntl = t->textureFormat; - t->regs.size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) | - (log2Size << R128_TEX_SIZE_SHIFT) | - (log2Height << R128_TEX_HEIGHT_SHIFT) | - (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); - t->regs.border_color = 0x00000000; - - if (log2MinSize == log2Size || - log2MinSize != 0) - t->regs.tex_cntl |= R128_MIP_MAP_DISABLE; - - r128SetTexWrap(t, tObj->WrapS, tObj->WrapT); - r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter); - r128SetTexBorderColor(t, tObj->BorderColor); - - tObj->DriverData = t; - - make_empty_list(t); - - return t; + r128TexObjPtr t; + struct gl_texture_image *image; + int log2Pitch, log2Height, log2Size, log2MinSize; + int totalSize; + int i; + + image = tObj->Image[0]; + if ( !image ) + return NULL; + + t = (r128TexObjPtr)CALLOC( sizeof(*t) ); + if ( !t ) + return NULL; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj ); + + switch ( image->Format ) { + case GL_RGBA: + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + if ( r128ctx->r128Screen->bpp == 32 ) { + t->texelBytes = 4; + t->textureFormat = R128_DATATYPE_ARGB8888; + } else { + t->texelBytes = 2; + t->textureFormat = R128_DATATYPE_ARGB4444; + } + break; + + case GL_RGB: + if ( r128ctx->r128Screen->bpp == 32 ) { + t->texelBytes = 4; + t->textureFormat = R128_DATATYPE_ARGB8888; + } else { + t->texelBytes = 2; + t->textureFormat = R128_DATATYPE_RGB565; + } + 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; + } + break; + + case GL_COLOR_INDEX: + t->texelBytes = 1; + t->textureFormat = R128_DATATYPE_CI8; + break; + + 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, log2Pitch = 0 ; i < image->Width ; i *= 2 ) { + log2Pitch++; + } + if ( image->Width > image->Height ) { + log2Size = log2Pitch; + } else { + log2Size = log2Height; + } + + t->dirty_images = 0; + + /* Calculate mipmap offsets and dimensions */ + totalSize = 0; + for ( i = 0 ; i <= log2Size && tObj->Image[i] ; i++ ) { + t->image[i].offset = totalSize; + t->image[i].width = tObj->Image[i]->Width; + t->image[i].height = tObj->Image[i]->Height; + + t->dirty_images |= (1 << i); + + totalSize += (tObj->Image[i]->Height * + tObj->Image[i]->Width * + t->texelBytes); + + /* Offsets must be 32-byte aligned for host data blits and tiling */ + totalSize = (totalSize + 31) & ~31; + } + log2MinSize = log2Size - i + 1; + + t->totalSize = totalSize; + t->internFormat = image->IntFormat; + + t->age = 0; + t->bound = 0; + t->heap = 0; + t->tObj = tObj; + + t->memBlock = NULL; + t->bufAddr = 0; + + /* Hardware state: + */ + t->setup.tex_cntl = (R128_MIN_BLEND_NEAREST | + R128_MAG_BLEND_NEAREST | + R128_TEX_CLAMP_S_WRAP | + R128_TEX_CLAMP_T_WRAP | + t->textureFormat); + + t->setup.tex_combine_cntl = 0x00000000; + + t->setup.tex_size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) | + (log2Size << R128_TEX_SIZE_SHIFT) | + (log2Height << R128_TEX_HEIGHT_SHIFT) | + (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); + + for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + t->setup.tex_offset[i] = 0x00000000; + } + t->setup.tex_border_color = 0x00000000; + + if ( ( log2MinSize == log2Size ) || ( log2MinSize != 0 ) ) { + t->setup.tex_cntl |= R128_MIP_MAP_DISABLE; + } + + r128SetTexWrap( t, tObj->WrapS, tObj->WrapT ); + r128SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + r128SetTexBorderColor( t, tObj->BorderColor ); + + tObj->DriverData = t; + + make_empty_list( t ); + + return t; } /* Destroy hardware state associated with texture `t' */ -/* NOTE: This function can be called while holding the hardware lock and - while not holding the lock*/ -void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t) +void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) { #if ENABLE_PERF_BOXES - /* Bump the performace counter */ - r128ctx->c_textureSwaps++; + /* Bump the performace counter */ + r128ctx->c_textureSwaps++; #endif - if (!t) return; + if ( !t ) return; - if (t->memBlock) { - mmFreeMem(t->memBlock); - t->memBlock = NULL; - } + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } - if (t->tObj) t->tObj->DriverData = NULL; - if (t->bound) r128ctx->CurrentTexObj[t->bound-1] = NULL; + if ( t->tObj ) + t->tObj->DriverData = NULL; + if ( t->bound ) + r128ctx->CurrentTexObj[t->bound-1] = NULL; - remove_from_list(t); - free(t); + remove_from_list( t ); + FREE( t ); } /* Keep track of swapped out texture objects */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128SwapOutTexObj(r128ContextPtr r128ctx, r128TexObjPtr t) +static void r128SwapOutTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) { #if ENABLE_PERF_BOXES - /* Bump the performace counter */ - r128ctx->c_textureSwaps++; + /* Bump the performace counter */ + r128ctx->c_textureSwaps++; #endif - if (t->memBlock) { - mmFreeMem(t->memBlock); - t->memBlock = NULL; - } + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } - t->dirty_images = ~0; - move_to_tail(&r128ctx->SwappedOut, t); + t->dirty_images = ~0; + move_to_tail( &r128ctx->SwappedOut, t ); } /* Print out debugging information about texture LRU */ -void r128PrintLocalLRU(r128ContextPtr r128ctx, int heap) +void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ) { - r128TexObjPtr t; - int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]); - - foreach(t, &r128ctx->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); - } - } + r128TexObjPtr t; + int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]); + + fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); + + foreach( t, &r128ctx->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 r128PrintGlobalLRU(r128ContextPtr r128ctx, int heap) +void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ) { - R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap]; - int i, j; - - for (i = 0, j = R128_NR_TEX_REGIONS ; i < R128_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 == R128_NR_TEX_REGIONS) break; - } - - if (j != R128_NR_TEX_REGIONS) { - fprintf(stderr, "Loop detected in global LRU\n"); - } + r128_tex_region_t *list = r128ctx->sarea->texList[heap]; + int i, j; + + fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); + + for ( i = 0, j = R128_NR_TEX_REGIONS ; i < R128_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 == R128_NR_TEX_REGIONS ) break; + } + + if ( j != R128_NR_TEX_REGIONS ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < R128_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 */ /* NOTE: This function is only called while holding the hardware lock */ -static void r128ResetGlobalLRU(r128ContextPtr r128ctx, int heap) +static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) { - R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap]; - int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; - int i; - - /* - * (Re)initialize the global circular LRU list. The last element in - * the array (R128_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) * log2sz <= r128ctx->r128Screen->texSize[heap]; i++) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - } - - i--; - list[0].prev = R128_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = R128_NR_TEX_REGIONS; - list[R128_NR_TEX_REGIONS].prev = i; - list[R128_NR_TEX_REGIONS].next = 0; - r128ctx->r128Screen->SAREA->texAge[heap] = 0; + r128_tex_region_t *list = r128ctx->sarea->texList[heap]; + int sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + int i; + + /* (Re)initialize the global circular LRU list. The last element in + * the array (R128_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 <= r128ctx->r128Screen->texSize[heap] ; i++ ) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = R128_NR_TEX_REGIONS; + list[i].prev = i-1; + 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; } /* 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) +static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) { - int heap = t->heap; - R128TexRegion *list = r128ctx->r128Screen->SAREA->texList[heap]; - int log2sz = r128ctx->r128Screen->log2TexGran[heap]; - - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size-1) >> log2sz; - int i; - - r128ctx->lastTexAge[heap] = ++r128ctx->r128Screen->SAREA->texAge[heap]; - - /* Update our local LRU */ - move_to_head(&r128ctx->TexObjList[heap], t); - - /* Update the global LRU */ - for (i = start ; i <= end ; i++) { - list[i].in_use = 1; - list[i].age = r128ctx->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 = R128_NR_TEX_REGIONS; - list[i].next = list[R128_NR_TEX_REGIONS].next; - list[(CARD32)list[R128_NR_TEX_REGIONS].next].prev = i; - list[R128_NR_TEX_REGIONS].next = i; - } + int heap = t->heap; + r128_tex_region_t *list = r128ctx->sarea->texList[heap]; + int log2sz = r128ctx->r128Screen->log2TexGran[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]; + + if ( !t->memBlock ) { + fprintf( stderr, "no memblock\n\n" ); + return; + } + + /* Update our local LRU */ + move_to_head( &r128ctx->TexObjList[heap], t ); + + /* Update the global LRU */ + for ( i = start ; i <= end ; i++ ) { + list[i].in_use = 1; + list[i].age = r128ctx->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 = R128_NR_TEX_REGIONS; + list[i].next = list[R128_NR_TEX_REGIONS].next; + list[(CARD32)list[R128_NR_TEX_REGIONS].next].prev = i; + list[R128_NR_TEX_REGIONS].next = i; + } + + if ( 0 ) { + r128PrintGlobalLRU( r128ctx, t->heap ); + r128PrintLocalLRU( r128ctx, t->heap ); + } } /* Update our notion of what textures have been changed since we last @@ -321,1557 +362,1330 @@ static void r128UpdateTexLRU(r128ContextPtr r128ctx, r128TexObjPtr t) 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, - int offset, int size, int in_use) +static void r128TexturesGone( r128ContextPtr r128ctx, int heap, + int offset, int size, int in_use ) { - r128TexObjPtr t, tmp; - - foreach_s (t, tmp, &r128ctx->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) r128SwapOutTexObj(r128ctx, t); - else r128DestroyTexObj(r128ctx, t); - } - - if (in_use) { - t = (r128TexObjPtr) calloc(1,sizeof(*t)); - if (!t) return; - - t->memBlock = mmAllocMem(r128ctx->texHeap[heap], size, 0, offset); - insert_at_head(&r128ctx->TexObjList[heap], t); - } + r128TexObjPtr t, tmp; + + foreach_s ( t, tmp, &r128ctx->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 ) { + r128SwapOutTexObj( r128ctx, t ); + } else { + r128DestroyTexObj( r128ctx, t ); + } + } + + if ( in_use ) { + t = (r128TexObjPtr) CALLOC( sizeof(*t) ); + if (!t) return; + + t->memBlock = mmAllocMem( r128ctx->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] ); + return; + } + insert_at_head( &r128ctx->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) +void r128AgeTextures( r128ContextPtr r128ctx, int heap ) { - R128SAREAPrivPtr sarea = r128ctx->r128Screen->SAREA; - - if (sarea->texAge[heap] != r128ctx->lastTexAge[heap]) { - int log2sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; - int nr = 0; - int idx; - - for (idx = sarea->texList[heap][R128_NR_TEX_REGIONS].prev; - idx != R128_NR_TEX_REGIONS && nr < R128_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 * log2sz > r128ctx->r128Screen->texSize[heap]) { - nr = R128_NR_TEX_REGIONS; - break; - } - - if (sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap]) - r128TexturesGone(r128ctx, heap, idx * log2sz, log2sz, - sarea->texList[heap][idx].in_use); - } - - if (nr == R128_NR_TEX_REGIONS) { - r128TexturesGone(r128ctx, heap, - 0, r128ctx->r128Screen->texSize[heap], 0); - r128ResetGlobalLRU(r128ctx, heap); - } - - r128ctx->dirty |= R128_UPDATE_TEX0IMAGES; - r128ctx->dirty |= R128_UPDATE_TEX1IMAGES; - r128ctx->lastTexAge[heap] = sarea->texAge[heap]; - } + R128SAREAPriv *sarea = r128ctx->sarea; + + if ( sarea->texAge[heap] != r128ctx->lastTexAge[heap] ) { + int sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + int nr = 0; + int idx; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in our local list... Fix with a cursor pointer. + */ + for ( idx = sarea->texList[heap][R128_NR_TEX_REGIONS].prev ; + idx != R128_NR_TEX_REGIONS && nr < R128_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 > r128ctx->r128Screen->texSize[heap] ) { + nr = R128_NR_TEX_REGIONS; + break; + } + + if ( sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap] ) { + r128TexturesGone( r128ctx, heap, idx * sz, sz, + sarea->texList[heap][idx].in_use ); + } + } + + /* If switching texturing schemes, then the SAREA might not + * have been properly cleared, so we need to reset the + * global texture LRU. + */ + if ( nr == R128_NR_TEX_REGIONS ) { + r128TexturesGone( r128ctx, heap, 0, + r128ctx->r128Screen->texSize[heap], 0 ); + r128ResetGlobalLRU( r128ctx, heap ); + } + + if ( 0 ) { + r128PrintGlobalLRU( r128ctx, heap ); + r128PrintLocalLRU( r128ctx, heap ); + } + + r128ctx->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_TEX0IMAGES | + R128_UPLOAD_TEX1IMAGES); + r128ctx->lastTexAge[heap] = sarea->texAge[heap]; + } } /* Convert a block of Mesa-formatted texture to an 8bpp hardware format */ -static void r128ConvertTexture8bpp(r128ContextPtr r128ctx, - struct gl_texture_image *image, - int x, int y, int width, int height, - int pitch) +static void r128ConvertTexture8bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) { - CARD8 *src; - CARD32 pix; - 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--) { - pix = ((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)); - R128CCE(pix); - src += 12; - } - } - break; - - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_COLOR_INDEX: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width >> 2; j; j--) { - pix = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); - R128CCE(pix); - src += 4; - } - } - break; - - default: - fprintf(stderr, "r128ConvertTexture8bpp: unsupported format 0x%x\n", - image->Format); - } + CARD8 *src; + 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: + 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; + } + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } } /* Convert a block of Mesa-formatted texture to a 16bpp hardware format */ -static void r128ConvertTexture16bpp(r128ContextPtr r128ctx, - struct gl_texture_image *image, - int x, int y, int width, int height, - int pitch) +static void r128ConvertTexture16bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) { - CARD8 *src; - CARD32 pix; - 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 >> 1; j; j--) { - pix = ((R128PACKCOLOR565(src[0], src[1], src[2]) ) | - (R128PACKCOLOR565(src[3], src[4], src[5]) << 16)); - R128CCE(pix); - src += 6; - } - } - break; - - case GL_RGBA: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; - for (j = width >> 1; j; j--) { - pix = - ((R128PACKCOLOR4444(src[0], src[1], src[2], src[3]) ) | - (R128PACKCOLOR4444(src[4], src[5], src[6], src[7])<<16)); - R128CCE(pix); - src += 8; - } - } - break; - - case GL_ALPHA: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width >> 1; j; j--) { - pix = ((R128PACKCOLOR4444(0xff, 0xff, 0xff, src[0]) ) | - (R128PACKCOLOR4444(0xff, 0xff, 0xff, src[1]) << 16)); - R128CCE(pix); - src += 2; - } - } - break; - - case GL_LUMINANCE: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width >> 1; j; j--) { - pix = ((R128PACKCOLOR1555(src[0], src[0], src[0], 0xff) ) | - (R128PACKCOLOR1555(src[1], src[1], src[1], 0xff)<<16)); - R128CCE(pix); - src += 2; - } - } - 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--) { - pix = - ((R128PACKCOLOR4444(src[0], src[0], src[0], src[1]) ) | - (R128PACKCOLOR4444(src[2], src[2], src[2], src[3])<<16)); - R128CCE(pix); - src += 4; - } - } - break; - - case GL_INTENSITY: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width >> 1; j; j--) { - pix = - ((R128PACKCOLOR4444(src[0], src[0], src[0], src[0]) ) | - (R128PACKCOLOR4444(src[1], src[1], src[1], src[1])<<16)); - R128CCE(pix); - src += 2; - } - } - break; - - default: - fprintf(stderr, "r128ConvertTexture16bpp: unsupported format 0x%x\n", - image->Format); - } + CARD8 *src; + int i, j; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s: %d,%d at %d,%d\n", + __FUNCTION__, width, height, x, y ); + } + + + 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; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((R128PACKCOLOR4444( src[0], src[1], src[2], src[3] )) | + (R128PACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16)); + src += 8; + } + } + 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++ = ((R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) | + (R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16)); + src += 2; + } + } + 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++ = ((R128PACKCOLOR1555( src[0], src[0], src[0], 0xff )) | + (R128PACKCOLOR1555( src[1], src[1], src[1], 0xff ) << 16)); + src += 2; + } + } + 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++ = ((R128PACKCOLOR4444( src[0], src[0], src[0], src[1] )) | + (R128PACKCOLOR4444( src[2], src[2], src[2], src[3] ) << 16)); + src += 4; + } + } + 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 ); + break; + } } /* Convert a block of Mesa-formatted texture to a 32bpp hardware format */ -static void r128ConvertTexture32bpp(r128ContextPtr r128ctx, - struct gl_texture_image *image, - int x, int y, int width, int height, - int pitch) +static void r128ConvertTexture32bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) { - CARD8 *src; - CARD32 pix; - 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--) { - pix = R128PACKCOLOR8888(src[0], src[1], src[2], 0xff); - R128CCE(pix); - src += 3; - } - } - break; - - case GL_RGBA: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; - for (j = width; j; j--) { - pix = R128PACKCOLOR8888(src[0], src[1], src[2], src[3]); - R128CCE(pix); - src += 4; - } - } - break; - - case GL_ALPHA: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width; j; j--) { - pix = R128PACKCOLOR8888(0xff, 0xff, 0xff, src[0]); - R128CCE(pix); - src += 1; - } - } - break; - - case GL_LUMINANCE: - for (i = 0 ; i < height ; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width; j; j--) { - pix = R128PACKCOLOR8888(src[0], src[0], src[0], 0xff); - R128CCE(pix); - src += 1; - } - } - break; - - case GL_LUMINANCE_ALPHA: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; - for (j = width; j; j-- ) { - pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[1]); - R128CCE(pix); - src += 2; - } - } - break; - - case GL_INTENSITY: - for (i = 0; i < height; i++) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for (j = width; j; j--) { - pix = R128PACKCOLOR8888(src[0], src[0], src[0], src[0]); - R128CCE(pix); - src += 1; - } - } - break; - - default: - fprintf(stderr, "r128ConvertTexture32bpp: unsupported format 0x%x\n", - image->Format); - } + CARD8 *src; + 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; + for ( j = width ; j ; j-- ) { + *dst++ = R128PACKCOLOR8888( src[0], src[1], src[2], src[3] ); + src += 4; + } + } + break; + + case GL_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width ; j ; j-- ) { + *dst++ = R128PACKCOLOR8888( 0xff, 0xff, 0xff, src[0] ); + src += 1; + } + } + break; + + case GL_LUMINANCE: + 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 ); + src += 1; + } + } + break; + + case GL_LUMINANCE_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for ( j = width ; j ; j-- ) { + *dst++ = R128PACKCOLOR8888( src[0], src[0], src[0], src[1] ); + src += 2; + } + } + 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 ); + break; + } } /* 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, - r128TexObjPtr t, int level, - int x, int y, int width, int height) +static void r128UploadSubImage( r128ContextPtr r128ctx, + r128TexObjPtr t, int level, + int x, int y, int width, int height ) { - struct gl_texture_image *image; - int texelsPerDword = 0; - int imageWidth, imageHeight; - int remaining, rows; - int format, pitch, dwords; - CARD32 offset; - - /* Ensure we have a valid texture to upload */ - if (level < 0 || level > R128_TEX_MAXLEVELS) return; - if (!(image = t->tObj->Image[level])) return; - - /* FIXME: support RGB888 (i.e., 24bpp) textures? */ - switch (t->texelBytes) { - case 1: texelsPerDword = 4; break; - case 2: texelsPerDword = 2; break; - case 4: texelsPerDword = 1; break; - } - - /* FIXME: The sub image offset calcs are broken - they weren't a - * while ago? - */ - x = 0; - y = 0; - width = image->Width; - height = image->Height; - - imageWidth = image->Width; - imageHeight = image->Height; - - format = t->textureFormat >> 16; - - /* The texel upload routines have a minimum width, so force the size - if needed */ - if (imageWidth < texelsPerDword) { - int factor; - - factor = texelsPerDword / imageWidth; - imageWidth = texelsPerDword; - imageHeight /= factor; - if (imageHeight == 0) { - /* In this case, the texel converter will actually walk a - texel or two off the end of the image, but normal malloc - alignment should prevent it from ever causing a fault. */ - imageHeight = 1; - } - } - - /* We can't upload to a pitch less than 8 texels so we will need to - linearly upload all modified rows for textures smaller than this. - This makes the x/y/width/height different for the blitter and the - texture walker. */ - if (imageWidth >= 8) { - /* The texture walker and the blitter look identical */ - pitch = imageWidth >> 3; - } else { - int factor; - int y2; - int start, end; - - start = (y * imageWidth) & ~7; - end = (y + height) * imageWidth; - - if (end - start < 8) { - /* Handle the case where the total number of texels uploaded - is < 8 */ - x = 0; - y = start / 8; - width = end - start; - height = 1; - } else { - /* Upload some number of full 8 texel blit rows */ - factor = 8 / imageWidth; - - y2 = y + height - 1; - y /= factor; - y2 /= factor; - - x = 0; - width = 8; - height = y2 - y + 1; - } - - /* Fixed pitch of 8 */ - pitch = 1; - } - - dwords = width * height / texelsPerDword; - offset = t->bufAddr + t->image[level].offset; - -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - r128ctx->c_textureBytes += (dwords << 2); + struct gl_texture_image *image; + int texelsPerDword = 0; + int imageWidth, imageHeight; + int remaining, rows; + int format, dwords; + CARD32 pitch, offset; + drmBufPtr buffer; + CARD32 *dst; + int i; + + /* Ensure we have a valid texture to upload */ + if ( ( level < 0 ) || ( level > R128_TEX_MAXLEVELS ) ) + 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; + } + +#if 1 + /* FIXME: The subimage index calcs are wrong - who changed them? */ + x = 0; + y = 0; + width = image->Width; + height = image->Height; #endif - /* Fix offset for AGP textures */ - if (t->heap == R128_AGP_TEX_HEAP) - offset += R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; - - if (R128_DEBUG_FLAGS & 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%08x pitch: 0x%x dwords: %d " - "level: %d format: %x\n", - (int)offset, pitch, dwords, level, format); - } - - /* Subdivide the texture if required */ - if (dwords < R128_CCE_PACKET_MAX_DWORDS) { - rows = height; - } else { - rows = (R128_CCE_PACKET_MAX_DWORDS * texelsPerDword) / (2 * width); - } - - /* Flush the pixel cache, and mark the contents as Read Invalid */ - R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0); - R128CCE(r128ctx->regs.pc_gui_ctlstat | - R128_PC_RI_GUI | - R128_PC_FLUSH_GUI); - R128CCE_SUBMIT_PACKET(); - - /* Build the CCE host data blit header */ - R128CCE3(R128_CCE_PACKET3_CNTL_HOSTDATA_BLT, 0); - - /* DP_GUI_MASTER_CNTL */ - R128CCE(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (format << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_HOST_DATA | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | - R128_GMC_WR_MSK_DIS ); - - /* DST_OFFSET_PITCH - fixed at the moment until we get better ring - control */ - R128CCE((pitch << 21) | (offset>>5)); - - /* FRGD_COLOR, BKGD_COLOR */ - R128CCE(0xffffffff); - R128CCE(0xffffffff); - - for (remaining = height; remaining > 0; remaining -= rows, y += rows) { - height = (remaining >= rows) ? rows : remaining; - dwords = width * height / texelsPerDword; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) { - fprintf(stderr, " blitting: %d,%d at %d,%d - %d dwords\n", - width, height, x, y, dwords); - } - - r128ctx->CCEbuf[0] &= ~R128_CCE_PACKET_COUNT_MASK; - r128ctx->CCEbuf[0] |= (dwords + 6) << 16; - - /* Blit coords, size */ - R128CCE((y << 16) | x); - R128CCE((height << 16) | width); - R128CCE(dwords); - - /* Actually do the texture conversion */ - switch (t->texelBytes) { - case 1: - r128ConvertTexture8bpp(r128ctx, image, - x, y, width, height, width); - break; - case 2: - r128ConvertTexture16bpp(r128ctx, image, - x, y, width, height, width); - break; - case 4: - r128ConvertTexture32bpp(r128ctx, - image, x, y, width, height, width); - break; - } + imageWidth = image->Width; + imageHeight = image->Height; + + format = t->textureFormat >> 16; + + /* The texel upload routines have a minimum width, so force the size + * if needed. + */ + if ( imageWidth < texelsPerDword ) { + int factor; + + factor = texelsPerDword / imageWidth; + imageWidth = texelsPerDword; + imageHeight /= factor; + if ( imageHeight == 0 ) { + /* In this case, the texel converter will actually walk a + * texel or two off the end of the image, but normal malloc + * alignment should prevent it from ever causing a fault. + */ + imageHeight = 1; + } + } + + /* We can't upload to a pitch less than 8 texels so we will need to + * linearly upload all modified rows for textures smaller than this. + * This makes the x/y/width/height different for the blitter and the + * texture walker. + */ + if ( imageWidth >= 8 ) { + /* The texture walker and the blitter look identical */ + pitch = imageWidth >> 3; + } else { + int factor; + int y2; + int start, end; + + start = (y * imageWidth) & ~7; + end = (y + height) * imageWidth; + + if ( end - start < 8 ) { + /* Handle the case where the total number of texels + * uploaded is < 8. + */ + x = 0; + y = start / 8; + width = end - start; + height = 1; + } else { + /* Upload some number of full 8 texel blit rows */ + factor = 8 / imageWidth; + + y2 = y + height - 1; + y /= factor; + y2 /= factor; + + x = 0; + width = 8; + height = y2 - y + 1; + } + + /* Fixed pitch of 8 */ + pitch = 1; + } + + 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; + } - /* Flush the pixel cache */ - R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0 ); - R128CCE(r128ctx->regs.pc_gui_ctlstat | R128_PC_FLUSH_GUI); +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + r128ctx->c_textureBytes += (dwords << 2); +#endif - /* Save the partial blit header */ - R128CCE_SUBMIT_PACKET(); - r128ctx->CCEcount = 5; - } - /* Clean up CCE ring buffer */ - r128ctx->CCEcount = 0; + 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 ); + } + + /* Subdivide the texture if required */ + if ( dwords <= R128_BUFFER_MAX_DWORDS / 2 ) { + rows = height; + } else { + rows = (R128_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * width); + } + + for ( i = 0, remaining = height ; + remaining > 0 ; + remaining -= rows, y += rows, i++ ) + { + height = (remaining >= rows) ? rows : remaining; + dwords = width * height / texelsPerDword; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, " blitting: %d,%d at %d,%d - %d dwords\n", + width, height, x, y, dwords ); + } + + /* Grab the indirect buffer for the texture blit */ + buffer = r128GetBufferLocked( r128ctx ); + + dst = (CARD32 *)((char *)buffer->address + R128_HOSTDATA_BLIT_OFFSET); + + /* Actually do the texture conversion */ + switch ( t->texelBytes ) { + case 1: + r128ConvertTexture8bpp( dst, image, + x, y, width, height, width ); + break; + case 2: + r128ConvertTexture16bpp( dst, image, + x, y, width, height, width ); + break; + case 4: + r128ConvertTexture32bpp( dst, image, + x, y, width, height, width ); + break; + } + + r128FireBlitLocked( r128ctx, buffer, + offset, pitch, format, + x, y, width, height ); + } + + r128ctx->new_state |= R128_NEW_CONTEXT; + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_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. */ + * 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 r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t) +int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) { - int i; - int minLevel; - int maxLevel; - int heap; - - 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; - - /* 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); - - /* 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], - t->totalSize, 12, 0); - - if (t->memBlock) heap = t->heap = R128_AGP_TEX_HEAP; - } - - /* Kick out textures until the requested texture fits */ - while (!t->memBlock) { - if (r128ctx->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) { - 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; - continue; - } else { - fprintf(stderr, "r128UploadTexImages: upload texture " - "failure on both local and AGP texture heaps, " - "sz=%d\n", - t->totalSize); - return -1; - } - } - - r128DestroyTexObj(r128ctx, r128ctx->TexObjList[heap].prev); - - t->memBlock = mmAllocMem(r128ctx->texHeap[heap], - t->totalSize, 12, 0); - } - - /* Set the base offset of the texture image */ - t->bufAddr = r128ctx->r128Screen->texOffset[heap] + t->memBlock->ofs; - - maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> - R128_TEX_SIZE_SHIFT); - minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> - R128_TEX_MIN_SIZE_SHIFT); - - /* Update the hardware's texture image addresses */ - switch (t->bound) { - case 1: - /* Set texture offsets */ - if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.prim_tex_offset[i] = t->bufAddr; - } else { - for (i = maxLevel; i >= minLevel; i--) - r128ctx->regs.prim_tex_offset[i] = - 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++) - r128ctx->regs.prim_tex_offset[i] += - R128_AGP_TEX_OFFSET + - r128ctx->r128Screen->agpTexOffset; - /* Force loading the new state into the hardware */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_TEX0STATE; - break; - - case 2: - /* Set texture offsets */ - if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.sec_tex_offset[i] = t->bufAddr; - } else { - for (i = maxLevel; i >= minLevel; i--) - r128ctx->regs.sec_tex_offset[i] = - 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++) - r128ctx->regs.sec_tex_offset[i] += - R128_AGP_TEX_OFFSET + - r128ctx->r128Screen->agpTexOffset; - /* Force loading the new state into the hardware */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_TEX1STATE; - break; - - default: + int i; + int minLevel; + int maxLevel; + int heap; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %p )\n", + __FUNCTION__, r128ctx->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; + } + + /* 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 ); + + /* 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], + t->totalSize, 12, 0 ); + + if ( t->memBlock ) + heap = t->heap = R128_AGP_TEX_HEAP; + } + + /* Kick out textures until the requested texture fits */ + while ( !t->memBlock ) { + if ( r128ctx->TexObjList[heap].prev->bound ) { + fprintf( stderr, + "r128UploadTexImages: ran into bound texture\n" ); return -1; - } - } - - /* Let the world know we've used this memory recently */ - r128UpdateTexLRU(r128ctx, t); - - /* Upload any images that are new */ - if (t->dirty_images) { - int num_levels = (((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> - R128_TEX_SIZE_SHIFT) - - ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> - R128_TEX_MIN_SIZE_SHIFT)); - - for (i = 0; i <= num_levels; i++) { - if (t->dirty_images & (1<<i)) { - r128UploadSubImage(r128ctx, t, i, 0, 0, - t->image[i].width, t->image[i].height); + } + if ( r128ctx->TexObjList[heap].prev == &r128ctx->TexObjList[heap] ) { + if ( r128ctx->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; + continue; + } else { + fprintf( stderr, "r128UploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize ); + return -1; } - } - - r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + } + + r128DestroyTexObj( r128ctx, r128ctx->TexObjList[heap].prev ); + + t->memBlock = mmAllocMem( r128ctx->texHeap[heap], + t->totalSize, 12, 0 ); + } + + /* Set the base offset of the texture image */ + t->bufAddr = r128ctx->r128Screen->texOffset[heap] + t->memBlock->ofs; + + maxLevel = ((t->setup.tex_size_pitch & R128_TEX_SIZE_MASK) >> + R128_TEX_SIZE_SHIFT); + minLevel = ((t->setup.tex_size_pitch & R128_TEX_MIN_SIZE_MASK) >> + R128_TEX_MIN_SIZE_SHIFT); + + /* Set texture offsets */ + if ( t->setup.tex_cntl & R128_MIP_MAP_DISABLE ) { + for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + t->setup.tex_offset[i] = t->bufAddr; + } + } else { + for ( i = maxLevel ; i >= minLevel ; i-- ) { + t->setup.tex_offset[i] = + (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; + break; + + case 2: + r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX1; + break; + + default: + return -1; + } + } + + /* Let the world know we've used this memory recently */ + r128UpdateTexLRU( r128ctx, t ); + + /* Upload any images that are new */ + if ( t->dirty_images ) { + int num_levels = (((t->setup.tex_size_pitch & R128_TEX_SIZE_MASK) >> + R128_TEX_SIZE_SHIFT) - + ((t->setup.tex_size_pitch & R128_TEX_MIN_SIZE_MASK) >> + R128_TEX_MIN_SIZE_SHIFT)); + + for ( i = 0 ; i <= num_levels ; i++ ) { + if ( t->dirty_images & (1 << i) ) { + r128UploadSubImage( r128ctx, t, i, 0, 0, + t->image[i].width, t->image[i].height ); + } + } + + r128ctx->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + + r128ctx->dirty |= R128_UPLOAD_CONTEXT; + } + + t->dirty_images = 0; + return 0; +} - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_ENGINESTATE; - } - t->dirty_images = 0; - return 0; -} +/* + * Texture combiners: + */ -/* Update the hardware state for texture unit 0 */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UpdateTex0State(r128ContextPtr r128ctx) +#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 ) { - GLcontext *ctx = r128ctx->glCtx; - r128TexObjPtr t; - struct gl_texture_object *tObj; - int i; - CARD32 tex_size_pitch, tex_combine_cntl; - - /* Only update the hardware texture state if the texture is current, - complete and enabled. */ - if (!(tObj = ctx->Texture.Unit[0].Current)) return; - if ((tObj != ctx->Texture.Unit[0].CurrentD[2]) && - (tObj != ctx->Texture.Unit[0].CurrentD[1])) return; - if (!tObj->Complete) return; - - /* If neither tex0 nor tex1 is enabled, then disable tex0. However, - if tex1 is enabled but tex0 is disabled, then we need to enable - tex0 and have it to copy the input (see how tex_combine_cntl is - setup below). */ - if (!(ctx->Texture.ReallyEnabled & (ENABLE_TEX0 | ENABLE_TEX1))) { - r128ctx->regs.tex_cntl_c &= ~R128_TEXMAP_ENABLE; - return; - } - - r128ctx->regs.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; - - /* If this is the first time the texture has been used, then create - a new texture object for it. */ - t = tObj->DriverData; - if (!t) t = r128CreateTexObj(r128ctx, tObj); - if (!t) return; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) - fprintf(stderr, "r128UpdateTex0State(%p, 0x%08x)\n", - tObj, (int)t->dirty_images); - - /* Force any texture images to be loaded into the hardware */ - if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX0IMAGES; - - /* Bind texture to texture 0 unit */ - r128ctx->CurrentTexObj[0] = t; - t->bound = 1; - - if (t->memBlock) r128UpdateTexLRU(r128ctx, t); - - /* Set the texture environment state */ - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_REPLACE: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - tex_combine_cntl = (R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_DIS | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case GL_RGB: - case GL_LUMINANCE: - tex_combine_cntl = (R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + int source = r128ctx->tmu_source[unit]; + struct gl_texture_object *tObj; + r128TexObjPtr t; + GLuint enabled; + CARD32 combine; + + if ( R128_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. + */ + 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; + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + if ( unit == 0 ) { + combine = INPUT_INTERP; + } else { + combine = INPUT_PREVIOUS; + } + + /* Set the texture environment state */ + switch ( ctx->Texture.Unit[source].EnvMode ) { + case GL_REPLACE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_DISABLE | /* C = Ct */ + ALPHA_COMB_DISABLE); /* A = At */ + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_DISABLE | /* C = Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_DISABLE); /* A = At */ + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_MODULATE | /* C = CfCt */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_MODULATE | /* C = CfCt */ + 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_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + combine |= (COLOR_COMB_BLEND_TEX | /* C = Cf(1-At)+CtAt */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + case GL_RGB: + combine |= (COLOR_COMB_DISABLE | /* C = Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + /* Undefined behaviour - just copy the incoming fragment */ + combine |= (COLOR_COMB_COPY_INPUT | /* C = undefined */ + ALPHA_COMB_COPY_INPUT); /* A = undefined */ + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + /* Catch the cases of GL_BLEND we can't handle (yet, in some cases). + */ + if ( r128ctx->blend_flags ) { + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + } + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + switch ( r128ctx->env_color ) { + case 0x00000000: + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE); /* A = AfAt */ break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_DIS | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_BLEND: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - switch (r128ctx->regs.constant_color_c & - R128_CONSTANT_COLOR_MASK) { - case R128_CONSTANT_COLOR_ZERO: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_NTEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case R128_CONSTANT_COLOR_ONE: - default: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; - break; + case 0xffffffff: + if ( unit == 0 ) { + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + } else { + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ } break; - case GL_RGB: - case GL_LUMINANCE: - switch (r128ctx->regs.constant_color_c & - R128_CONSTANT_COLOR_MASK) { - case R128_CONSTANT_COLOR_ZERO: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_NTEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case R128_CONSTANT_COLOR_ONE: - default: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; - break; - } + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + } + break; + case GL_RGB: + case GL_LUMINANCE: + switch ( r128ctx->env_color ) { + case 0x00000000: + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ break; - case GL_INTENSITY: - switch (r128ctx->regs.constant_color_c & - R128_CONSTANT_COLOR_MASK) { - case R128_CONSTANT_COLOR_ZERO: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_NTEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_NTEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case R128_CONSTANT_COLOR_ONE: - default: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; - break; + case 0xffffffff: + if ( unit == 0 ) { + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } else { + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ } break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_MODULATE: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case GL_RGB: - case GL_LUMINANCE: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_COPY_INPUT); /* A = fallback */ + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + } + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + case GL_INTENSITY: + switch ( r128ctx->env_color ) { + case 0x00000000: + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_DECAL: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - tex_combine_cntl = (R128_COMB_BLEND_TEXTURE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case GL_RGB: - tex_combine_cntl = (R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - /* Undefined behaviour - just copy the input */ - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_ADD: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - tex_combine_cntl = (R128_COMB_ADD | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + case 0x00ffffff: + if ( unit == 0 ) { + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + } else { + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } break; - case GL_RGB: - case GL_LUMINANCE: - tex_combine_cntl = (R128_COMB_ADD | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + case 0xffffffff: + if ( unit == 0 ) { + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + } else { + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_ADD); /* A = Af+At */ + } break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - default: - return; - } - - /* If tex0 is disabled, then make sure it just copies the input */ - if (!(ctx->Texture.ReallyEnabled & ENABLE_TEX0)) - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_INT_ALPHA); - - /* Enable tex0 */ - r128ctx->regs.tex_cntl_c |= R128_TEXMAP_ENABLE; - - tex_size_pitch = r128ctx->regs.tex_size_pitch_c; - tex_size_pitch &= ~R128_TEX_SIZE_PITCH_MASK; - tex_size_pitch |= t->regs.size_pitch << R128_TEX_SIZE_PITCH_SHIFT; - - /* Set the primary texture state in r128ctx->regs */ - r128ctx->regs.prim_tex_cntl_c = t->regs.tex_cntl; - r128ctx->regs.prim_texture_combine_cntl_c = tex_combine_cntl; - r128ctx->regs.tex_size_pitch_c = tex_size_pitch; - r128ctx->regs.prim_texture_border_color_c = t->regs.border_color; - - /* Set texture offsets */ - if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.prim_tex_offset[i] = t->bufAddr; - } else { - int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> - R128_TEX_SIZE_SHIFT); - int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> - R128_TEX_MIN_SIZE_SHIFT); - for (i = maxLevel; i >= minLevel; i--) - r128ctx->regs.prim_tex_offset[i] = - t->image[maxLevel-i].offset + t->bufAddr; - } - /* Fix AGP texture offsets */ - if (t->heap == R128_AGP_TEX_HEAP) - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.prim_tex_offset[i] += - R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; - - /* Force loading the new state into the hardware */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_TEX0STATE | R128_CTX_ENGINESTATE; + } + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + 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; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + 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_COLOR_INDEX: + default: + return; + } + break; + + default: + return; + } + + t->setup.tex_combine_cntl = combine; } -/* Update the hardware state for texture unit 1 */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UpdateTex1State(r128ContextPtr r128ctx) +static void r128UpdateTextureObject( GLcontext *ctx, int unit ) { - GLcontext *ctx = r128ctx->glCtx; - r128TexObjPtr t; - struct gl_texture_object *tObj; - int i; - CARD32 tex_size_pitch, tex_combine_cntl, tex_cntl; - - /* Only update the hardware texture state if the texture is current, - complete and enabled. */ - if (!(tObj = ctx->Texture.Unit[1].Current)) return; - if ((tObj != ctx->Texture.Unit[1].CurrentD[2]) && - (tObj != ctx->Texture.Unit[1].CurrentD[1])) return; - if (!tObj->Complete) return; - - /* If tex1 is not enabled, then disable it */ - if (!(ctx->Texture.ReallyEnabled & ENABLE_TEX1)) { - r128ctx->regs.tex_cntl_c &= ~R128_SEC_TEXMAP_ENABLE; - return; - } - - /* If te1 is enabled, split the texel cache */ - r128ctx->regs.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; - - /* If this is the first time the texture has been used, then create - a new texture object for it. */ - t = tObj->DriverData; - if (!t) t = r128CreateTexObj(r128ctx, tObj); - if (!t) return; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) - fprintf(stderr, "r128UpdateTex1State(%p, 0x%08x)\n", - tObj, (int)t->dirty_images); - - /* Force any texture images to be loaded into the hardware */ - if (t->dirty_images) r128ctx->dirty |= R128_UPDATE_TEX1IMAGES; - - /* Bind texture to texture 1 unit */ - r128ctx->CurrentTexObj[1] = t; - t->bound = 2; - - if (t->memBlock) r128UpdateTexLRU(r128ctx, t); - - /* Set the texture environment state */ - switch (ctx->Texture.Unit[1].EnvMode) { - case GL_REPLACE: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - tex_combine_cntl = (R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_DIS | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_RGB: - case GL_LUMINANCE: - tex_combine_cntl = (R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_DIS | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_BLEND: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - switch ( r128ctx->regs.constant_color_c & R128_CONSTANT_COLOR_MASK ) { - case R128_CONSTANT_COLOR_ZERO: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_NTEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case R128_CONSTANT_COLOR_ONE: - default: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; - break; - } - break; - case GL_RGB: - case GL_LUMINANCE: - switch (r128ctx->regs.constant_color_c & - R128_CONSTANT_COLOR_MASK) { - case R128_CONSTANT_COLOR_ZERO: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_NTEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA ); - break; - case R128_CONSTANT_COLOR_ONE: - default: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA ); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; - break; - } - break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_INTENSITY: - switch (r128ctx->regs.constant_color_c & - R128_CONSTANT_COLOR_MASK) { - case R128_CONSTANT_COLOR_ZERO: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_NTEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_NTEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case R128_CONSTANT_COLOR_ONE: - default: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; - break; - } - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_MODULATE: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_RGB: - case GL_LUMINANCE: - tex_combine_cntl = (R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_DECAL: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - tex_combine_cntl = (R128_COMB_BLEND_TEXTURE | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_RGB: - tex_combine_cntl = (R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - /* Undefined behaviour - just copy the input */ - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - case GL_ADD: - switch (tObj->Image[0]->Format) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - tex_combine_cntl = (R128_COMB_ADD | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_RGB: - case GL_LUMINANCE: - tex_combine_cntl = (R128_COMB_ADD | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_COPY_INP | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_ALPHA: - tex_combine_cntl = (R128_COMB_COPY_INP | - R128_COLOR_FACTOR_TEX | - R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_MODULATE | - R128_ALPHA_FACTOR_TEX_ALPHA | - R128_INP_FACTOR_A_PREV_ALPHA); - break; - case GL_COLOR_INDEX: - default: - return; - } - break; - - default: - return; - } - - /* Enable tex1 */ - r128ctx->regs.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE; - - tex_size_pitch = r128ctx->regs.tex_size_pitch_c; - tex_size_pitch &= ~R128_SEC_TEX_SIZE_PITCH_MASK; - tex_size_pitch |= t->regs.size_pitch << R128_SEC_TEX_SIZE_PITCH_SHIFT; - - tex_cntl = t->regs.tex_cntl | R128_SEC_SELECT_SEC_ST; - - /* Set the secondary texture state in r128ctx->regs */ - r128ctx->regs.sec_tex_cntl_c = tex_cntl; - r128ctx->regs.sec_tex_combine_cntl_c = tex_combine_cntl; - r128ctx->regs.tex_size_pitch_c = tex_size_pitch; - r128ctx->regs.sec_texture_border_color_c = t->regs.border_color; - - /* Set texture offsets */ - if (t->regs.tex_cntl & R128_MIP_MAP_DISABLE) { - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.sec_tex_offset[i] = t->bufAddr; - } else { - int maxLevel = ((t->regs.size_pitch & R128_TEX_SIZE_MASK) >> - R128_TEX_SIZE_SHIFT); - int minLevel = ((t->regs.size_pitch & R128_TEX_MIN_SIZE_MASK) >> - R128_TEX_MIN_SIZE_SHIFT); - for (i = maxLevel; i >= minLevel; i--) - r128ctx->regs.sec_tex_offset[i] = - t->image[maxLevel-i].offset + t->bufAddr; - } - /* Fix AGP texture offsets */ - if (t->heap == R128_AGP_TEX_HEAP) - for (i = 0; i < R128_TEX_MAXLEVELS; i++) - r128ctx->regs.sec_tex_offset[i] += - R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; - - /* Force loading the new state into the hardware */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_TEX1STATE | R128_CTX_ENGINESTATE; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + int source = r128ctx->tmu_source[unit]; + struct gl_texture_object *tObj; + r128TexObjPtr t; + GLuint enabled; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d ) really=0x%x\n", + __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; + 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 ) { + r128ctx->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; + return; + } + + if ( !tObj->DriverData ) { + /* If this is the first time the texture has been used, then create + * a new texture object for it. + */ + r128CreateTexObj( r128ctx, tObj ); + + if ( !tObj->DriverData ) { + /* Can't create a texture object... */ + fprintf( stderr, "%s: texture object creation failed!\n", + __FUNCTION__ ); + r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + return; + } + } + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + /* Force the texture unit state to be loaded into the hardware */ + r128ctx->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); + + /* Bind to the given texture unit */ + r128ctx->CurrentTexObj[unit] = t; + t->bound = unit + 1; + + if ( t->memBlock ) + r128UpdateTexLRU( r128ctx, 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; + + 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; + } } /* Update the hardware texture state */ -/* NOTE: This function is only called while holding the hardware lock */ -void r128UpdateTextureState(r128ContextPtr r128ctx) +void r128UpdateTextureState( GLcontext *ctx ) { - /* Clear the GL_BLEND texturing fallback */ - r128ctx->Fallback &= ~R128_FALLBACK_TEXTURE; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) en=0x%x\n", + __FUNCTION__, ctx, ctx->Texture.ReallyEnabled ); + } + + /* Clear any texturing fallbacks */ + r128ctx->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; + 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; + + r128ctx->setup.tex_size_pitch_c = 0x00000000; + + r128UpdateTextureObject( ctx, 0 ); + r128UpdateTextureStage( ctx, 0 ); - if (r128ctx->glCtx->Enabled & (TEXTURE0_3D|TEXTURE1_3D)) - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + if ( r128ctx->multitex ) { + r128UpdateTextureObject( ctx, 1 ); + r128UpdateTextureStage( ctx, 1 ); + } - /* Update the texture unit 0/1 state */ - r128UpdateTex0State(r128ctx); - r128UpdateTex1State(r128ctx); + r128ctx->dirty |= R128_UPLOAD_CONTEXT; } + /* Set the texture wrap mode */ -static void r128SetTexWrap(r128TexObjPtr t, GLenum swrap, GLenum twrap) +static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) { - t->regs.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK); - - switch (swrap) { - case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; break; - case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_S_WRAP; break; - default: /* ERROR!! */ return; - } - - switch (twrap) { - case GL_CLAMP: t->regs.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; break; - case GL_REPEAT: t->regs.tex_cntl |= R128_TEX_CLAMP_T_WRAP; break; - default: /* ERROR!! */ return; - } + 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) +static void r128SetTexFilter( r128TexObjPtr t, GLenum minf, GLenum magf ) { - t->regs.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK); - - switch (minf) { - case GL_NEAREST: - t->regs.tex_cntl |= R128_MIN_BLEND_NEAREST; - break; - case GL_LINEAR: - t->regs.tex_cntl |= R128_MIN_BLEND_LINEAR; - break; - case GL_NEAREST_MIPMAP_NEAREST: - t->regs.tex_cntl |= R128_MIN_BLEND_MIPNEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - t->regs.tex_cntl |= R128_MIN_BLEND_MIPLINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - t->regs.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR; - break; - default: /* ERROR!! */ return; - } - - switch (magf) { - case GL_NEAREST: - t->regs.tex_cntl |= R128_MAG_BLEND_NEAREST; - break; - case GL_LINEAR: - t->regs.tex_cntl |= R128_MAG_BLEND_LINEAR; - break; - } + 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]) +static void r128SetTexBorderColor( r128TexObjPtr t, GLubyte c[4] ) { - t->regs.border_color = r128PackColor(32, c[0], c[1], c[2], c[3]); + t->setup.tex_border_color = r128PackColor( 32, c[0], c[1], c[2], c[3] ); } + +/* +============================================================================ + +Driver functions called directly from mesa + +============================================================================ +*/ + + /* Set the texture environment state */ -static void r128DDTexEnv(GLcontext *ctx, GLenum target, GLenum pname, - const GLfloat *param) +static void r128DDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - struct gl_texture_unit *texUnit; - GLubyte c[4]; - CARD32 col; - - /* FIXME: Add texture LOD bias extension */ - - switch (pname) { - case GL_TEXTURE_ENV_MODE: - /* TexEnv modes are handled in UpdateTextureState */ - FLUSH_BATCH(r128ctx); - r128ctx->dirty |= R128_UPDATE_TEXSTATE; - break; - case GL_TEXTURE_ENV_COLOR: - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - FLOAT_RGBA_TO_UBYTE_RGBA(texUnit->EnvColor, c); - col = r128PackColor(32, c[0], c[1], c[2], c[3]); - if (r128ctx->regs.constant_color_c != col) { - FLUSH_BATCH(r128ctx); - r128ctx->regs.constant_color_c = col; - - r128ctx->dirty |= R128_UPDATE_CONTEXT; - r128ctx->dirty_context |= R128_CTX_TEXENVSTATE; - } - break; - default: - return; - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + struct gl_texture_unit *texUnit; + GLubyte c[4]; + int bias; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + 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; + 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; + + r128ctx->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). + */ + 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; + } + } + 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; + + r128ctx->new_state |= R128_NEW_RENDER; + } + break; + + default: + return; + } } /* 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) +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 ); + 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; + + t = (r128TexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( r128ctx ); + + /* 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; + } +} + +/* Upload a new texture sub-image */ +static void r128DDTexSubImage( 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 ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128TexObjPtr t; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128TexObjPtr t; - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) - fprintf(stderr, "r128DDTexImage(%p, level %d)\n", tObj, level); + if ( R128_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 >= R128_TEX_MAXLEVELS) return; + if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; + if ( level >= R128_TEX_MAXLEVELS ) return; - t = (r128TexObjPtr)tObj->DriverData; - if (t) { - if (t->bound) FLUSH_BATCH(r128ctx); + t = (r128TexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( r128ctx ); - /* 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->dirty |= R128_UPDATE_TEXSTATE; - } -} + LOCK_HARDWARE( r128ctx ); + r128UploadSubImage( r128ctx, t, level, + xoffset, yoffset, width, height ); + UNLOCK_HARDWARE( r128ctx ); -/* Upload a new texture sub-image */ -static void r128DDTexSubImage(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) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128TexObjPtr t; - - if (R128_DEBUG_FLAGS & DEBUG_VERBOSE_API) - fprintf(stderr, "r128DDTexSubImage(%p, level %d) " - "size: %d,%d of %d,%d\n", - tObj, level, width, height, image->Width, image->Height); - - if ((target != GL_TEXTURE_2D) && (target != GL_TEXTURE_1D)) return; - if (level >= R128_TEX_MAXLEVELS) return; - - t = (r128TexObjPtr)tObj->DriverData; - if (t) { - if (t->bound) FLUSH_BATCH(r128ctx); - - LOCK_HARDWARE(r128ctx); - r128UploadSubImage(r128ctx, t, level, - xoffset, yoffset, width, height); - UNLOCK_HARDWARE(r128ctx); - - /* Update the context state */ - r128ctx->regs.tex_cntl_c |= R128_TEX_CACHE_FLUSH; - - r128ctx->dirty |= (R128_UPDATE_CONTEXT | - R128_UPDATE_TEXSTATE); - r128ctx->dirty_context |= (R128_CTX_ENGINESTATE | - R128_CTX_TEX0STATE | - R128_CTX_TEX1STATE); - } + /* Update the context state */ + r128ctx->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + + r128ctx->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) +static void r128DDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; - - if (!t) 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); - r128SetTexFilter(t, tObj->MinFilter, tObj->MagFilter); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - if (t->bound) FLUSH_BATCH(r128ctx); - r128SetTexWrap(t, tObj->WrapS, tObj->WrapT); - break; - - case GL_TEXTURE_BORDER_COLOR: - if (t->bound) FLUSH_BATCH(r128ctx); - r128SetTexBorderColor(t, tObj->BorderColor); - break; - - default: - return; - } - - r128ctx->dirty |= R128_UPDATE_TEXSTATE; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + 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 ); + r128SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if ( t->bound ) FLUSH_BATCH( r128ctx ); + r128SetTexWrap( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + if ( t->bound ) FLUSH_BATCH( r128ctx ); + r128SetTexBorderColor( t, tObj->BorderColor ); + break; + + default: + return; + } + + r128ctx->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) +static void r128DDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + GLint unit = ctx->Texture.CurrentUnit; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) unit=%d\n", + __FUNCTION__, tObj, unit ); + } - FLUSH_BATCH(r128ctx); + FLUSH_BATCH( r128ctx ); - /* Unbind the old texture */ - if (r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]) { - r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; - r128ctx->CurrentTexObj[ctx->Texture.CurrentUnit] = NULL; - } + /* Unbind the old texture */ + if ( r128ctx->CurrentTexObj[unit] ) { + r128ctx->CurrentTexObj[unit]->bound &= ~(unit+1); + r128ctx->CurrentTexObj[unit] = NULL; + } - /* The actualy binding occurs in the Tex[01]UpdateState function */ - r128ctx->dirty |= R128_UPDATE_TEXSTATE; + /* The actualy binding occurs in the Tex[01]UpdateState function */ + r128ctx->new_state |= R128_NEW_TEXTURE; } /* Remove texture from AGP/local texture memory */ -static void r128DDDeleteTexture(GLcontext *ctx, - struct gl_texture_object *tObj) +static void r128DDDeleteTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; - if (t) { - if (t->bound) { - FLUSH_BATCH(r128ctx); + if ( t ) { + if ( t->bound ) { + FLUSH_BATCH( r128ctx ); - r128ctx->CurrentTexObj[t->bound-1] = 0; - r128ctx->dirty |= R128_UPDATE_TEXSTATE; - } + r128ctx->CurrentTexObj[t->bound-1] = 0; + r128ctx->new_state |= R128_NEW_TEXTURE; + } - r128DestroyTexObj(r128ctx, t); - tObj->DriverData = NULL; - } + r128DestroyTexObj( r128ctx, 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) + * texture memory. + */ +static GLboolean r128DDIsTextureResident( GLcontext *ctx, + struct gl_texture_object *tObj ) { - r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; - return t && t->memBlock; + return t && t->memBlock; } /* Initialize the driver's texture functions */ -void r128DDInitTextureFuncs(GLcontext *ctx) +void r128DDInitTextureFuncs( GLcontext *ctx ) { - ctx->Driver.TexEnv = r128DDTexEnv; - ctx->Driver.TexImage = r128DDTexImage; - ctx->Driver.TexSubImage = r128DDTexSubImage; - ctx->Driver.TexParameter = r128DDTexParameter; - ctx->Driver.BindTexture = r128DDBindTexture; - ctx->Driver.DeleteTexture = r128DDDeleteTexture; - ctx->Driver.UpdateTexturePalette = NULL; - ctx->Driver.ActiveTexture = NULL; - ctx->Driver.IsTextureResident = r128DDIsTextureResident; - ctx->Driver.PrioritizeTexture = NULL; + ctx->Driver.TexEnv = r128DDTexEnv; + ctx->Driver.TexImage = r128DDTexImage; + ctx->Driver.TexSubImage = r128DDTexSubImage; + ctx->Driver.TexParameter = r128DDTexParameter; + ctx->Driver.BindTexture = r128DDBindTexture; + ctx->Driver.DeleteTexture = r128DDDeleteTexture; + ctx->Driver.UpdateTexturePalette = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.IsTextureResident = r128DDIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; } 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 ed1d5e2b5..d225765a6 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h @@ -1,8 +1,8 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.h,v 1.1 2000/06/17 00:03:08 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.h,v 1.2 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., - Cedar Park, Texas. + Cedar Park, Texas. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Gareth Hughes <gareth@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -38,12 +38,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -extern void r128AgeTextures(r128ContextPtr r128ctx, int heap); -extern int r128UploadTexImages(r128ContextPtr r128ctx, r128TexObjPtr t); -extern void r128UpdateTextureState(r128ContextPtr r128ctx); -extern void r128DestroyTexObj(r128ContextPtr r128ctx, r128TexObjPtr t); +extern void r128UpdateTextureState( GLcontext *ctx ); + +extern int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ); + +extern void r128AgeTextures( r128ContextPtr r128ctx, int heap ); +extern void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ); + +extern void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ); +extern void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ); + +extern void r128DDInitTextureFuncs( GLcontext *ctx ); -extern void r128DDInitTextureFuncs(GLcontext *ctx); #define R128PACKCOLOR332(r, g, b) \ (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) @@ -64,16 +70,16 @@ extern void r128DDInitTextureFuncs(GLcontext *ctx); #define R128PACKCOLOR4444(r, g, b, a) \ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) -static __inline__ CARD32 r128PackColor(GLuint depth, - GLubyte r, GLubyte g, - GLubyte b, GLubyte a) +static __inline__ CARD32 r128PackColor( GLuint depth, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) { - switch (depth) { - case 8: return R128PACKCOLOR332(r, g, b); - case 15: return R128PACKCOLOR1555(r, g, b, a); - case 16: return R128PACKCOLOR565(r, g, b); - case 24: return R128PACKCOLOR888(r, g, b); - case 32: return R128PACKCOLOR8888(r, g, b, a); + switch ( depth ) { + case 8: return R128PACKCOLOR332( r, g, b ); + case 15: return R128PACKCOLOR1555( r, g, b, a ); + case 16: return R128PACKCOLOR565( r, g, b ); + case 24: return R128PACKCOLOR888( r, g, b ); + case 32: return R128PACKCOLOR8888( r, g, b, a ); default: return 0; } } 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 504d35087..59b568321 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.2 2000/09/27 03:39:03 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,60 +28,55 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Gareth Hughes <gareth@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ #ifndef _R128_TEXOBJ_H_ #define _R128_TEXOBJ_H_ +#include "r128_sarea.h" #include "mm.h" -#define R128_TEX_MAXLEVELS 11 - -/* Setup registers for each texture */ -typedef struct { - CARD32 tex_cntl; - CARD32 size_pitch; - CARD32 border_color; -} r128TextureRegs; - /* Individual texture image information */ typedef struct { - int offset; /* Offset into locally shared texture space (i.e., + GLuint offset; /* Offset into locally shared texture space (i.e., relative to bufAddr (below) */ - int width; /* Width of texture image */ - int height; /* Height of texture image */ + GLuint width; /* Width of texture image */ + GLuint height; /* Height of texture image */ } r128TexImage; typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr; /* 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 */ + 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 */ - int bound; /* Texture unit currently bound to */ - int heap; /* Texture heap currently stored in */ - r128TexImage image[R128_TEX_MAXLEVELS]; /* Image data for all - mipmap levels */ - int totalSize; /* Total size of the texture + + 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 */ + + GLint totalSize; /* Total size of the texture including all mipmap levels */ - int internFormat; /* Internal GL format used to store + GLuint internFormat; /* Internal GL format used to store texture on card */ - int textureFormat; /* Actual hardware format */ - int texelBytes; /* Number of bytes per texel */ + CARD32 textureFormat; /* Actual hardware format */ + GLint texelBytes; /* Number of bytes per texel */ - r128TextureRegs regs; /* 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 2dc13af19..8d1053e90 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.2 2000/08/25 13:42:31 dawes Exp $ */ /* -*- c-basic-offset: 4 -*- */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ /* -*- c-basic-offset: 3 -*- */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,35 +28,59 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_lock.h" -#include "r128_reg.h" -#include "r128_cce.h" +#include "r128_ioctl.h" #include "r128_vb.h" #include "r128_tris.h" #include "r128_state.h" +#include "pipeline.h" +#include "vbindirect.h" + static struct { - points_func points; - line_func line; - triangle_func tri; - quad_func quad; -} rast_tab[0x10]; + points_func points; + line_func line; + triangle_func triangle; + 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]; \ + (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 ) { +} +static void r128_null_triangle( GLcontext *ctx, GLuint v0, + 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 r128PrintRenderState( const char *msg, GLuint state ) +{ + fprintf( stderr, "%s: (0x%x) %s%s%s%s%s\n", + msg, state, + (state & R128_FLAT_BIT) ? "flat, " : "", + (state & R128_OFFSET_BIT) ? "offset, " : "", + (state & R128_TWOSIDE_BIT) ? "twoside, " : "", + (state & R128_NODRAW_BIT) ? "no-draw, " : "", + (state & R128_FALLBACK_BIT) ? "fallback" : "" ); +} + #define IND (0) #define TAG(x) x #include "r128_tritmp.h" @@ -89,75 +113,95 @@ do { \ #define TAG(x) x##_twoside_offset_flat #include "r128_tritmp.h" + /* Initialize the table of points, line and triangle drawing functions */ -void r128DDTriangleFuncsInit(void) +void r128DDTriangleFuncsInit( void ) { - init(); - init_flat(); - init_offset(); - init_offset_flat(); - init_twoside(); - init_twoside_flat(); - init_twoside_offset(); - init_twoside_offset_flat(); + int 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 < 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; + } + } } - /* FIXME: Only enable software fallback for stencil in 16 bpp mode after - we have hardware stencil support */ -#define ALL_FALLBACK (DD_MULTIDRAW | DD_SELECT | DD_FEEDBACK | DD_STENCIL) -#define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH) -#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) + * we have hardware stencil support. + */ +#define ALL_FALLBACK (DD_MULTIDRAW | 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_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) /* 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 r128DDChooseRenderState(GLcontext *ctx) + * current rendering state. Wherever possible, use the hardware to + * render the primitive. Otherwise, fallback to software rendering. + */ +void r128DDChooseRenderState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - GLuint flags = ctx->TriangleCaps; - CARD32 index = 0; - - if (r128ctx->Fallback) { - r128ctx->RenderIndex = R128_FALLBACK_BIT; - return; - } - - if (flags & (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET)) { - if (flags & DD_FLATSHADE) index |= R128_FLAT_BIT; - if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT; - } - - r128ctx->PointsFunc = rast_tab[index].points; - r128ctx->LineFunc = rast_tab[index].line; - r128ctx->TriangleFunc = rast_tab[index].tri; - r128ctx->QuadFunc = rast_tab[index].quad; - - r128ctx->RenderIndex = index; - r128ctx->IndirectTriangles = 0; - - if (flags & ANY_FALLBACK) { - r128ctx->RenderIndex |= R128_FALLBACK_BIT; - - if (flags & POINT_FALLBACK) { - r128ctx->PointsFunc = 0; - r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; - } - - if (flags & LINE_FALLBACK) { - r128ctx->LineFunc = 0; - r128ctx->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); - } - } + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + GLuint flags = ctx->TriangleCaps; + CARD32 index = 0; + + if ( r128ctx->Fallback ) { + r128ctx->RenderIndex = R128_FALLBACK_BIT; + return; + } + + if ( flags & ANY_RASTER_FLAGS ) { + if ( flags & DD_FLATSHADE ) index |= R128_FLAT_BIT; + if ( flags & DD_TRI_LIGHT_TWOSIDE ) index |= R128_TWOSIDE_BIT; + if ( flags & DD_TRI_OFFSET ) index |= R128_OFFSET_BIT; + 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; + + r128ctx->RenderIndex = index; + r128ctx->IndirectTriangles = 0; + + if ( flags & ANY_FALLBACK ) { + r128ctx->RenderIndex |= R128_FALLBACK_BIT; + + if ( flags & POINT_FALLBACK ) { + r128ctx->PointsFunc = 0; + r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + } + + if ( flags & LINE_FALLBACK ) { + r128ctx->LineFunc = 0; + r128ctx->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); + } + } + + if ( 0 ) { + gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); + r128PrintRenderState( "r128 render state", r128ctx->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 c6f4db2ad..364aa02c9 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.2 2000/08/25 13:42:31 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -42,154 +43,277 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void r128DDChooseRenderState(GLcontext *ctx); extern void r128DDTriangleFuncsInit(void); -#define R128_FLAT_BIT 0x01 -#define R128_OFFSET_BIT 0x02 -#define R128_TWOSIDE_BIT 0x04 -#define R128_FALLBACK_BIT 0x08 +#define R128_ANTIALIAS_BIT 0x00 /* Ignored for now */ +#define R128_FLAT_BIT 0x01 +#define R128_OFFSET_BIT 0x02 +#define R128_TWOSIDE_BIT 0x04 +#define R128_NODRAW_BIT 0x08 +#define R128_FALLBACK_BIT 0x10 +#define R128_MAX_TRIFUNC 0x20 /* Draw a triangle from the vertices in the vertex buffer */ -static __inline void r128DrawTriangleVB( r128ContextPtr r128ctx, +static __inline void r128_draw_triangle( r128ContextPtr r128ctx, r128Vertex *v0, r128Vertex *v1, r128Vertex *v2 ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVertexDwordsInlined( r128ctx, 3 * vertsize ); - int j; + int vertsize = r128ctx->vertsize; + CARD32 *vb = r128AllocVerticesInline( r128ctx, 3 ); + int j; #if defined (USE_X86_ASM) - /* GTH: 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" ); + /* GTH: 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]; + 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] = 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] = v2->ui[j]; +#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 ) +{ + int vertsize = r128ctx->vertsize; + CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: 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 } /* Draw a line from the vertices in the vertex buffer */ -static __inline void r128DrawLineVB( r128ContextPtr r128ctx, +static __inline void r128_draw_line( r128ContextPtr r128ctx, r128Vertex *tmp0, r128Vertex *tmp1, float width ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVertexDwordsInlined( r128ctx, 6 * vertsize ); - float dx, dy, ix, iy; - int j; - - dx = tmp0->vert1.x - tmp1->vert1.x; - dy = tmp0->vert1.y - tmp1->vert1.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->vert1.x - ix; - *(float *)&vb[1] = tmp0->vert1.y - iy; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp0->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp1->vert1.x + ix; - *(float *)&vb[1] = tmp1->vert1.y + iy; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp1->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp0->vert1.x + ix; - *(float *)&vb[1] = tmp0->vert1.y + iy; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp0->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp0->vert1.x - ix; - *(float *)&vb[1] = tmp0->vert1.y - iy; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp0->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp1->vert1.x - ix; - *(float *)&vb[1] = tmp1->vert1.y - iy; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp1->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp1->vert1.x + ix; - *(float *)&vb[1] = tmp1->vert1.y + iy; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp1->ui[j]; +#if 1 + int vertsize = r128ctx->vertsize; + CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + float dx, dy, ix, iy; + int 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 + + int vertsize = r128ctx->vertsize; + CARD32 *vb = r128AllocVerticesInline( r128ctx, 2 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: 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 } /* Draw a point from the vertices in the vertex buffer */ -static __inline void r128DrawPointVB( r128ContextPtr r128ctx, +static __inline void r128_draw_point( r128ContextPtr r128ctx, r128Vertex *tmp, float sz ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVertexDwordsInlined( r128ctx, 6 * vertsize ); - int j; - - *(float *)&vb[0] = tmp->vert1.x - sz; - *(float *)&vb[1] = tmp->vert1.y - sz; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp->vert1.x + sz; - *(float *)&vb[1] = tmp->vert1.y - sz; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp->vert1.x + sz; - *(float *)&vb[1] = tmp->vert1.y + sz; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp->vert1.x + sz; - *(float *)&vb[1] = tmp->vert1.y + sz; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp->vert1.x - sz; - *(float *)&vb[1] = tmp->vert1.y + sz; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; - vb += vertsize; - - *(float *)&vb[0] = tmp->vert1.x - sz; - *(float *)&vb[1] = tmp->vert1.y - sz; - for (j = 2 ; j < vertsize ; j++) - vb[j] = tmp->ui[j]; +#if 1 + int vertsize = r128ctx->vertsize; + CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int 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 = r128ctx->vertsize; + CARD32 *vb = r128AllocVerticesInline( r128ctx, 1 ); + int j; + +#if defined (USE_X86_ASM) + /* GTH: 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 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 12a813e66..d448493d0 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h,v 1.2 2000/08/25 13:42:31 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h,v 1.4 2000/12/04 22:46:01 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,107 +28,212 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ #if !defined(TAG) || !defined(IND) - this is an error +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) +static __inline void TAG(triangle)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, + GLuint pv ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVertexDwords(r128ctx, - 3 * vertsize); - struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - const r128Vertex *v[3]; - int i, j; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; + r128Vertex *v[3]; #if (IND & R128_OFFSET_BIT) - GLfloat offset; + GLfloat offset; + GLfloat z[3]; #endif #if (IND & R128_TWOSIDE_BIT) - int c[3]; - - c[0] = c[1] = c[2] = *(int *)&r128verts[pv].vert1.dif_argb; + GLuint c[3]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; - v[2] = &r128verts[e2]; + v[0] = &r128verts[e0]; + v[1] = &r128verts[e1]; + v[2] = &r128verts[e2]; + +#if (IND & R128_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; +#endif #if (IND & (R128_TWOSIDE_BIT | R128_OFFSET_BIT)) - { - GLfloat ex = v[0]->vert1.x - v[2]->vert1.x; - GLfloat ey = v[0]->vert1.y - v[2]->vert1.y; - GLfloat fx = v[1]->vert1.x - v[2]->vert1.x; - GLfloat fy = v[1]->vert1.y - v[2]->vert1.y; - GLfloat cc = ex*fy - ey*fx; + { + 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 & R128_TWOSIDE_BIT) - { - GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; - GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & R128_FLAT_BIT) { - R128_COLOR((char *)&c[0], vbcolor[pv]); - c[2] = c[1] = c[0]; - } else { - R128_COLOR((char *)&c[0], vbcolor[e0]); - R128_COLOR((char *)&c[1], vbcolor[e1]); - R128_COLOR((char *)&c[2], vbcolor[e2]); - } - } + { + 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] ); + 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] ); + } + } #endif #if (IND & R128_OFFSET_BIT) - { - offset = ctx->Polygon.OffsetUnits * r128ctx->depth_scale; - if (cc * cc > 1e-16) { - GLfloat ez = v[0]->vert1.z - v[2]->vert1.z; - GLfloat fz = v[1]->vert1.z - v[2]->vert1.z; - 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; - } - } + { + offset = ctx->Polygon.OffsetUnits * r128ctx->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 + + r128_draw_triangle( r128ctx, v[0], v[1], v[2] ); + +#if (IND & R128_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; +#endif + +#if (IND & R128_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 + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; + r128Vertex *v[4]; + +#if (IND & R128_OFFSET_BIT) + GLfloat offset; + GLfloat z[4]; #endif - for (j = 0 ; j < 3 ; j++, vb += vertsize) { +#if (IND & R128_TWOSIDE_BIT) + int c[4]; +#endif - for (i = 0 ; i < vertsize ; i++) - vb[i] = v[j]->ui[i]; + v[0] = &r128verts[e0]; + v[1] = &r128verts[e1]; + v[2] = &r128verts[e2]; + v[3] = &r128verts[e3]; #if (IND & R128_TWOSIDE_BIT) - vb[4] = c[j]; /* color is the fifth element... */ + 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 & (R128_TWOSIDE_BIT | R128_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 & R128_TWOSIDE_BIT) + { + 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]); + 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]); + } + } +#endif + #if (IND & R128_OFFSET_BIT) - *(float *)&vb[2] = v[j]->vert1.z + offset; + { + offset = ctx->Polygon.OffsetUnits * r128ctx->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 + r128_draw_quad( r128ctx, v[0], v[1], v[2], v[3] ); -static void TAG(quad)(GLcontext *ctx, - GLuint v0, GLuint v1, GLuint v2, GLuint v3, - GLuint pv) -{ - TAG(triangle)(ctx, v0, v1, v3, pv); - TAG(triangle)(ctx, v1, v2, v3, pv); +#if (IND & R128_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 & R128_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 } @@ -141,44 +246,97 @@ static void TAG(quad)(GLcontext *ctx, * Twosided lighting for GL_LINE triangles is dependent on the same * harness. */ -static void TAG(line)(GLcontext *ctx, - GLuint v0, GLuint v1, - GLuint pv) +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; - float width = ctx->Line.Width; + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128VertexPtr r128verts = R128_DRIVER_DATA(ctx->VB)->verts; + GLfloat width = ctx->Line.Width; + r128Vertex *v[2]; + +#if (IND & R128_OFFSET_BIT) + GLfloat offset; + GLfloat z[2]; +#endif +#if (IND & R128_TWOSIDE_BIT) + int c[2]; +#endif + + v[0] = &r128verts[e0]; + v[1] = &r128verts[e1]; + +#if (IND & R128_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; +#endif + +#if (IND & R128_TWOSIDE_BIT) + { + GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + if (IND & R128_FLAT_BIT) { + R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + 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] ); + } + } +#endif + +#if (IND & R128_OFFSET_BIT) + offset = ctx->LineZoffset * r128ctx->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 ); + +#if (IND & R128_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; +#endif + +#if (IND & R128_TWOSIDE_BIT) + 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[v0]; - r128Vertex tmp1 = r128verts[v1]; + 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.vert1.dif_argb, vbcolor[pv]); - *(int *)&tmp1.vert1.dif_argb = *(int *)&tmp0.vert1.dif_argb; + R128_COLOR((char *)&tmp0.v.color, vbcolor[pv]); + *(int *)&tmp1.v.color = *(int *)&tmp0.v.color; } else { - R128_COLOR((char *)&tmp0.vert1.dif_argb, vbcolor[v0]); - R128_COLOR((char *)&tmp1.vert1.dif_argb, vbcolor[v1]); + R128_COLOR((char *)&tmp0.v.color, vbcolor[e0]); + R128_COLOR((char *)&tmp1.v.color, vbcolor[e1]); } } else if (IND & R128_FLAT_BIT) { - *(int *)&tmp0.vert1.dif_argb = *(int *)&r128verts[pv].vert1.dif_argb; - *(int *)&tmp1.vert1.dif_argb = *(int *)&r128verts[pv].vert1.dif_argb; + *(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.vert1.z += offset; - tmp1.vert1.z += offset; + tmp0.v.z += offset; + tmp1.v.z += offset; } - r128DrawLineVB( r128ctx, &tmp0, &tmp1, width ); + r128_draw_line( r128ctx, &tmp0, &tmp1, width ); + } else { + r128_draw_line( r128ctx, &r128verts[e0], &r128verts[e1], width ); } - else - r128DrawLineVB( r128ctx, &r128verts[v0], &r128verts[v1], width ); +#endif } /* Draw a set of points. Note that the device-dependent vertex data @@ -186,40 +344,40 @@ static void TAG(line)(GLcontext *ctx, 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; - - - for(i = first; i <= last; i++) { - if(VB->ClipMask[i] == 0) { - if (IND & (R128_TWOSIDE_BIT|R128_OFFSET_BIT)) { - r128Vertex tmp0 = r128verts[i]; - - if (IND & R128_TWOSIDE_BIT) { - GLubyte (*vbcolor)[4] = VB->ColorPtr->data; - R128_COLOR((char *)&tmp0.vert1.dif_argb, vbcolor[i]); - } - if (IND & R128_OFFSET_BIT) { - GLfloat offset = ctx->PointZoffset * r128ctx->depth_scale; - tmp0.vert1.z += offset; - } - r128DrawPointVB( r128ctx, &tmp0, size ); - } else - r128DrawPointVB( r128ctx, &r128verts[i], size ); - } - } + 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; + + + for(i = first; i < last; i++) { + if(VB->ClipMask[i] == 0) { + if (IND & (R128_TWOSIDE_BIT|R128_OFFSET_BIT)) { + r128Vertex tmp0 = r128verts[i]; + + if (IND & R128_TWOSIDE_BIT) { + GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + R128_COLOR((char *)&tmp0.v.color, vbcolor[i]); + } + if (IND & R128_OFFSET_BIT) { + GLfloat offset = ctx->PointZoffset * r128ctx->depth_scale; + tmp0.v.z += offset; + } + r128_draw_point( r128ctx, &tmp0, size ); + } else + r128_draw_point( r128ctx, &r128verts[i], size ); + } + } } /* Initialize the table of primitives to render. */ static void TAG(init)(void) { - rast_tab[IND].tri = TAG(triangle); - rast_tab[IND].quad = TAG(quad); - rast_tab[IND].line = TAG(line); - rast_tab[IND].points = TAG(points); + rast_tab[IND].triangle = TAG(triangle); + rast_tab[IND].quad = TAG(quad); + rast_tab[IND].line = TAG(line); + rast_tab[IND].points = TAG(points); } #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 3248a1493..64308e76d 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.7 2000/11/08 05:02:51 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.8 2000/12/04 19:21:48 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,453 +28,477 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ -#include "r128_init.h" -#include "r128_xmesa.h" #include "r128_context.h" -#include "r128_lock.h" -#include "r128_reg.h" -#include "r128_cce.h" +#include "r128_ioctl.h" #include "r128_state.h" #include "r128_vb.h" + #include "mem.h" #include "stages.h" -#define TEX0 \ -do { \ - v->vert1.tu0 = tc0[i][0]; \ - v->vert1.tv0 = tc0[i][1]; \ +#define TEX0 \ +do { \ + v->v.tu0 = tc0[i][0]; \ + v->v.tv0 = tc0[i][1]; \ } while (0) -#define TEX1 \ -do { \ - v->vert2.tu1 = tc1[i][0]; \ - v->vert2.tv1 = tc1[i][1]; \ +#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->vert1.spec_frgb.r = spec[0]; \ - v->vert1.spec_frgb.g = spec[1]; \ - v->vert1.spec_frgb.b = spec[2]; \ +#define SPC \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.blue = spec[2]; \ + v->v.specular.green = spec[1]; \ + v->v.specular.red = spec[0]; \ } while (0) #define FOG \ do { \ - GLubyte *spec = &(VB->Spec[0][i][0]); \ - v->vert1.spec_frgb.a = spec[3]; \ + 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->vert1.dif_argb.a = col[3]; \ - v->vert1.dif_argb.r = col[0]; \ - v->vert1.dif_argb.g = col[1]; \ - v->vert1.dif_argb.b = col[2]; \ +#define COL \ +do { \ + GLubyte *col = &(VB->Color[0]->data[i][0]); \ + v->v.color.blue = col[2]; \ + v->v.color.green = col[1]; \ + v->v.color.red = col[0]; \ + v->v.color.alpha = col[3]; \ } while (0) -#if 1 -/* FIXME: These are handled by the Rage 128 */ -#define TEX0_4 -#define TEX1_4 -#else -#define TEX0_4 \ -do { \ - 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++) { \ - float oow = 1.0 / tc[i][3]; \ - v->vert1.rhw *= tc[i][3]; \ - v->vert1.tu0 *= oow; \ - v->vert1.tv0 *= oow; \ - } \ - } \ +#define TEX0_4 \ +do { \ + 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++) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ + v->v.tu0 *= oow; \ + v->v.tv0 *= oow; \ + } \ + } \ } while (0) -#ifdef USE_RHW2 -#define TEX1_4 \ -do { \ - 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++) { \ - float oow = 1.0 / tc[i][3]; \ - v->vert3.rhw2 *= tc[i][3]; \ - v->vert3.tu1 *= oow; \ - v->vert3.tv1 *= oow; \ - } \ - } \ -} while (0) -#else -#define TEX1_4 -#endif -#endif - -#ifdef USE_RHW2 -#define COORD \ -do { \ - GLfloat *win = VB->Win.data[i]; \ - v->vert3.x = win[0]; \ - v->vert3.y = r128height - win[1]; \ - v->vert3.z = scale * win[2]; \ - v->vert3.rhw = v->vert3.rhw2 = win[3]; \ +#if USE_RHW2 + +#define TEX1_4 \ +do { \ + 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++) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw2 *= tc[i][3]; \ + v->v.tu1 *= oow; \ + v->v.tv1 *= oow; \ + } \ + } \ } while (0) -#else -#define COORD \ -do { \ - GLfloat *win = VB->Win.data[i]; \ - v->vert1.x = win[0]; \ - v->vert1.y = r128height - win[1]; \ - v->vert1.z = scale * win[2]; \ - v->vert1.rhw = win[3]; \ + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = r128height - win[1]; \ + v->v.z = scale * win[2]; \ + v->v.rhw = v->v.rhw2 = win[3]; \ } while (0) -#endif + +#else /* USE_RHW2 */ + +#define TEX1_4 + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = r128height - win[1]; \ + v->v.z = 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) \ -{ \ - 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; \ - \ - (void) r128height; (void) r128ctx; (void) scale; \ - \ - gl_import_client_data(VB, VB->ctx->RenderFlags, \ - (VB->ClipOrMask \ - ? VEC_WRITABLE | VEC_GOOD_STRIDE \ - : VEC_GOOD_STRIDE)); \ - \ - tc0 = VB->TexCoordPtr[0]->data; \ - tc1 = VB->TexCoordPtr[1]->data; \ - \ - v = &(R128_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; \ +#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ +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; \ + \ + (void) r128height; (void) r128ctx; (void) scale; \ + \ + 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; \ + \ + v = &(R128_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_wt1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, 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_wft1, COORD, NOP, NOP, TEX1, NOP, TEX1_4, 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_wgt1, COORD, COL, NOP, TEX1, NOP, TEX1_4, 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_wgst1, COORD, COL, NOP, TEX1, NOP, TEX1_4, 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_wgft1, COORD, COL, NOP, TEX1, NOP, TEX1_4, 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_wgfst1, COORD, COL, NOP, TEX1, NOP, TEX1_4, 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_t1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, 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_ft1, NOP, NOP, NOP, TEX1, NOP, TEX1_4, 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_gt1, NOP, COL, NOP, TEX1, NOP, TEX1_4, 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_gst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, 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_gft1, NOP, COL, NOP, TEX1, NOP, TEX1_4, 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_gfst1, NOP, COL, NOP, TEX1, NOP, TEX1_4, 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) +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, "r128RasterSetup(): invalid setup function\n"); + fprintf(stderr, "r128RasterSetup(): invalid setup function\n"); } typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint); -static setupFunc setup_func[0x20]; +static setupFunc setup_func[0x40]; /* Initialize the table of vertex buffer setup functions */ -void r128DDSetupInit(void) +void r128DDSetupInit( void ) +{ + int i; + + for (i = 0; i < 0x20; i++) setup_func[i] = rs_invalid; + + /* 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; + setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wft0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT] = rs_wg; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT] = rs_wgs; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT] = rs_wgt0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgt0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgst0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgst0t1; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT] = rs_wgf; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_wgfs; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wgft0; + setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgft0t1; + 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 */ + setup_func[R128_TEX0_BIT] = rs_t0; + setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1; + setup_func[R128_FOG_BIT] = rs_f; + setup_func[R128_FOG_BIT|R128_TEX0_BIT] = rs_ft0; + setup_func[R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_ft0t1; + setup_func[R128_RGBA_BIT] = rs_g; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT] = rs_gs; + setup_func[R128_RGBA_BIT|R128_TEX0_BIT] = rs_gt0; + setup_func[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gt0t1; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gst0; + setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gst0t1; + setup_func[R128_RGBA_BIT|R128_FOG_BIT] = rs_gf; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_gfs; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_gft0; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gft0t1; + setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gfst0; + 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 ) { - int i; - - for (i = 0; i < 0x20; i++) setup_func[i] = rs_invalid; - - /* Funcs to build vertices from scratch */ - setup_func[R128_WIN_BIT|R128_TEX0_BIT] = rs_wt0; - setup_func[R128_WIN_BIT|R128_TEX1_BIT] = rs_wt1; - 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; - setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wft1; - setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wft0t1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT] = rs_wg; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT] = rs_wgs; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT] = rs_wgt0; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX1_BIT] = rs_wgt1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgt0t1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgst0; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_wgst1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgst0t1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT] = rs_wgf; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_wgfs; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wgft0; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_wgft1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgft0t1; - 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_TEX1_BIT] = rs_wgfst1; - setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgfst0t1; - - - /* Funcs to repair vertices */ - setup_func[R128_TEX0_BIT] = rs_t0; - setup_func[R128_TEX1_BIT] = rs_t1; - setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1; - setup_func[R128_FOG_BIT] = rs_f; - setup_func[R128_FOG_BIT|R128_TEX0_BIT] = rs_ft0; - setup_func[R128_FOG_BIT|R128_TEX1_BIT] = rs_ft1; - setup_func[R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_ft0t1; - setup_func[R128_RGBA_BIT] = rs_g; - setup_func[R128_RGBA_BIT|R128_SPEC_BIT] = rs_gs; - setup_func[R128_RGBA_BIT|R128_TEX0_BIT] = rs_gt0; - setup_func[R128_RGBA_BIT|R128_TEX1_BIT] = rs_gt1; - setup_func[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gt0t1; - setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gst0; - setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gst1; - setup_func[R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gst0t1; - setup_func[R128_RGBA_BIT|R128_FOG_BIT] = rs_gf; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT] = rs_gfs; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_gft0; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX1_BIT] = rs_gft1; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gft0t1; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_gfst0; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX1_BIT] = rs_gfst1; - setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gfst0t1; + fprintf( stderr, "%s: %d %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & R128_WIN_BIT) ? " xyzw," : "", + (flags & R128_RGBA_BIT) ? " rgba," : "", + (flags & R128_SPEC_BIT) ? " spec," : "", + (flags & R128_FOG_BIT) ? " fog," : "", + (flags & R128_TEX0_BIT) ? " tex-0," : "", + (flags & R128_TEX1_BIT) ? " tex-1," : "" ); } /* Initialize the vertex buffer setup functions based on the current rendering state */ -void r128DDChooseRasterSetupFunc(GLcontext *ctx) +void r128DDChooseRasterSetupFunc( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - int funcIndex = R128_WIN_BIT | R128_RGBA_BIT; - - r128ctx->vertsize = 8; - r128ctx->vc_format = R128_TEX0_VERTEX_FORMAT; - r128ctx->multitex = 0; - - if (ctx->Texture.ReallyEnabled & ENABLE_TEX0) { - /* This doesn't work for non-RGBA textures - if (ctx->Texture.Unit[0].EnvMode == GL_REPLACE) - funcIndex &= ~R128_RGBA_BIT; - */ - funcIndex |= R128_TEX0_BIT; - } - - if (ctx->Texture.ReallyEnabled & ENABLE_TEX1) { - /* GTH: we should really only enable the second texture unit - * when we're doing true multitexturing. I guess there aren't - * that many cases where apps will only bind a texture to the - * second texture unit, but it would definitely be a performance - * win in those cases. - */ - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->multitex = 1; - funcIndex |= R128_TEX1_BIT; - } - - /* FIXME: Verify this works properly */ - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - funcIndex |= R128_SPEC_BIT; - - if (ctx->Fog.Enabled) - funcIndex |= R128_FOG_BIT; - - r128ctx->SetupIndex = funcIndex; - ctx->Driver.RasterSetup = setup_func[funcIndex]; + 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; + + 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; + index |= R128_TEX1_BIT; + } + + index |= R128_TEX0_BIT; + } + + 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; + 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; + index |= R128_TEX1_BIT; + } + + index |= R128_TEX0_BIT; + } + } + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) + index |= R128_SPEC_BIT; + + if ( ctx->Fog.Enabled ) + index |= R128_FOG_BIT; + + if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, "\n" ); + r128PrintSetupFlags( "full setup function", index ); + } + + r128ctx->new_state |= R128_NEW_TEXTURE; + r128ctx->SetupIndex = index; + + ctx->Driver.RasterSetup = setup_func[index]; } /* Check to see if any updates of the vertex buffer entries are needed */ -void r128DDCheckPartialRasterSetup(GLcontext *ctx, - struct gl_pipeline_stage *s) +void r128DDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - int tmp = r128ctx->SetupDone; + r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + int tmp = r128ctx->SetupDone; - s->type = 0; - r128ctx->SetupDone = GL_FALSE; + s->type = 0; + r128ctx->SetupDone = GL_FALSE; - if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return; - if (ctx->IndirectTriangles) return; + if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return; + if (ctx->IndirectTriangles) return; - r128ctx->SetupDone = tmp; + r128ctx->SetupDone = tmp; } /* Update the vertex buffer entries, if necessary */ -void r128DDPartialRasterSetup(struct vertex_buffer *VB) +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; - - if (new & VERT_WIN) { - new = available; - index |= R128_WIN_BIT | R128_FOG_BIT; - } - - if (new & VERT_RGBA) index |= R128_RGBA_BIT | R128_SPEC_BIT; - if (new & VERT_TEX0_ANY) index |= R128_TEX0_BIT; - if (new & VERT_TEX1_ANY) index |= R128_TEX1_BIT; - if (new & VERT_FOG_COORD) index |= R128_FOG_BIT; - - r128ctx->SetupDone &= ~index; - index &= r128ctx->SetupIndex; - r128ctx->SetupDone |= index; - - if (index) setup_func[index](VB, VB->Start, VB->Count); + r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); + int new = VB->pipeline->new_outputs; + int available = VB->pipeline->outputs; + int index = 0; + + if (new & VERT_WIN) { + new = available; + index |= R128_WIN_BIT | R128_FOG_BIT; + } + + if (new & VERT_RGBA) + index |= R128_RGBA_BIT | R128_SPEC_BIT; + + if (new & VERT_TEX0_ANY) + index |= R128_TEX0_BIT; + + if (new & VERT_TEX1_ANY) + index |= r128ctx->tex_dest[1]; + + if (new & VERT_FOG_COORD) + index |= R128_FOG_BIT; + + r128ctx->SetupDone &= ~index; + index &= r128ctx->SetupIndex; + r128ctx->SetupDone |= index; + + if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) + r128PrintSetupFlags( "partial setup function", index ); + + if ( index ) + 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) +void r128DDDoRasterSetup( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - - if (VB->Type == VB_CVA_PRECALC) r128DDPartialRasterSetup(VB); - else if (ctx->Driver.RasterSetup) ctx->Driver.RasterSetup(VB, - VB->CopyStart, - VB->Count); + GLcontext *ctx = VB->ctx; + + if ( VB->Type == VB_CVA_PRECALC ) { + r128DDPartialRasterSetup( VB ); + } else if ( ctx->Driver.RasterSetup ) { + ctx->Driver.RasterSetup( VB, + VB->CopyStart, + VB->Count ); + } } /* Resize an existing vertex buffer */ -void r128DDResizeVB(struct vertex_buffer *VB, GLuint size) +void r128DDResizeVB( struct vertex_buffer *VB, GLuint size ) { - r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); - - while (r128vb->size < size) - r128vb->size *= 2; - - free(r128vb->vert_store); - r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31); - if (!r128vb->vert_store) { - fprintf(stderr, "Cannot allocate vertex store! Exiting...\n"); - exit(1); - } - - r128vb->verts = - (r128VertexPtr)(((unsigned long)r128vb->vert_store + 31) & ~31); - - gl_vector1ui_free(&r128vb->clipped_elements); - gl_vector1ui_alloc(&r128vb->clipped_elements, - VEC_WRITABLE, r128vb->size, 32); - if (!r128vb->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, 4); - if (!VB->ClipMask) { - fprintf(stderr, "Cannot allocate clipmask! Exiting...\n"); - exit(1); - } + r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + + while ( r128vb->size < size ) + r128vb->size *= 2; + + ALIGN_FREE( r128vb->vert_store ); + r128vb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * r128vb->size, 32 ); + if ( !r128vb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + r128vb->verts = (r128VertexPtr)r128vb->vert_store; + + gl_vector1ui_free( &r128vb->clipped_elements ); + gl_vector1ui_alloc( &r128vb->clipped_elements, + VEC_WRITABLE, r128vb->size, 32 ); + if ( !r128vb->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 ); + 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) +void r128DDRegisterVB( struct vertex_buffer *VB ) { - r128VertexBufferPtr r128vb; - - r128vb = (r128VertexBufferPtr)calloc(1, sizeof(*r128vb)); - - r128vb->size = VB->Size * 2; - r128vb->vert_store = malloc(sizeof(r128Vertex) * r128vb->size + 31); - if (!r128vb->vert_store) { - fprintf(stderr, "Cannot allocate vertex store! Exiting...\n"); - exit(1); - } - - r128vb->verts = - (r128VertexPtr)(((unsigned long)r128vb->vert_store + 31) & ~31); - - gl_vector1ui_alloc(&r128vb->clipped_elements, - VEC_WRITABLE, r128vb->size, 32); - if (!r128vb->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, 4); - if (!VB->ClipMask) { - fprintf(stderr, "Cannot allocate clipmask! Exiting...\n"); - exit(1); - } - - VB->driver_data = r128vb; + r128VertexBufferPtr r128vb; + + r128vb = (r128VertexBufferPtr)CALLOC( sizeof(*r128vb) ); + + r128vb->size = VB->Size * 2; + r128vb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * r128vb->size, 32 ); + if ( !r128vb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + r128vb->verts = (r128VertexPtr)r128vb->vert_store; + + gl_vector1ui_alloc( &r128vb->clipped_elements, + VEC_WRITABLE, r128vb->size, 32 ); + if ( !r128vb->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 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } + + VB->driver_data = r128vb; } /* Destroy a device-dependent vertex buffer */ -void r128DDUnregisterVB(struct vertex_buffer *VB) +void r128DDUnregisterVB( struct vertex_buffer *VB ) { - r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); - - if (r128vb) { - if (r128vb->vert_store) free(r128vb->vert_store); - gl_vector1ui_free(&r128vb->clipped_elements); - free(r128vb); - VB->driver_data = 0; - } + r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + + if ( r128vb ) { + if ( r128vb->vert_store ) ALIGN_FREE( r128vb->vert_store ); + gl_vector1ui_free( &r128vb->clipped_elements ); + FREE( r128vb ); + 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 761b3de85..f1afdff2c 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.2 2000/08/25 13:42:31 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.3 2000/12/04 19:21:48 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,7 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -39,66 +40,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* FIXME: This is endian-specific */ typedef struct { - GLubyte b; - GLubyte g; - GLubyte r; - GLubyte a; -} r128Color; - -/* Single texture vertex, single x86 cache line. - * - * GTH: This is in use now. - */ -typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - GLfloat rhw; /* Reciprocal homogeneous w */ - r128Color dif_argb; /* Diffuse color */ - r128Color spec_frgb; /* Specular color (alpha is fog) */ - GLfloat tu0, tv0; /* Texture 0 coordinates */ -} r128_vertex1; - -/* The only vertex format in current use, but unsatisfactory for two - * reasons: - * - Not possible to implement fully conformant rendering - * with this format (projective multitexturing), - * - Performance is lower with this vertex for single-texture - * geometry, as the vertex is unnecessarily larger than - * a cacheline. - * - * Switching to single-texture vertices can be accomplished in state - * management, and is relatively trivial. Switching to the rhw2 - * format is data-dependent (are there any glTexCoord4f's in the - * current buffer). One option is to switch between single-texture - * and rhw2 vertex formats only on the standard path. - * - * The fastpath never requires the rhw2 format, as it already makes - * the data-dependent checks. - * - * GTH: This is fixed. - */ -typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - GLfloat rhw; /* Reciprocal homogeneous w */ - r128Color dif_argb; /* Diffuse color */ - r128Color spec_frgb; /* Specular color (alpha is fog) */ - GLfloat tu0, tv0; /* Texture 0 coordinates */ - GLfloat tu1, tv1; /* Texture 1 coordinates */ -} r128_vertex2; - -/* Need to be slightly clever about flushing vertex buffers in order - * to use rhw2 only on demand. - * - * GTH: This can be used now. + 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 */ - r128Color dif_argb; /* Diffuse color */ - r128Color spec_frgb; /* Specular color (alpha is fog) */ - GLfloat tu0, tv0; /* Texture 0 coordinates */ - GLfloat tu1, tv1; /* Texture 1 coordinates */ - GLfloat rhw2; /* Reciprocal homogeneous w2 */ -} r128_vertex2_rhw2; + 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 \ @@ -125,11 +84,9 @@ typedef struct { /* FIXME: We currently only have assembly for 16-stride vertices */ union r128_vertex_t { - r128_vertex1 vert1; - r128_vertex2 vert2; - r128_vertex2_rhw2 vert3; - float f[16]; - CARD32 ui[16]; + r128_vertex v; + GLfloat f[16]; + CARD32 ui[16]; }; typedef union r128_vertex_t r128Vertex; 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 461ab30c3..c33eca347 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c,v 1.1 2000/06/17 00:03:09 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c,v 1.2 2000/12/04 19:21:48 dawes Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,45 +28,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ #ifdef GLX_DIRECT_RENDERING /* r128 Mesa driver includes */ -#include "r128_init.h" #include "r128_context.h" -#include "r128_xmesa.h" +#include "r128_ioctl.h" #include "r128_state.h" #include "r128_tex.h" -#include "r128_swap.h" /* Mesa src includes */ #include "context.h" #include "simple_list.h" #include "mmath.h" -#ifndef R128_DEBUG_FLAGS -int R128_DEBUG_FLAGS = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_CCE */ -/* | DEBUG_VERBOSE_OUTREG */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_NO_OUTRING */ -/* | DEBUG_NO_OUTREG */ -/* | DEBUG_VERBOSE_API */ -/* | DEBUG_VERBOSE_2D */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VALIDATE_RING */ -/* | DEBUG_VERBOSE_IOCTL */ - ); -#endif - -#if DEBUG_LOCKING -char *prevLockFile = NULL; -int prevLockLine = 0; -#endif +extern void __driRegisterExtensions( void ); static r128ContextPtr r128Context = NULL; @@ -190,16 +170,28 @@ GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; +#if 0 + /* GH: This causes the driver to fail the glean makeCurrent + * tests. Leave it disabled for now... + */ if (r128Context && r128ctx == (void *)r128Context && driDrawPriv == R128_DRIDRAWABLE(r128Context)) return GL_TRUE; +#endif + /* GH: Do we still need this then? + */ 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; + } + if (!R128_MESACTX(r128Context)->Viewport.Width) { gl_Viewport(R128_MESACTX(r128Context), 0, 0, driDrawPriv->w, driDrawPriv->h); @@ -218,37 +210,10 @@ GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) return GL_TRUE; } -/* 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. */ -/* NOTE: This routine is only called while holding the hardware lock. */ -void XMesaUpdateState(__DRIcontextPrivate *driContextPriv) -{ - r128ContextPtr r128ctx = driContextPriv->driverPrivate; - __DRIscreenPrivate *sPriv = R128_DRISCREEN(r128ctx); - __DRIdrawablePrivate *dPriv = R128_DRIDRAWABLE(r128ctx); - int stamp = dPriv->lastStamp; - - /* 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(r128ctx->display, sPriv, dPriv); - - r128UpdateState(r128ctx, (stamp != dPriv->lastStamp)); -} - /* 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) +void __driRegisterExtensions( void ) { } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c b/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c index 1170a3a68..2f2d0cfb8 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c,v 1.1 2000/09/24 13:51:14 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddspan.c,v 1.5 2000/12/02 20:29:06 alanh Exp $ */ /* * Mesa 3-D graphics library * Version: 3.3 @@ -321,14 +321,13 @@ read_R5G6B5_span(const GLcontext * ctx, GLuint n, GLint x, GLint y, ? (fxMesa->screen_width) : (info.strideInBytes / 2); const GLushort *data16 = (const GLushort *) info.lfbPtr + (winY - y) * srcStride + (winX + x); - const GLuint *data32 = (const GLuint *) data16; GLuint i, j; GLuint extraPixel = (n & 1); n -= extraPixel; for (i = j = 0; i < n; i += 2, j++) { - GLuint pixel = data32[j]; - GLuint pixel0 = pixel & 0xffff; - GLuint pixel1 = pixel >> 16; + /* use data16[] to keep correct alignment */ + GLuint pixel0 = data16[i]; + GLuint pixel1 = data16[i+1]; rgba[i][RCOMP] = FX_PixelToR(fxMesa, pixel0); rgba[i][GCOMP] = FX_PixelToG(fxMesa, pixel0); rgba[i][BCOMP] = FX_PixelToB(fxMesa, pixel0); @@ -1251,7 +1250,7 @@ GetFbParams(fxMesaContext fxMesa, { FxU32 physicalStrideInBytes, bufferOffset; FxU32 strideInBytes = info->strideInBytes; - FxU32 lfbPtr = (FxU32) (info->lfbPtr); + char *lfbPtr = (char *) (info->lfbPtr); /* * These two come directly from the info structure. @@ -1278,7 +1277,7 @@ GetFbParams(fxMesaContext fxMesa, * < bufferOffset&(info->strideInBytes-1) * the buffer begins in the forbidden zone. We assert for this. */ - bufferOffset = lfbPtr - (FxU32) backBufferInfo->lfbPtr; + bufferOffset = lfbPtr - (char *) backBufferInfo->lfbPtr; physicalStrideInBytes = (fxMesa->screen_width * elementSize + TILE_WIDTH_IN_BYTES - 1) & ~(TILE_WIDTH_IN_BYTES - 1); @@ -1290,7 +1289,7 @@ GetFbParams(fxMesaContext fxMesa, * This is the address of the next physical line. */ ReadParamsp->lfbWrapPtr - = (void *) ((FxU32) backBufferInfo->lfbPtr + = (void *) ((char *) backBufferInfo->lfbPtr + (bufferOffset & ~(strideInBytes - 1)) + (TILE_HEIGHT_IN_LINES) * strideInBytes); } |