summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/radeon')
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/Imakefile386
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_context.c234
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_context.h253
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c217
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h46
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c504
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h246
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c542
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h185
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c703
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h161
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c95
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h112
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c168
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h54
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c220
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h87
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_span.c346
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_span.h45
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_state.c1338
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_state.h55
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c2253
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h96
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h87
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c209
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h316
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h336
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c483
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h136
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c314
30 files changed, 10227 insertions, 0 deletions
diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile
new file mode 100644
index 000000000..52787a5fc
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile
@@ -0,0 +1,386 @@
+XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.1 2001/01/08 01:07:26 martin Exp $
+
+#include <Threads.tmpl>
+
+#define DoNormalLib NormalLibGlx
+#define DoSharedLib SharedLibGlx
+#define DoExtraLib SharedLibGlx
+#define DoDebugLib DebugLibGlx
+#define DoProfileLib ProfileLibGlx
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+#ifdef i386Architecture
+#if MesaUseMMX
+ MMX_DEFS = -DUSE_MMX_ASM
+#endif
+#if MesaUse3DNow
+ 3DNOW_DEFS = -DUSE_3DNOW_ASM
+#endif
+#if MesaUseKatmai
+ KATMAI_DEFS = -DUSE_KATMAI_ASM
+#endif
+ ASM_DEFINES = -DUSE_X86_ASM $(MMX_DEFS) $(3DNOW_DEFS) $(KATMAI_DEFS)
+#endif
+
+#if BuildXF86DRI
+ DRI_DEFINES = GlxDefines -DDRIVERTS
+ DRI_INCLUDES = -I../../../../dri \
+ -I../../../../glx \
+ -I../../../dri \
+ -I$(TOP)/include \
+ -I$(TOP)/include/GL \
+ -I$(XF86OSSRC) \
+ -I$(XF86COMSRC) \
+ -I$(SERVERSRC)/GL/dri \
+ -I$(XF86DRIVERSRC)/ati \
+ -I../../../include \
+ -I../.. \
+ -I../../X \
+ -I../common
+#endif
+
+MESA_INCLUDES = -I. -I.. -I../../include \
+ -I../../../../dri/drm
+
+ DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES)
+
+ RADEONSRCS = radeon_context.c \
+ radeon_dd.c \
+ radeon_fastpath.c \
+ radeon_eltpath.c \
+ radeon_ioctl.c \
+ radeon_lock.c \
+ radeon_pipeline.c \
+ radeon_screen.c \
+ radeon_span.c \
+ radeon_state.c \
+ radeon_tex.c \
+ radeon_tris.c \
+ radeon_vb.c \
+ radeon_xmesa.c
+
+ RADEONOBJS = radeon_context.o \
+ radeon_dd.o \
+ radeon_fastpath.o \
+ radeon_eltpath.o \
+ radeon_ioctl.o \
+ radeon_lock.o \
+ radeon_pipeline.o \
+ radeon_screen.o \
+ radeon_span.o \
+ radeon_state.o \
+ radeon_tex.o \
+ radeon_tris.o \
+ radeon_vb.o \
+ radeon_xmesa.o
+
+#if !GlxUseBuiltInDRIDriver
+ DRISRCS = ../../../dri/dri_mesa.c \
+ ../../../../dri/dri_tmm.c
+
+ DRIOBJS = ../../../dri/dri_mesa.o \
+ ../../../../dri/dri_tmm.o
+
+ DRMSRCS = ../../../../dri/drm/xf86drm.c \
+ ../../../../dri/drm/xf86drmHash.c \
+ ../../../../dri/drm/xf86drmRandom.c \
+ ../../../../dri/drm/xf86drmSL.c \
+ ../../../../dri/drm/xf86drmRadeon.c
+
+ DRMOBJS = ../../../../dri/drm/xf86drm.o \
+ ../../../../dri/drm/xf86drmHash.o \
+ ../../../../dri/drm/xf86drmRandom.o \
+ ../../../../dri/drm/xf86drmSL.o \
+ ../../../../dri/drm/xf86drmRadeon.o
+
+ MESASRCS = ../../aatriangle.c \
+ ../../accum.c \
+ ../../alpha.c \
+ ../../alphabuf.c \
+ ../../attrib.c \
+ ../../bbox.c \
+ ../../bitmap.c \
+ ../../blend.c \
+ ../../buffers.c \
+ ../../clip.c \
+ ../../colortab.c \
+ ../../config.c \
+ ../../context.c \
+ ../../copypix.c \
+ ../../cva.c \
+ ../../debug_xform.c \
+ ../../depth.c \
+ ../../dlist.c \
+ ../../drawpix.c \
+ ../../enable.c \
+ ../../enums.c \
+ ../../eval.c \
+ ../../extensions.c \
+ ../../feedback.c \
+ ../../fog.c \
+ ../../get.c \
+ ../../glapi.c \
+ ../../glapinoop.c \
+ ../../glthread.c \
+ ../../hash.c \
+ ../../image.c \
+ ../../imaging.c \
+ ../../light.c \
+ ../../lines.c \
+ ../../logic.c \
+ ../../masking.c \
+ ../../matrix.c \
+ ../../mem.c \
+ ../../mmath.c \
+ ../../pb.c \
+ ../../pipeline.c \
+ ../../pixel.c \
+ ../../pixeltex.c \
+ ../../points.c \
+ ../../polygon.c \
+ ../../quads.c \
+ ../../rastpos.c \
+ ../../readpix.c \
+ ../../rect.c \
+ ../../scissor.c \
+ ../../shade.c \
+ ../../span.c \
+ ../../stages.c \
+ ../../state.c \
+ ../../stencil.c \
+ ../../teximage.c \
+ ../../texobj.c \
+ ../../texstate.c \
+ ../../texture.c \
+ ../../texutil.c \
+ ../../translate.c \
+ ../../triangle.c \
+ ../../varray.c \
+ ../../vb.c \
+ ../../vbcull.c \
+ ../../vbfill.c \
+ ../../vbindirect.c \
+ ../../vbrender.c \
+ ../../vbxform.c \
+ ../../vector.c \
+ ../../vertices.c \
+ ../../winpos.c \
+ ../../xform.c \
+ ../../zoom.c
+
+ MESAOBJS = ../../aatriangle.o \
+ ../../accum.o \
+ ../../alpha.o \
+ ../../alphabuf.o \
+ ../../attrib.o \
+ ../../bbox.o \
+ ../../bitmap.o \
+ ../../blend.o \
+ ../../buffers.o \
+ ../../clip.o \
+ ../../colortab.o \
+ ../../config.o \
+ ../../context.o \
+ ../../copypix.o \
+ ../../cva.o \
+ ../../debug_xform.o \
+ ../../depth.o \
+ ../../dlist.o \
+ ../../drawpix.o \
+ ../../enable.o \
+ ../../enums.o \
+ ../../eval.o \
+ ../../extensions.o \
+ ../../feedback.o \
+ ../../fog.o \
+ ../../get.o \
+ ../../hash.o \
+ ../../hint.o \
+ ../../image.o \
+ ../../imaging.o \
+ ../../light.o \
+ ../../lines.o \
+ ../../logic.o \
+ ../../masking.o \
+ ../../matrix.o \
+ ../../mem.o \
+ ../../mmath.o \
+ ../../pb.o \
+ ../../pipeline.o \
+ ../../pixel.o \
+ ../../pixeltex.o \
+ ../../points.o \
+ ../../polygon.o \
+ ../../quads.o \
+ ../../rastpos.o \
+ ../../readpix.o \
+ ../../rect.o \
+ ../../scissor.o \
+ ../../shade.o \
+ ../../span.o \
+ ../../stages.o \
+ ../../state.o \
+ ../../stencil.o \
+ ../../teximage.o \
+ ../../texobj.o \
+ ../../texstate.o \
+ ../../texture.o \
+ ../../texutil.o \
+ ../../translate.o \
+ ../../triangle.o \
+ ../../varray.o \
+ ../../vb.o \
+ ../../vbcull.o \
+ ../../vbfill.o \
+ ../../vbindirect.o \
+ ../../vbrender.o \
+ ../../vbxform.o \
+ ../../vector.o \
+ ../../vertices.o \
+ ../../winpos.o \
+ ../../xform.o \
+ ../../zoom.o
+
+#ifdef i386Architecture
+ X86_SRCS = ../../X86/common_x86.c \
+ ../../X86/common_x86_asm.S \
+ ../../X86/x86.c \
+ ../../X86/x86_cliptest.S \
+ ../../X86/x86_vertex.S \
+ ../../X86/x86_xform_masked2.S \
+ ../../X86/x86_xform_masked3.S \
+ ../../X86/x86_xform_masked4.S \
+ ../../X86/x86_xform_raw2.S \
+ ../../X86/x86_xform_raw3.S \
+ ../../X86/x86_xform_raw4.S
+
+ X86_OBJS = ../../X86/common_x86.o \
+ ../../X86/common_x86_asm.o \
+ ../../X86/x86.o \
+ ../../X86/x86_cliptest.o \
+ ../../X86/x86_vertex.o \
+ ../../X86/x86_xform_masked2.o \
+ ../../X86/x86_xform_masked3.o \
+ ../../X86/x86_xform_masked4.o \
+ ../../X86/x86_xform_raw2.o \
+ ../../X86/x86_xform_raw3.o \
+ ../../X86/x86_xform_raw4.o
+
+#if MesaUseMMX
+ MMX_SRCS = ../../X86/mmx_blend.S
+
+ MMX_OBJS = ../../X86/mmx_blend.o
+#endif
+
+#if MesaUse3DNow
+ 3DNOW_SRCS = ../../X86/3dnow.c \
+ ../../X86/3dnow_norm_raw.S \
+ ../../X86/3dnow_vertex.S \
+ ../../X86/3dnow_xform_masked1.S \
+ ../../X86/3dnow_xform_masked2.S \
+ ../../X86/3dnow_xform_masked3.S \
+ ../../X86/3dnow_xform_masked4.S \
+ ../../X86/3dnow_xform_raw1.S \
+ ../../X86/3dnow_xform_raw2.S \
+ ../../X86/3dnow_xform_raw3.S \
+ ../../X86/3dnow_xform_raw4.S
+
+ 3DNOW_OBJS = ../../X86/3dnow.o \
+ ../../X86/3dnow_norm_raw.o \
+ ../../X86/3dnow_vertex.o \
+ ../../X86/3dnow_xform_masked1.o \
+ ../../X86/3dnow_xform_masked2.o \
+ ../../X86/3dnow_xform_masked3.o \
+ ../../X86/3dnow_xform_masked4.o \
+ ../../X86/3dnow_xform_raw1.o \
+ ../../X86/3dnow_xform_raw2.o \
+ ../../X86/3dnow_xform_raw3.o \
+ ../../X86/3dnow_xform_raw4.o
+#endif
+
+#if MesaUseKatmai
+ KATMAI_SRCS = ../../X86/katmai.c \
+ ../../X86/katmai_norm_raw.S \
+ ../../X86/katmai_vertex.S \
+ ../../X86/katmai_xform_masked1.S \
+ ../../X86/katmai_xform_masked2.S \
+ ../../X86/katmai_xform_masked3.S \
+ ../../X86/katmai_xform_masked4.S \
+ ../../X86/katmai_xform_raw1.S \
+ ../../X86/katmai_xform_raw2.S \
+ ../../X86/katmai_xform_raw3.S \
+ ../../X86/katmai_xform_raw4.S
+
+ KATMAI_OBJS = ../../X86/katmai.o \
+ ../../X86/katmai_norm_raw.o \
+ ../../X86/katmai_vertex.o \
+ ../../X86/katmai_xform_masked1.o \
+ ../../X86/katmai_xform_masked2.o \
+ ../../X86/katmai_xform_masked3.o \
+ ../../X86/katmai_xform_masked4.o \
+ ../../X86/katmai_xform_raw1.o \
+ ../../X86/katmai_xform_raw2.o \
+ ../../X86/katmai_xform_raw3.o \
+ ../../X86/katmai_xform_raw4.o
+#endif
+#endif
+#endif
+
+#ifdef GlxSoProf
+ LOSRCS = ../../../../lowpc.c
+ HISRCS = ../../../../highpc.c
+
+ LOOBJS = ../../../../lowpc.o
+ HIOBJS = ../../../../highpc.o
+#endif
+
+ ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) $(KATMAI_SRCS)
+ ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) $(KATMAI_OBJS)
+
+ COMMONSRCS = ../common/mm.c ../common/hwlog.c
+ COMMONOBJS = ../common/mm.o ../common/hwlog.o
+
+ SRCS = $(LOSRCS) $(DRISRCS) $(DRMSRCS) $(MESASRCS) \
+ $(ASMSRCS) $(COMMONSRCS) $(RADEONSRCS) $(HISRCS)
+ OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) \
+ $(ASMOBJS) $(COMMONOBJS) $(RADEONOBJS) $(HIOBJS)
+
+REQUIREDLIBS += MathLibrary
+#if !GlxBuiltInRadeon
+REQUIREDLIBS += -L../../../.. -lGL
+#endif
+
+
+#if !GlxUseBuiltInDRIDriver
+#undef DoNormalLib NormalLibGlx
+#undef DoExtraLib SharedLibGlx
+#undef DoDebugLib DebugLibGlx
+#undef DoProfileLib ProfileLibGlx
+#endif
+
+#include <Library.tmpl>
+
+LibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+NormalLintTarget($(SRCS))
+
+#if !GlxUseBuiltInDRIDriver
+LIBNAME = radeon_dri.so
+ALL_OBJS = $(OBJS)
+ALL_DEPS = DONE
+SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri)
+
+#ifdef GlxSoProf
+SOPROF_LIBNAME = _radeon_dri_p
+NormalDepLibraryTarget($(SOPROF_LIBNAME),$(ALL_DEPS),$(ALL_OBJS))
+InstallLibrary($(SOPROF_LIBNAME),$(MODULEDIR)/dri)
+#endif
+#endif
+
+DependTarget()
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c
new file mode 100644
index 000000000..9af8b5691
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c
@@ -0,0 +1,234 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.1 2001/01/08 01:07:26 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include <stdlib.h>
+
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_dd.h"
+#include "radeon_state.h"
+#include "radeon_span.h"
+#include "radeon_tex.h"
+#include "radeon_vb.h"
+#include "radeon_pipeline.h"
+
+#include "context.h"
+#include "simple_list.h"
+#include "mem.h"
+
+#ifndef RADEON_DEBUG
+int RADEON_DEBUG = (0
+/* | DEBUG_ALWAYS_SYNC */
+/* | DEBUG_VERBOSE_API */
+/* | DEBUG_VERBOSE_MSG */
+/* | DEBUG_VERBOSE_LRU */
+/* | DEBUG_VERBOSE_DRI */
+/* | DEBUG_VERBOSE_IOCTL */
+/* | DEBUG_VERBOSE_2D */
+ );
+#endif
+
+/* Create the device specific context.
+ */
+GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual,
+ __DRIcontextPrivate *driContextPriv )
+{
+ GLcontext *ctx = driContextPriv->mesaContext;
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ radeonContextPtr rmesa;
+ radeonScreenPtr radeonScreen;
+ int i;
+
+ rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) );
+ if ( !rmesa ) return GL_FALSE;
+
+ rmesa->glCtx = ctx;
+ rmesa->display = dpy;
+
+ rmesa->driContext = driContextPriv;
+ rmesa->driScreen = sPriv;
+ rmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */
+
+ rmesa->hHWContext = driContextPriv->hHWContext;
+ rmesa->driHwLock = &sPriv->pSAREA->lock;
+ rmesa->driFd = sPriv->fd;
+
+ radeonScreen = rmesa->radeonScreen = (radeonScreenPtr)(sPriv->private);
+
+ rmesa->sarea = (RADEONSAREAPrivPtr)((char *)sPriv->pSAREA +
+ sizeof(XF86DRISAREARec));
+
+ rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+ if ( !rmesa->tmp_matrix ) {
+ FREE( rmesa );
+ return GL_FALSE;
+ }
+
+ make_empty_list( &rmesa->SwappedOut );
+
+ for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) {
+ rmesa->CurrentTexObj[i] = NULL;
+ make_empty_list( &rmesa->TexObjList[i] );
+ rmesa->texHeap[i] = mmInit( 0, radeonScreen->texSize[i] );
+ rmesa->lastTexAge[i] = -1;
+ }
+ rmesa->lastTexHeap = radeonScreen->numTexHeaps;
+
+ rmesa->RenderIndex = -1; /* Impossible value */
+ rmesa->OnFastPath = 0;
+
+ rmesa->vert_buf = NULL;
+ rmesa->num_verts = 0;
+
+ rmesa->elt_buf = NULL;
+ rmesa->retained_buf = NULL;
+ rmesa->vert_heap = radeonScreen->buffers->list->address;
+
+ /* KW: Set the maximum texture size small enough that we can
+ * guarentee that both texture units can bind a maximal texture
+ * and have them both in on-card memory at once. (Kevin or
+ * Gareth: Please check these numbers are OK)
+ */
+ if ( radeonScreen->texSize[0] < 2*1024*1024 ) {
+ ctx->Const.MaxTextureLevels = 9;
+ ctx->Const.MaxTextureSize = (1 << 8);
+ } else if ( radeonScreen->texSize[0] < 8*1024*1024 ) {
+ ctx->Const.MaxTextureLevels = 10;
+ ctx->Const.MaxTextureSize = (1 << 9);
+ } else {
+ ctx->Const.MaxTextureLevels = 11;
+ ctx->Const.MaxTextureSize = (1 << 10);
+ }
+
+ /* FIXME: Support all available texture units... */
+ ctx->Const.MaxTextureUnits = 2;
+
+#if ENABLE_PERF_BOXES
+ if (getenv("LIBGL_PERFORMANCE_BOXES"))
+ rmesa->boxes = 1;
+ else
+ rmesa->boxes = 0;
+#endif
+
+ ctx->DriverCtx = (void *)rmesa;
+
+ radeonDDInitExtensions( ctx );
+
+ radeonDDInitDriverFuncs( ctx );
+ radeonDDInitIoctlFuncs( ctx );
+ radeonDDInitStateFuncs( ctx );
+ radeonDDInitSpanFuncs( ctx );
+ radeonDDInitTextureFuncs( ctx );
+
+ ctx->Driver.TriangleCaps = (DD_TRI_CULL |
+ DD_TRI_LIGHT_TWOSIDE |
+ DD_TRI_STIPPLE |
+ DD_TRI_OFFSET);
+
+ /* Ask Mesa to clip fog coordinates for us.
+ */
+ ctx->TriangleCaps |= DD_CLIP_FOG_COORD;
+
+ if ( ctx->VB )
+ radeonDDRegisterVB( ctx->VB );
+
+ if ( ctx->NrPipelineStages ) {
+ ctx->NrPipelineStages =
+ radeonDDRegisterPipelineStages( ctx->PipelineStage,
+ ctx->PipelineStage,
+ ctx->NrPipelineStages );
+ }
+
+ radeonDDInitState( rmesa );
+
+ driContextPriv->driverPrivate = (void *)rmesa;
+
+ return GL_TRUE;
+}
+
+/* Destroy the device specific context.
+ */
+void radeonDestroyContext( radeonContextPtr rmesa )
+{
+ if ( rmesa ) {
+ radeonTexObjPtr t, next_t;
+ int i;
+
+ for ( i = 0 ; i < rmesa->radeonScreen->numTexHeaps ; i++ ) {
+ foreach_s ( t, next_t, &rmesa->TexObjList[i] ) {
+ radeonDestroyTexObj( rmesa, t );
+ }
+ mmDestroy( rmesa->texHeap[i] );
+ }
+
+ foreach_s ( t, next_t, &rmesa->SwappedOut ) {
+ radeonDestroyTexObj( rmesa, t );
+ }
+
+ ALIGN_FREE( rmesa->tmp_matrix );
+ FREE( rmesa );
+ }
+
+#if 0
+ /* Use this to force shared object profiling. */
+ glx_fini_prof();
+#endif
+}
+
+/* Load the device specific context into the hardware. The actual
+ * setting of the hardware state is done in the radeonUpdateHWState().
+ */
+radeonContextPtr radeonMakeCurrent( radeonContextPtr oldCtx,
+ radeonContextPtr newCtx,
+ __DRIdrawablePrivate *dPriv )
+{
+ if ( oldCtx ) {
+ if ( oldCtx != newCtx ) {
+ newCtx->new_state |= RADEON_NEW_CONTEXT;
+ newCtx->dirty = RADEON_UPLOAD_ALL;
+ }
+ if ( oldCtx->driDrawable != dPriv ) {
+ newCtx->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP;
+ }
+ } else {
+ newCtx->new_state |= RADEON_NEW_CONTEXT;
+ newCtx->dirty = RADEON_UPLOAD_ALL;
+ }
+
+ newCtx->driDrawable = dPriv;
+
+ return newCtx;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h
new file mode 100644
index 000000000..cae9d5b30
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h
@@ -0,0 +1,253 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.1 2001/01/08 01:07:26 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_CONTEXT_H__
+#define __RADEON_CONTEXT_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlibint.h>
+
+#include "dri_mesaint.h"
+#include "dri_tmm.h"
+
+#include "xf86drm.h"
+#include "xf86drmRadeon.h"
+
+#include "types.h"
+
+#include "radeon_sarea.h"
+#include "radeon_reg.h"
+
+struct radeon_context;
+typedef struct radeon_context radeonContextRec;
+typedef struct radeon_context *radeonContextPtr;
+
+#include "radeon_lock.h"
+#include "radeon_texobj.h"
+#include "radeon_screen.h"
+
+/* Flags for what context state needs to be updated */
+#define RADEON_NEW_ALPHA 0x0001
+#define RADEON_NEW_DEPTH 0x0002
+#define RADEON_NEW_FOG 0x0004
+#define RADEON_NEW_CLIP 0x0008
+#define RADEON_NEW_CULL 0x0010
+#define RADEON_NEW_MASKS 0x0020
+#define RADEON_NEW_WINDOW 0x0040
+#define RADEON_NEW_TEXTURE 0x0080
+#define RADEON_NEW_CONTEXT 0x0100
+#define RADEON_NEW_ALL 0x01ff
+
+/* Flags for software fallback cases */
+#define RADEON_FALLBACK_TEXTURE 0x0001
+#define RADEON_FALLBACK_DRAW_BUFFER 0x0002
+#define RADEON_FALLBACK_READ_BUFFER 0x0004
+#define RADEON_FALLBACK_STENCIL 0x0008
+#define RADEON_FALLBACK_RENDER_MODE 0x0010
+#define RADEON_FALLBACK_MULTIDRAW 0x0020
+#define RADEON_FALLBACK_LOGICOP 0x0040
+
+typedef void (*radeon_interp_func)( GLfloat t,
+ GLfloat *result,
+ const GLfloat *in,
+ const GLfloat *out );
+
+struct radeon_elt_tab {
+ void (*emit_unclipped_verts)( struct vertex_buffer *VB );
+
+ void (*build_tri_verts)( radeonContextPtr rmesa,
+ struct vertex_buffer *VB,
+ GLfloat *O, GLuint *elt );
+
+ void (*interp)( GLfloat t, GLfloat *O,
+ const GLfloat *I, const GLfloat *J );
+
+ void (*project_and_emit_verts)( radeonContextPtr rmesa,
+ const GLfloat *verts,
+ GLuint *elts,
+ GLuint nr );
+};
+
+struct radeon_context {
+ GLcontext *glCtx; /* Mesa context */
+
+ /* Driver and hardware state management
+ */
+ GLuint new_state;
+ GLuint dirty; /* Hardware state to be updated */
+ radeon_context_regs_t setup;
+
+ GLuint vertsize;
+ GLuint vc_format;
+ GLfloat depth_scale;
+
+ CARD32 Color; /* Current draw color */
+ CARD32 ClearColor; /* Color used to clear color buffer */
+ CARD32 ClearDepth; /* Value used to clear depth buffer */
+ CARD32 ClearStencil; /* Value used to clear stencil */
+
+ /* Map GL texture units onto hardware
+ */
+ GLint multitex;
+ GLint tmu_source[RADEON_MAX_TEXTURE_UNITS];
+ GLint tex_dest[RADEON_MAX_TEXTURE_UNITS];
+ GLuint color_combine[RADEON_MAX_TEXTURE_UNITS];
+ GLuint alpha_combine[RADEON_MAX_TEXTURE_UNITS];
+ GLuint env_color[RADEON_MAX_TEXTURE_UNITS];
+ GLuint lod_bias[RADEON_MAX_TEXTURE_UNITS];
+
+ /* Texture object bookkeeping
+ */
+ radeonTexObjPtr CurrentTexObj[RADEON_MAX_TEXTURE_UNITS];
+ radeonTexObj TexObjList[RADEON_NR_TEX_HEAPS];
+ radeonTexObj SwappedOut;
+ memHeap_t *texHeap[RADEON_NR_TEX_HEAPS];
+ GLint lastTexAge[RADEON_NR_TEX_HEAPS];
+ GLint lastTexHeap;
+
+ /* Current rendering state, fallbacks
+ */
+ points_func PointsFunc;
+ line_func LineFunc;
+ triangle_func TriangleFunc;
+ quad_func QuadFunc;
+
+ GLuint IndirectTriangles;
+ GLuint Fallback;
+
+ /* Fast path
+ */
+ GLuint SetupIndex;
+ GLuint SetupDone;
+ GLuint RenderIndex;
+ GLuint OnFastPath;
+ radeon_interp_func interp;
+ GLfloat *tmp_matrix;
+
+ /* Vertex buffers
+ */
+ drmBufPtr vert_buf;
+ GLuint vert_prim;
+ GLuint num_verts;
+
+ /* Elt path
+ */
+ drmBufPtr elt_buf, retained_buf;
+ GLushort *first_elt, *next_elt;
+ GLfloat *next_vert, *vert_heap;
+ GLushort next_vert_index;
+ GLushort first_vert_index;
+ GLuint elt_vertsize;
+ struct radeon_elt_tab *elt_tab;
+ GLfloat device_matrix[16];
+
+ /* Page flipping
+ */
+ GLuint doPageFlip;
+ GLuint currentPage;
+
+ /* Drawable, cliprect and scissor information
+ */
+ GLenum DrawBuffer; /* Optimize draw buffer update */
+ GLint drawOffset, drawPitch;
+ GLint readOffset, readPitch;
+
+ GLuint numClipRects; /* Cliprects for the draw buffer */
+ XF86DRIClipRectPtr pClipRects;
+
+ GLuint scissor;
+ XF86DRIClipRectRec scissor_rect; /* Current software scissor */
+
+ /* Mirrors of some DRI state
+ */
+ Display *display; /* X server display */
+
+ __DRIcontextPrivate *driContext; /* DRI context */
+ __DRIscreenPrivate *driScreen; /* DRI screen */
+ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
+
+ drmContext hHWContext;
+ drmLock *driHwLock;
+ int driFd;
+
+ radeonScreenPtr radeonScreen; /* Screen private DRI data */
+ RADEONSAREAPrivPtr sarea; /* Private SAREA data */
+
+ /* Performance counters
+ */
+ GLuint boxes; /* Draw performance boxes */
+ GLuint hardwareWentIdle;
+ GLuint c_clears;
+ GLuint c_drawWaits;
+ GLuint c_textureSwaps;
+ GLuint c_textureBytes;
+ GLuint c_vertexBuffers;
+};
+
+#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx))
+
+
+extern GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual,
+ __DRIcontextPrivate *driContextPriv );
+extern void radeonDestroyContext( radeonContextPtr rmesa );
+extern radeonContextPtr radeonMakeCurrent( radeonContextPtr oldCtx,
+ radeonContextPtr newCtx,
+ __DRIdrawablePrivate *dPriv );
+
+
+/* ================================================================
+ * Debugging:
+ */
+#define DO_DEBUG 0
+#define ENABLE_PERF_BOXES 0
+
+#if DO_DEBUG
+extern int RADEON_DEBUG;
+#else
+#define RADEON_DEBUG 0
+#endif
+
+#define DEBUG_ALWAYS_SYNC 0x01
+#define DEBUG_VERBOSE_API 0x02
+#define DEBUG_VERBOSE_MSG 0x04
+#define DEBUG_VERBOSE_LRU 0x08
+#define DEBUG_VERBOSE_DRI 0x10
+#define DEBUG_VERBOSE_IOCTL 0x20
+#define DEBUG_VERBOSE_2D 0x40
+
+#endif
+#endif /* __RADEON_CONTEXT_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
new file mode 100644
index 000000000..52cf810cc
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c
@@ -0,0 +1,217 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c,v 1.3 2001/01/21 21:19:09 tsi Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_state.h"
+#include "radeon_vb.h"
+#include "radeon_pipeline.h"
+#include "radeon_dd.h"
+
+#include "extensions.h"
+#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM)
+#include "X86/common_x86_asm.h"
+#endif
+
+#define RADEON_DATE "20010105"
+
+
+/* Return the width and height of the current color buffer.
+ */
+static void radeonDDGetBufferSize( GLcontext *ctx,
+ GLuint *width, GLuint *height )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ LOCK_HARDWARE( rmesa );
+ *width = rmesa->driDrawable->w;
+ *height = rmesa->driDrawable->h;
+ UNLOCK_HARDWARE( rmesa );
+}
+
+/* Return various strings for glGetString().
+ */
+static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ static char buffer[128];
+
+ switch ( name ) {
+ case GL_VENDOR:
+ return (GLubyte *)"VA Linux Systems, Inc.";
+
+ case GL_RENDERER:
+ sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE );
+
+ /* Append any chipset-specific information. None yet.
+ */
+
+ /* Append any AGP-specific information.
+ */
+ switch ( rmesa->radeonScreen->AGPMode ) {
+ case 1:
+ strncat( buffer, " AGP 1x", 7 );
+ break;
+ case 2:
+ strncat( buffer, " AGP 2x", 7 );
+ break;
+ case 4:
+ strncat( buffer, " AGP 4x", 7 );
+ break;
+ }
+
+ /* Append any CPU-specific information.
+ */
+#ifdef USE_X86_ASM
+ if ( gl_x86_cpu_features ) {
+ strncat( buffer, " x86", 4 );
+ }
+#endif
+#ifdef USE_3DNOW_ASM
+ if ( cpu_has_3dnow ) {
+ strncat( buffer, "/3DNow!", 7 );
+ }
+#endif
+#ifdef USE_KATMAI_ASM
+ if ( cpu_has_xmm ) {
+ strncat( buffer, "/SSE", 4 );
+ }
+#endif
+ return (GLubyte *)buffer;
+
+ default:
+ return NULL;
+ }
+}
+
+/* Send all commands to the hardware. If vertex buffers or indirect
+ * buffers are in use, then we need to make sure they are sent to the
+ * hardware. All commands that are normally sent to the ring are
+ * already considered `flushed'.
+ */
+static void radeonDDFlush( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+
+#if ENABLE_PERF_BOXES
+ if ( rmesa->boxes ) {
+ LOCK_HARDWARE( rmesa );
+ radeonPerformanceBoxesLocked( rmesa );
+ UNLOCK_HARDWARE( rmesa );
+ }
+
+ /* Log the performance counters if necessary */
+ radeonPerformanceCounters( rmesa );
+#endif
+}
+
+/* Make sure all commands have been sent to the hardware and have
+ * completed processing.
+ */
+static void radeonDDFinish( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+#if ENABLE_PERF_BOXES
+ /* Bump the performance counter */
+ rmesa->c_drawWaits++;
+#endif
+
+ radeonDDFlush( ctx );
+ radeonWaitForIdle( rmesa );
+}
+
+/* Return various parameters requested by Mesa (this is deprecated).
+ */
+static GLint radeonDDGetParameteri( const GLcontext *ctx, GLint param )
+{
+ switch ( param ) {
+ case DD_HAVE_HARDWARE_FOG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Initialize the extensions supported by this driver.
+ */
+void radeonDDInitExtensions( GLcontext *ctx )
+{
+ gl_extensions_disable( ctx, "GL_ARB_imaging" );
+ gl_extensions_disable( ctx, "GL_ARB_texture_compression" );
+ gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" );
+
+ gl_extensions_disable( ctx, "GL_EXT_blend_color" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_minmax" );
+ gl_extensions_disable( ctx, "GL_EXT_blend_subtract" );
+ gl_extensions_disable( ctx, "GL_EXT_convolution" );
+ gl_extensions_disable( ctx, "GL_EXT_paletted_texture" );
+ gl_extensions_disable( ctx, "GL_EXT_point_parameters" );
+ gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" );
+ gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" );
+ gl_extensions_enable( ctx, "GL_EXT_texture_env_dot3" );
+
+ gl_extensions_disable( ctx, "GL_HP_occlusion_test" );
+
+ gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" );
+
+ gl_extensions_disable( ctx, "GL_SGI_color_matrix" );
+ gl_extensions_disable( ctx, "GL_SGI_color_table" );
+ gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" );
+}
+
+/* Initialize the driver's misc functions.
+ */
+void radeonDDInitDriverFuncs( GLcontext *ctx )
+{
+ ctx->Driver.GetBufferSize = radeonDDGetBufferSize;
+ ctx->Driver.GetString = radeonDDGetString;
+ ctx->Driver.Finish = radeonDDFinish;
+ ctx->Driver.Flush = radeonDDFlush;
+
+ ctx->Driver.Error = NULL;
+ ctx->Driver.GetParameteri = radeonDDGetParameteri;
+
+ ctx->Driver.DrawPixels = NULL;
+ ctx->Driver.Bitmap = NULL;
+
+ ctx->Driver.RegisterVB = radeonDDRegisterVB;
+ ctx->Driver.UnregisterVB = radeonDDUnregisterVB;
+ ctx->Driver.BuildPrecalcPipeline = radeonDDBuildPrecalcPipeline;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h
new file mode 100644
index 000000000..5e16e5e62
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h
@@ -0,0 +1,46 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h,v 1.1 2001/01/08 01:07:26 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_DD_H__
+#define __RADEON_DD_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void radeonDDInitExtensions( GLcontext *ctx );
+extern void radeonDDInitDriverFuncs( GLcontext *ctx );
+
+#endif
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c
new file mode 100644
index 000000000..6b2f36614
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c
@@ -0,0 +1,504 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c,v 1.1 2001/01/08 01:07:26 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ * Keith Whitwell <keithw@valinux.com>
+ *
+ */
+
+#include <stdio.h>
+
+#include "radeon_context.h"
+#include "radeon_pipeline.h"
+#include "radeon_ioctl.h"
+#include "radeon_tris.h"
+#include "radeon_state.h"
+#include "radeon_vb.h"
+
+#include "types.h"
+#include "enums.h"
+#include "cva.h"
+#include "vertices.h"
+#include "mmath.h"
+#include "xform.h"
+
+/* Always use a full-sized stride for vertices. [FIXME]
+ * Stride in the buffers must be a quadword multiple.
+ */
+#define CLIP_STRIDE 10
+
+static void fire_elts( radeonContextPtr rmesa )
+{
+ GLuint vertsize = rmesa->vertsize;
+
+ LOCK_HARDWARE( rmesa );
+
+ /* Fire queued elements and discard that buffer if its contents
+ * won't be referenced by future elements.
+ */
+ if ( rmesa->elt_buf )
+ {
+ GLuint retain = (rmesa->elt_buf == rmesa->retained_buf);
+
+ if ( rmesa->first_elt != rmesa->next_elt ) {
+ radeonFireEltsLocked( rmesa,
+ ((GLuint)rmesa->first_elt -
+ (GLuint)rmesa->elt_buf->address),
+ ((GLuint)rmesa->next_elt -
+ (GLuint)rmesa->elt_buf->address),
+ !retain );
+ } else if ( !retain ) {
+ radeonReleaseBufLocked( rmesa, rmesa->elt_buf );
+ }
+
+ rmesa->elt_buf = 0;
+ }
+ else if ( rmesa->vert_buf )
+ {
+ radeonFlushVerticesLocked( rmesa );
+ }
+
+ radeonGetEltBufLocked( rmesa );
+
+ UNLOCK_HARDWARE( rmesa );
+
+ /* Give the compiler a chance to optimize the divisions.
+ */
+ switch ( vertsize ) {
+ case 8:
+ rmesa->next_vert_index = (GLushort)
+ (((rmesa->elt_buf->idx + 1) *
+ RADEON_BUFFER_SIZE / (8 * sizeof(GLuint))) - 1);
+ rmesa->next_vert = (GLfloat *)
+ ((GLuint)rmesa->vert_heap +
+ rmesa->next_vert_index * 8 * sizeof(GLfloat));
+ break;
+
+ case 10:
+ rmesa->next_vert_index = (GLushort)
+ (((rmesa->elt_buf->idx + 1) *
+ RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) - 1);
+ rmesa->next_vert = (GLfloat *)
+ ((GLuint)rmesa->vert_heap +
+ rmesa->next_vert_index * 10 * sizeof(GLfloat));
+ break;
+ }
+
+ rmesa->first_elt = rmesa->next_elt = (GLushort *)
+ ((GLubyte *)rmesa->elt_buf->address + RADEON_INDEX_PRIM_OFFSET);
+
+ rmesa->elt_vertsize = vertsize;
+}
+
+
+static void release_bufs( radeonContextPtr rmesa )
+{
+ if ( rmesa->retained_buf && rmesa->retained_buf != rmesa->elt_buf )
+ {
+ LOCK_HARDWARE( rmesa );
+ if ( rmesa->first_elt != rmesa->next_elt ) {
+ radeonFireEltsLocked( rmesa,
+ ((GLuint)rmesa->first_elt -
+ (GLuint)rmesa->elt_buf->address),
+ ((GLuint)rmesa->next_elt -
+ (GLuint)rmesa->elt_buf->address),
+ 0 );
+
+ ALIGN_NEXT_ELT( rmesa );
+ rmesa->first_elt = rmesa->next_elt;
+ }
+
+ radeonReleaseBufLocked( rmesa, rmesa->retained_buf );
+ UNLOCK_HARDWARE( rmesa );
+ }
+
+ rmesa->retained_buf = 0;
+}
+
+
+
+
+#define NEGATIVE( f ) (f < 0)
+#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0)
+#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A)))
+
+
+#define INTERP_RGBA( t, out, a, b ) { \
+ GLuint i; \
+ for ( i = 0 ; i < 4 ; i++ ) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \
+ GLfloat fo = LINTERP( t, fa, fb ); \
+ FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \
+ } \
+}
+
+
+#define CLIP( SGN, V, PLANE ) \
+do { \
+ if ( mask & PLANE ) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]]; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ for ( i = n = 0 ; i < nr ; i++ ) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i]; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \
+ GLfloat *O = verts[next_vert]; \
+ outdata[n++] = next_vert++; \
+ \
+ if ( NEGATIVE( dpI ) ) { \
+ GLfloat t = dpI / (dpI - dpJ); \
+ interp( t, O, I, J ); \
+ } \
+ else \
+ { \
+ GLfloat t = dpJ / (dpJ - dpI); \
+ interp( t, O, J, I ); \
+ } \
+ } \
+ \
+ if ( !NEGATIVE( dpI ) ) \
+ outdata[n++] = elt_i; \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if ( n < 3 ) return; \
+ } \
+} while (0)
+
+
+static void radeon_tri_clip( radeonContextPtr rmesa,
+ struct vertex_buffer *VB,
+ GLuint *elt,
+ GLubyte mask )
+{
+ struct radeon_elt_tab *tab = rmesa->elt_tab;
+ radeon_interp_func interp = tab->interp;
+ GLuint vertsize = rmesa->vertsize;
+ GLuint inlist[2][VB_MAX_CLIPPED_VERTS];
+ GLuint in = 0;
+ GLuint n = 3, next_vert = 3;
+ GLuint i;
+ GLfloat verts[VB_MAX_CLIPPED_VERTS][CLIP_STRIDE];
+
+ /* Build temporary vertices in clipspace. This is the potential
+ * downside to this path.
+ */
+ tab->build_tri_verts( rmesa, VB, (GLfloat *)verts, elt );
+
+ inlist[0][0] = 0;
+ inlist[0][1] = 1;
+ inlist[0][2] = 2;
+
+ CLIP( -, 0, CLIP_RIGHT_BIT );
+ CLIP( +, 0, CLIP_LEFT_BIT );
+ CLIP( -, 1, CLIP_TOP_BIT );
+ CLIP( +, 1, CLIP_BOTTOM_BIT );
+ CLIP( -, 2, CLIP_FAR_BIT );
+ CLIP( +, 2, CLIP_NEAR_BIT );
+
+
+ {
+ GLuint *out = inlist[in];
+ GLint space = (GLint)((GLuint)rmesa->next_vert -
+ (GLuint)rmesa->next_elt);
+
+ if ( space < (GLint)(n * (vertsize + 2) * sizeof(GLuint)) ) {
+ fire_elts( rmesa );
+ }
+
+ /* Project the new vertices and emit to dma buffers. Translate
+ * out values to physical addresses for setup dma.
+ */
+ tab->project_and_emit_verts( rmesa, (GLfloat *)verts, out, n );
+
+ /* Convert the planar polygon to a list of triangles and emit to
+ * elt buffers.
+ */
+ for ( i = 2 ; i < n ; i++ ) {
+ rmesa->next_elt[0] = (GLushort) out[0];
+ rmesa->next_elt[1] = (GLushort) out[i-1];
+ rmesa->next_elt[2] = (GLushort) out[i];
+ rmesa->next_elt += 3;
+ }
+ }
+}
+
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+
+#define INIT( x )
+
+#define TRI_THRESHOLD (GLint)(2 * sizeof(GLuint))
+
+#define UNCLIPPED_VERT( x ) (GLushort)(rmesa->first_vert_index - x)
+
+#define TRIANGLE( e2, e1, e0 ) \
+do { \
+ if ( (GLint)((GLuint)rmesa->next_vert - \
+ (GLuint)rmesa->next_elt) < TRI_THRESHOLD ) { \
+ fire_elts( rmesa ); \
+ } \
+ rmesa->next_elt[0] = UNCLIPPED_VERT( e2 ); \
+ rmesa->next_elt[1] = UNCLIPPED_VERT( e1 ); \
+ rmesa->next_elt[2] = UNCLIPPED_VERT( e0 ); \
+ rmesa->next_elt += 3; \
+} while (0)
+
+#define CLIP_TRIANGLE( e2, e1, e0 ) \
+do { \
+ GLubyte ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if ( ormask == 0 ) { \
+ TRIANGLE( e2, e1, e0 ); \
+ } else if ( (mask[e2] & mask[e1] & mask[e0]) == 0 ) { \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ radeon_tri_clip( rmesa, VB, out, ormask ); \
+ } \
+} while (0)
+
+#define LOCAL_VARS \
+ radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \
+ GLuint *elt = VB->EltPtr->data; \
+ GLuint out[VB_MAX_CLIPPED_VERTS]; \
+ GLubyte *mask = VB->ClipMask; \
+ (void) mask; (void) out; (void) elt; (void) rmesa;
+
+
+
+#define RENDER_POINTS( start, count )
+#define RENDER_LINE( i1, i0 )
+#define RENDER_TRI( i2, i1, i0, pv, parity ) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if ( parity ) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD( i3, i2, i1, i0, pv ) \
+ CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \
+ CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] )
+
+#define TAG(x) radeon_##x##_elt
+#include "render_tmp.h"
+
+
+
+#define LOCAL_VARS \
+ radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \
+ GLuint *elt = VB->EltPtr->data; \
+ (void) elt; (void) rmesa;
+
+#define RENDER_POINTS( start, count )
+#define RENDER_LINE( i1, i0 )
+#define RENDER_TRI( i2, i1, i0, pv, parity ) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if ( parity ) e2 = elt[i1], e1 = elt[i2]; \
+ TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD( i3, i2, i1, i0, pv ) \
+ TRIANGLE( elt[i3], elt[i2], elt[i0] ); \
+ TRIANGLE( elt[i2], elt[i1], elt[i0] )
+
+#define TAG(x) radeon_##x##_elt_unclipped
+#include "render_tmp.h"
+
+
+
+
+static void refresh_projection_matrix( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ GLfloat *m = rmesa->device_matrix;
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY];
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+}
+
+#define CLIP_UBYTE_R 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_B 2
+#define CLIP_UBYTE_A 3
+
+
+#define TYPE (0)
+#define TAG(x) x
+#include "radeon_elttmp.h"
+
+#define TYPE (RADEON_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "radeon_elttmp.h"
+
+#define TYPE (RADEON_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "radeon_elttmp.h"
+
+#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "radeon_elttmp.h"
+
+#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "radeon_elttmp.h"
+
+#define TYPE (RADEON_TEX0_BIT|RADEON_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "radeon_elttmp.h"
+
+
+/* Very sparsely popluated array - fix the indices.
+ */
+static struct radeon_elt_tab radeonEltTab[RADEON_MAX_SETUPFUNC];
+
+void radeonDDEltPathInit( void )
+{
+ radeon_render_init_elt();
+ radeon_render_init_elt_unclipped();
+
+ radeon_init_eltpath( &radeonEltTab[0] );
+ radeon_init_eltpath_RGBA( &radeonEltTab[RADEON_RGBA_BIT] );
+ radeon_init_eltpath_TEX0( &radeonEltTab[RADEON_TEX0_BIT] );
+ radeon_init_eltpath_RGBA_TEX0( &radeonEltTab[(RADEON_RGBA_BIT |
+ RADEON_TEX0_BIT)] );
+ radeon_init_eltpath_TEX0_TEX1( &radeonEltTab[(RADEON_TEX0_BIT |
+ RADEON_TEX1_BIT)] );
+ radeon_init_eltpath_RGBA_TEX0_TEX1( &radeonEltTab[(RADEON_RGBA_BIT |
+ RADEON_TEX0_BIT |
+ RADEON_TEX1_BIT)] );
+}
+
+#define VALID_SETUP (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT)
+
+
+
+/* Use a temporary array for device coordinates, so that we can easily
+ * tap into existing mesa assembly. Otherwise consider emitting
+ * device coordinates to dma buffers directly from the project/cliptest
+ * routine. (requires output stride, potential loss of writecombining
+ * efficiency?)
+ *
+ * This path is a lot closer to the standard vertex path in the
+ * initial stages than the original fastpath. A slightly more optimal
+ * path could be constructed, but would require us to write new
+ * assembly.
+ */
+void radeonDDEltPath( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct radeon_elt_tab *tab =
+ &radeonEltTab[rmesa->SetupIndex & VALID_SETUP];
+ GLint vertsize = rmesa->vertsize;
+ GLint space;
+
+ VB->ClipPtr = TransformRaw( &VB->Clip,
+ &ctx->ModelProjectMatrix,
+ VB->ObjPtr );
+
+ refresh_projection_matrix( ctx );
+
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
+ &VB->Win,
+ VB->ClipMask,
+ &VB->ClipOrMask,
+ &VB->ClipAndMask );
+
+ if ( VB->ClipAndMask )
+ return;
+
+ if ( rmesa->vert_buf )
+ radeonFlushVertices( rmesa );
+
+ if ( rmesa->new_state )
+ radeonDDUpdateHWState( ctx );
+
+ space = (GLint)((GLuint)rmesa->next_vert -
+ (GLuint)rmesa->next_elt);
+
+ /* Allocate a single buffer to hold unclipped vertices. All
+ * unclipped vertices must be contiguous.
+ */
+ if ( space < (GLint)(VB->Count * vertsize * sizeof(GLuint)) ||
+ rmesa->vertsize != rmesa->elt_vertsize ) {
+ fire_elts( rmesa );
+ }
+
+ rmesa->retained_buf = rmesa->elt_buf;
+
+ /* Emit unclipped vertices to the buffer.
+ */
+ tab->emit_unclipped_verts( VB );
+
+ /* Emit indices and clipped vertices to one or more buffers.
+ */
+ if ( VB->ClipOrMask ) {
+ rmesa->elt_tab = tab;
+ radeon_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 );
+ } else {
+ radeon_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 );
+ }
+
+ /* Send to hardware and release the elt buffer.
+ */
+ release_bufs( rmesa );
+
+ /* This indicates that there is no cached data to reuse.
+ */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+
+ FLUSH_BATCH( rmesa );
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h
new file mode 100644
index 000000000..56c0ccedd
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h
@@ -0,0 +1,246 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+/* Buffers fill from high addresses down with vertices and from low
+ * addresses up with elements.
+ */
+
+
+/* Emit the bulk of the vertices to the first dma buffer. Leave
+ * empty slots for clipped vertices so that we can still address
+ * vertices by index.
+ */
+static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx);
+ GLfloat *dev = VB->Projected->start;
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+ GLuint buffer_stride = rmesa->vertsize;
+
+ GLfloat *f = rmesa->next_vert;
+ GLuint count = VB->Count;
+ GLubyte *clipmask = VB->ClipMask;
+
+ const GLfloat *m = rmesa->device_matrix;
+ const GLfloat sx = m[0], sy = m[5], sz = m[10];
+ const GLfloat tx = m[12], ty = m[13], tz = m[14];
+ GLuint i;
+
+ rmesa->retained_buf = rmesa->elt_buf;
+ rmesa->first_vert_index = rmesa->next_vert_index;
+
+ for ( i = 0 ; i < count ; f -= buffer_stride, i++ )
+ {
+ if ( !clipmask[i] )
+ {
+ f[0] = sx * dev[0] + tx;
+ f[1] = sy * dev[1] + ty;
+ f[2] = sz * dev[2] + tz;
+ f[3] = dev[3];
+
+ if ( TYPE & RADEON_RGBA_BIT ) {
+ *(GLuint *)&f[4] = *(GLuint *)color;
+ }
+
+ if ( TYPE & RADEON_TEX0_BIT ) {
+ *(GLuint *)&f[6] = *(GLuint *)&tex0_data[0];
+ *(GLuint *)&f[7] = *(GLuint *)&tex0_data[1];
+ }
+
+ if ( TYPE & RADEON_TEX1_BIT ) {
+ *(GLuint *)&f[8] = *(GLuint *)&tex1_data[0];
+ *(GLuint *)&f[9] = *(GLuint *)&tex1_data[1];
+ }
+ }
+
+ STRIDE_F( dev, 16 );
+ if ( TYPE & RADEON_RGBA_BIT ) color += color_stride;
+ if ( TYPE & RADEON_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride );
+ if ( TYPE & RADEON_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride );
+ }
+
+ rmesa->next_vert = f;
+ rmesa->next_vert_index -= count;
+}
+
+
+/* Build three temporary clipspace vertex for clipping a triangle.
+ * Recreate from the VB data rather than trying to read back from
+ * uncached memory.
+ */
+static void TAG(build_tri_verts)( radeonContextPtr rmesa,
+ struct vertex_buffer *VB,
+ GLfloat *O,
+ GLuint *elt )
+{
+ GLint i;
+
+ for ( i = 0 ; i < 3 ; i++, O += CLIP_STRIDE ) {
+ GLfloat *clip = VB->Clip.start + elt[i]*4;
+
+ O[0] = clip[0];
+ O[1] = clip[1];
+ O[2] = clip[2];
+ O[3] = clip[3];
+
+ if ( TYPE & RADEON_RGBA_BIT ) {
+ GLubyte *color = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]);
+ *(GLuint *)&O[4] = *(GLuint *)color;
+ }
+
+ *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]);
+
+ if ( TYPE & RADEON_TEX0_BIT ) {
+ GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]);
+ *(GLuint *)&O[6] = *(GLuint *)&tex0_data[0];
+ *(GLuint *)&O[7] = *(GLuint *)&tex0_data[1];
+ }
+
+ if ( TYPE & RADEON_TEX1_BIT ) {
+ GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]);
+ *(GLuint *)&O[8] = *(GLuint *)&tex1_data[0];
+ *(GLuint *)&O[9] = *(GLuint *)&tex1_data[1];
+ }
+ }
+}
+
+
+/* Interpolate between two of the vertices constructed above.
+ */
+static void TAG(interp)( GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J )
+{
+ O[0] = LINTERP( t, I[0], J[0] );
+ O[1] = LINTERP( t, I[1], J[1] );
+ O[2] = LINTERP( t, I[2], J[2] );
+ O[3] = LINTERP( t, I[3], J[3] );
+
+ if ( TYPE & RADEON_RGBA_BIT ) {
+ INTERP_RGBA( t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])) );
+ }
+
+ *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */
+
+ if ( TYPE & RADEON_TEX0_BIT ) {
+ O[6] = LINTERP( t, I[6], J[6] );
+ O[7] = LINTERP( t, I[7], J[7] );
+ }
+
+ if ( TYPE & RADEON_TEX1_BIT ) {
+ O[8] = LINTERP( t, I[8], J[8] );
+ O[9] = LINTERP( t, I[9], J[9] );
+ }
+}
+
+
+
+/* When clipping is complete, scan the final vertex list and emit any
+ * new ones to dma buffers. Update the element list to a format
+ * suitable for sending to hardware.
+ */
+static void TAG(project_and_emit_verts)( radeonContextPtr rmesa,
+ const GLfloat *verts,
+ GLuint *elt,
+ GLuint nr)
+{
+ GLfloat *O = rmesa->next_vert;
+ GLushort index = rmesa->next_vert_index;
+ GLuint buffer_stride = rmesa->vertsize;
+
+ const GLfloat *m = rmesa->device_matrix;
+ const GLfloat sx = m[0], sy = m[5], sz = m[10];
+ const GLfloat tx = m[12], ty = m[13], tz = m[14];
+ GLuint i;
+
+ for ( i = 0 ; i < nr ; i++ ) {
+ const GLfloat *I = &verts[elt[i] * CLIP_STRIDE];
+ GLuint tmp = *(GLuint *)&I[5];
+
+ if ( (elt[i] = tmp) == ~0 ) {
+ GLfloat oow = 1.0 / I[3];
+
+ elt[i] = index--;
+
+ O[0] = sx * I[0] * oow + tx;
+ O[1] = sy * I[1] * oow + ty;
+ O[2] = sz * I[2] * oow + tz;
+ O[3] = oow;
+
+ if ( TYPE & RADEON_RGBA_BIT ) {
+ *(GLuint *)&O[4] = *(GLuint *)&I[4];
+ }
+
+ if ( TYPE & RADEON_TEX0_BIT ) {
+ *(GLuint *)&O[6] = *(GLuint *)&I[6];
+ *(GLuint *)&O[7] = *(GLuint *)&I[7];
+ }
+
+ if ( TYPE & RADEON_TEX1_BIT ) {
+ *(GLuint *)&O[8] = *(GLuint *)&I[8];
+ *(GLuint *)&O[9] = *(GLuint *)&I[9];
+ }
+
+ O -= buffer_stride;
+ }
+ }
+
+ rmesa->next_vert = O;
+ rmesa->next_vert_index = index;
+}
+
+
+
+static void TAG(radeon_init_eltpath)( struct radeon_elt_tab *tab )
+{
+ tab->emit_unclipped_verts = TAG(emit_unclipped_verts);
+ tab->build_tri_verts = TAG(build_tri_verts);
+ tab->interp = TAG(interp);
+ tab->project_and_emit_verts = TAG(project_and_emit_verts);
+}
+
+#undef TYPE
+#undef TAG
+#undef STRIDE
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c
new file mode 100644
index 000000000..1ff701435
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c
@@ -0,0 +1,542 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@valinux.com>
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_state.h"
+#include "radeon_vb.h"
+#include "radeon_pipeline.h"
+#include "radeon_ioctl.h"
+#include "radeon_tris.h"
+
+#include "mmath.h"
+#include "cva.h"
+#include "vertices.h"
+
+
+struct radeon_fast_tab {
+ void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest );
+ void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J );
+};
+
+#define POINT(x) radeon_draw_point( rmesa, &vert[x], psize )
+#define LINE(x,y) radeon_draw_line( rmesa, &vert[x], &vert[y], lwidth )
+#define TRI(x,y,z) radeon_draw_triangle( rmesa, &vert[x], &vert[y], &vert[z] )
+
+
+/* Direct, and no clipping required. The clip funcs have not been
+ * written yet, so this is only useful for the fast path.
+ */
+#define RENDER_POINTS( start, count ) \
+do { \
+ GLuint e; \
+ for ( e = start ; e < count ; e++ ) \
+ POINT( elt[e] ); \
+} while (0)
+
+#define RENDER_LINE( i1, i ) \
+do { \
+ GLuint e1 = elt[i1], e = elt[i]; \
+ LINE( e1, e ); \
+} while (0)
+
+#define RENDER_TRI( i2, i1, i, pv, parity ) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ if ( parity ) { \
+ GLuint tmp = e2; \
+ e2 = e1; \
+ e1 = tmp; \
+ } \
+ TRI( e2, e1, e ); \
+} while (0)
+
+#define RENDER_QUAD( i3, i2, i1, i, pv ) \
+do { \
+ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \
+ TRI( e3, e2, e ); \
+ TRI( e2, e1, e ); \
+} while (0)
+
+#define LOCAL_VARS \
+ radeonVertexPtr vert = RADEON_DRIVER_DATA(VB)->verts; \
+ const GLuint *elt = VB->EltPtr->data; \
+ GLcontext *ctx = VB->ctx; \
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
+ const GLfloat lwidth = ctx->Line.Width; \
+ const GLfloat psize = ctx->Point.Size; \
+ (void) lwidth; (void) psize; (void) vert;
+
+#define TAG(x) radeon_##x##_smooth_indirect
+#include "render_tmp.h"
+
+
+
+#define NEGATIVE( f ) (f < 0)
+#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0)
+#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A)))
+
+
+#define INTERP_RGBA( t, out, a, b ) \
+do { \
+ int i; \
+ for ( i = 0 ; i < 4 ; i++ ) { \
+ GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \
+ GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \
+ GLfloat fo = LINTERP( t, fa, fb ); \
+ FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \
+ } \
+} while (0)
+
+
+#define CLIP( SGN, V, PLANE ) \
+do { \
+ if ( mask & PLANE ) { \
+ GLuint *indata = inlist[in]; \
+ GLuint *outdata = inlist[in ^= 1]; \
+ GLuint nr = n; \
+ GLfloat *J = verts[indata[nr-1]].f; \
+ GLfloat dpJ = (SGN J[V]) + J[3]; \
+ \
+ inlist[0] = vlist1; \
+ for ( i = n = 0 ; i < nr ; i++ ) { \
+ GLuint elt_i = indata[i]; \
+ GLfloat *I = verts[elt_i].f; \
+ GLfloat dpI = (SGN I[V]) + I[3]; \
+ \
+ if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t, *in, *out; \
+ \
+ if ( NEGATIVE( dpI ) ) { \
+ t = dpI / (dpI - dpJ); \
+ in = I; \
+ out = J; \
+ } else { \
+ t = dpJ / (dpJ - dpI); \
+ in = J; \
+ out = I; \
+ } \
+ \
+ interp( t, O, in, out ); \
+ \
+ clipmask[next_vert] = 0; \
+ outdata[n++] = next_vert++; \
+ } \
+ \
+ clipmask[elt_i] |= PLANE; /* don't set up */ \
+ \
+ if ( !NEGATIVE( dpI ) ) { \
+ outdata[n++] = elt_i; \
+ clipmask[elt_i] &= ~PLANE; /* set up after all */ \
+ } \
+ \
+ J = I; \
+ dpJ = dpI; \
+ } \
+ \
+ if ( n < 3 ) return; \
+ } \
+} while (0)
+
+#define LINE_CLIP( x, y, z, w, PLANE ) \
+do { \
+ if ( mask & PLANE ) { \
+ GLfloat dpI = DOT4V( I, x, y, z, w); \
+ GLfloat dpJ = DOT4V( J, x, y, z, w); \
+ \
+ if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \
+ GLfloat *O = verts[next_vert].f; \
+ GLfloat t = dpI / (dpI - dpJ); \
+ \
+ interp( t, O, I, J ); \
+ \
+ clipmask[next_vert] = 0; \
+ \
+ if ( NEGATIVE( dpI ) ) { \
+ clipmask[elts[0]] |= PLANE; \
+ I = O; \
+ elts[0] = next_vert++; \
+ } else { \
+ clipmask[elts[1]] |= PLANE; \
+ J = O; \
+ elts[1] = next_vert++; \
+ } \
+ } else if ( NEGATIVE( dpI ) ) return; \
+ } \
+} while (0)
+
+
+static __inline void radeon_tri_clip( GLuint **p_elts,
+ radeonVertexPtr verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ radeon_interp_func interp )
+{
+ GLuint *elts = *p_elts;
+ GLuint next_vert = *p_next_vert;
+ GLuint in = 0;
+ GLuint n = 3;
+ GLuint vlist1[VB_MAX_CLIPPED_VERTS];
+ GLuint vlist2[VB_MAX_CLIPPED_VERTS];
+ GLuint *inlist[2];
+ GLuint *out;
+ GLuint i;
+
+ inlist[0] = elts;
+ inlist[1] = vlist2;
+
+ CLIP( -, 0, CLIP_RIGHT_BIT );
+ CLIP( +, 0, CLIP_LEFT_BIT );
+ CLIP( -, 1, CLIP_TOP_BIT );
+ CLIP( +, 1, CLIP_BOTTOM_BIT );
+ CLIP( -, 2, CLIP_FAR_BIT );
+ CLIP( +, 2, CLIP_NEAR_BIT );
+
+ /* Convert the planar polygon to a list of triangles */
+ out = inlist[in];
+
+ for ( i = 2 ; i < n ; i++ ) {
+ elts[0] = out[0];
+ elts[1] = out[i-1];
+ elts[2] = out[i];
+ elts += 3;
+ }
+
+ *p_next_vert = next_vert;
+ *p_elts = elts;
+}
+
+
+static __inline void radeon_line_clip( GLuint **p_elts,
+ radeonVertexPtr verts,
+ GLubyte *clipmask,
+ GLuint *p_next_vert,
+ GLubyte mask,
+ radeon_interp_func interp )
+{
+ GLuint *elts = *p_elts;
+ GLfloat *I = verts[elts[0]].f;
+ GLfloat *J = verts[elts[1]].f;
+ GLuint next_vert = *p_next_vert;
+
+ LINE_CLIP( 1, 0, 0, -1, CLIP_LEFT_BIT );
+ LINE_CLIP( -1, 0, 0, 1, CLIP_RIGHT_BIT );
+ LINE_CLIP( 0, 1, 0, -1, CLIP_TOP_BIT );
+ LINE_CLIP( 0, -1, 0, 1, CLIP_BOTTOM_BIT );
+ LINE_CLIP( 0, 0, 1, -1, CLIP_FAR_BIT );
+ LINE_CLIP( 0, 0, -1, 1, CLIP_NEAR_BIT );
+
+ *p_next_vert = next_vert;
+ *p_elts += 2;
+}
+
+
+
+#define CLIP_POINT( e ) \
+do { \
+ if ( mask[e] ) *out++ = e; \
+} while (0)
+
+#define CLIP_LINE( e1, e0 ) \
+do { \
+ GLubyte ormask = mask[e0] | mask[e1]; \
+ out[0] = e1; \
+ out[1] = e0; \
+ out += 2; \
+ if ( ormask ) { \
+ out-=2; \
+ if ( !(mask[e0] & mask[e1]) ) { \
+ radeon_line_clip( &out, verts, mask, \
+ &next_vert, ormask, interp ); \
+ } \
+ } \
+} while (0)
+
+#define CLIP_TRIANGLE( e2, e1, e0 ) \
+do { \
+ GLubyte ormask; \
+ out[0] = e2; \
+ out[1] = e1; \
+ out[2] = e0; \
+ out += 3; \
+ ormask = mask[e2] | mask[e1] | mask[e0]; \
+ if ( ormask ) { \
+ out -= 3; \
+ if ( !(mask[e2] & mask[e1] & mask[e0]) ) { \
+ radeon_tri_clip( &out, verts, mask, \
+ &next_vert, ormask, interp ); \
+ } \
+ } \
+} while (0)
+
+
+
+/* Build a table of functions to clip each primitive type. These
+ * produce a list of elements in the appropriate 'reduced' primitive,
+ * ie (points, lines, triangles) containing all the clipped and
+ * unclipped primitives from the original list.
+ */
+#define LOCAL_VARS \
+ radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \
+ radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); \
+ GLuint *elt = VB->EltPtr->data; \
+ radeonVertexPtr verts = rvb->verts; \
+ GLuint next_vert = rvb->last_vert; \
+ GLuint *out = rvb->clipped_elements.data; \
+ GLubyte *mask = VB->ClipMask; \
+ radeon_interp_func interp = rmesa->interp; \
+ (void) interp; (void) verts;
+
+#define POSTFIX \
+ rvb->clipped_elements.count = out - rvb->clipped_elements.data; \
+ rvb->last_vert = next_vert;
+
+
+#define INIT( x )
+
+#define RENDER_POINTS( start, count ) \
+do { \
+ GLuint i; \
+ for ( i = start; i < count ; i++ ) \
+ CLIP_POINT( elt[i] ); \
+} while (0)
+
+#define RENDER_LINE( i1, i0 ) \
+do { \
+ CLIP_LINE( elt[i1], elt[i0] ); \
+} while (0)
+
+#define RENDER_TRI( i2, i1, i0, pv, parity ) \
+do { \
+ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \
+ if ( parity ) e2 = elt[i1], e1 = elt[i2]; \
+ CLIP_TRIANGLE( e2, e1, e0 ); \
+} while (0)
+
+#define RENDER_QUAD( i3, i2, i1, i0, pv ) \
+do { \
+ CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \
+ CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ); \
+} while (0)
+
+#define TAG(x) radeon_##x##_clip_elt
+#include "render_tmp.h"
+
+
+
+/* Pack rgba and/or texture into the remaining half of a 32 byte vertex.
+ */
+#define CLIP_UBYTE_COLOR 4
+#define CLIP_UBYTE_R 0
+#define CLIP_UBYTE_G 1
+#define CLIP_UBYTE_B 2
+#define CLIP_UBYTE_A 3
+#define CLIP_S0 6
+#define CLIP_T0 7
+#define CLIP_S1 8
+#define CLIP_T1 9
+
+#define TYPE (0)
+#define TAG(x) x
+#include "radeon_fasttmp.h"
+
+#define TYPE (RADEON_RGBA_BIT)
+#define TAG(x) x##_RGBA
+#include "radeon_fasttmp.h"
+
+#define TYPE (RADEON_TEX0_BIT)
+#define TAG(x) x##_TEX0
+#include "radeon_fasttmp.h"
+
+#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT)
+#define TAG(x) x##_RGBA_TEX0
+#include "radeon_fasttmp.h"
+
+#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT)
+#define TAG(x) x##_RGBA_TEX0_TEX1
+#include "radeon_fasttmp.h"
+
+/* This one *could* get away with sneaking TEX1 into the color and
+ * specular slots, thus fitting inside a cache line. Would be even
+ * better to switch to a smaller vertex.
+ */
+#define TYPE (RADEON_TEX0_BIT | RADEON_TEX1_BIT)
+#define TAG(x) x##_TEX0_TEX1
+#include "radeon_fasttmp.h"
+
+
+
+static void radeon_render_elements_direct( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLenum prim = ctx->CVA.elt_mode;
+ GLuint nr = VB->EltPtr->count;
+ render_func func = radeon_render_tab_smooth_indirect[prim];
+ GLuint p = 0;
+
+ if ( rmesa->new_state )
+ radeonDDUpdateHWState( ctx );
+
+ do {
+ func( VB, 0, nr, 0 );
+ } while ( ctx->Driver.MultipassFunc &&
+ ctx->Driver.MultipassFunc( VB, ++p ) );
+}
+
+/* GH: These should go away altogether on the Radeon. We should disable
+ * the viewport mapping entirely in Mesa and let the hardware do it in
+ * all cases.
+ */
+static void radeon_project_vertices( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB);
+ GLfloat *m = rmesa->tmp_matrix;
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY];
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+
+ gl_project_v16( rvb->verts[VB->CopyStart].f,
+ rvb->verts[rvb->last_vert].f,
+ m,
+ 16 * 4 );
+}
+
+static void radeon_project_clipped_vertices( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLmatrix *mat = &ctx->Viewport.WindowMap;
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB);
+ GLfloat *m = rmesa->tmp_matrix;
+
+ m[MAT_SX] = mat->m[MAT_SX];
+ m[MAT_TX] = mat->m[MAT_TX];
+ m[MAT_SY] = -mat->m[MAT_SY];
+ m[MAT_TY] = -mat->m[MAT_TY];
+ m[MAT_SZ] = mat->m[MAT_SZ];
+ m[MAT_TZ] = mat->m[MAT_TZ];
+
+ gl_project_clipped_v16( rvb->verts[VB->CopyStart].f,
+ rvb->verts[rvb->last_vert].f,
+ m,
+ 16 * 4,
+ VB->ClipMask + VB->CopyStart );
+}
+
+static struct radeon_fast_tab radeonFastTab[RADEON_MAX_SETUPFUNC];
+
+void radeonDDFastPathInit( void )
+{
+ radeon_render_init_clip_elt();
+ radeon_render_init_smooth_indirect();
+
+ radeon_init_fastpath( &radeonFastTab[0] );
+ radeon_init_fastpath_RGBA( &radeonFastTab[RADEON_RGBA_BIT] );
+ radeon_init_fastpath_TEX0( &radeonFastTab[RADEON_TEX0_BIT] );
+ radeon_init_fastpath_RGBA_TEX0( &radeonFastTab[(RADEON_RGBA_BIT |
+ RADEON_TEX0_BIT)] );
+ radeon_init_fastpath_TEX0_TEX1( &radeonFastTab[(RADEON_TEX0_BIT |
+ RADEON_TEX1_BIT)] );
+ radeon_init_fastpath_RGBA_TEX0_TEX1( &radeonFastTab[(RADEON_RGBA_BIT |
+ RADEON_TEX0_BIT |
+ RADEON_TEX1_BIT)] );
+}
+
+#define VALID_SETUP (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT)
+
+void radeonDDFastPath( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+ GLenum prim = ctx->CVA.elt_mode;
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ struct radeon_fast_tab *tab =
+ &radeonFastTab[rmesa->SetupIndex & VALID_SETUP];
+ GLuint do_cliptest = 1;
+
+ gl_prepare_arrays_cva( VB ); /* still need this */
+
+ if ( ( gl_reduce_prim[prim] == GL_TRIANGLES ) &&
+ ( VB->Count < (RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) ) &&
+ ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL |
+ MAT_FLAG_PERSPECTIVE) ) )
+ {
+ radeonDDEltPath( VB );
+ return;
+ }
+
+ /* Reserve enough space for the pathological case */
+ if ( VB->EltPtr->count * 12 > RADEON_DRIVER_DATA(VB)->size ) {
+ radeonDDResizeVB( VB, VB->EltPtr->count * 12 );
+ do_cliptest = 1;
+ }
+
+ tab->build_vertices( VB, do_cliptest ); /* object->clip space */
+
+ if ( rmesa->new_state )
+ radeonDDUpdateHWState( ctx );
+
+ if ( VB->ClipOrMask ) {
+ if ( !VB->ClipAndMask ) {
+ render_func *clip = radeon_render_tab_clip_elt;
+
+ rmesa->interp = tab->interp;
+
+ clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */
+
+ ctx->CVA.elt_mode = gl_reduce_prim[prim];
+ VB->EltPtr = &(RADEON_DRIVER_DATA(VB)->clipped_elements);
+
+ radeon_project_clipped_vertices( VB ); /* clip->device space */
+ radeon_render_elements_direct( VB ); /* render using new list */
+ }
+ } else {
+ radeon_project_vertices( VB ); /* clip->device space */
+ radeon_render_elements_direct( VB ); /* render using orig list */
+ }
+
+ /* This indicates that there is no cached data to reuse */
+ VB->pipeline->data_valid = 0;
+ VB->pipeline->new_state = 0;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h
new file mode 100644
index 000000000..dc444aa8a
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h
@@ -0,0 +1,185 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell <keithw@valinux.com>
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+/* The first part of setup is applied to all vertices, clipped or
+ * unclipped. This data w!ill be used for clipping, and then all
+ * vertices with a zero clipmask will be projected to device space.
+ *
+ * This could be split into several loops, but - it seems that the
+ * large stride of the fxVertices makes cache issues the big
+ * performance factor, and that multiple loops mean multiple cache
+ * misses....
+ */
+static void TAG(radeon_setup_full)( struct vertex_buffer *VB,
+ GLuint do_cliptest )
+{
+ GLcontext *ctx = VB->ctx;
+ radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB);
+ const GLfloat *m = ctx->ModelProjectMatrix.m;
+ GLuint start = VB->CopyStart;
+ GLuint count = VB->Count;
+
+ gl_xform_points3_v16_general( rvb->verts[start].f,
+ m,
+ VB->ObjPtr->start,
+ VB->ObjPtr->stride,
+ count - start );
+
+ if ( do_cliptest ) {
+ VB->ClipAndMask = ~0;
+ VB->ClipOrMask = 0;
+ gl_cliptest_points4_v16( rvb->verts[start].f,
+ rvb->verts[count].f,
+ &(VB->ClipOrMask),
+ &(VB->ClipAndMask),
+ VB->ClipMask + start );
+ }
+
+ /* These branches are all resolved at compile time. Hopefully all
+ * the pointers are valid addresses even when not enabled.
+ */
+ if ( TYPE ) {
+ GLubyte *color = VB->ColorPtr->start;
+ GLfloat *tex0_data = VB->TexCoordPtr[0]->start;
+ GLfloat *tex1_data = VB->TexCoordPtr[1]->start;
+
+ GLuint color_stride = VB->ColorPtr->stride;
+ GLuint tex0_stride = VB->TexCoordPtr[0]->stride;
+ GLuint tex1_stride = VB->TexCoordPtr[1]->stride;
+
+ GLfloat *f = rvb->verts[start].f;
+ GLfloat *end = f + (16 * (count - start));
+
+ while ( f != end ) {
+ if ( TYPE & RADEON_RGBA_BIT ) {
+#if defined (USE_X86_ASM)
+ /* GH: Finally! Some damned hardware manufacturer uses
+ * little-endian RGBA for vertex color...
+ */
+ __asm__ ( "movl (%%ecx), %%eax \n"
+ "movl %%eax, 16(%%edi) \n"
+ :
+ : "c" (color), "D" (f)
+ : "%eax" );
+#else
+ *(GLuint *)(f+CLIP_UBYTE_COLOR) = *(GLuint *)color;
+#endif
+ }
+ if ( TYPE & RADEON_TEX0_BIT ) {
+#if defined (USE_X86_ASM)
+ __asm__ ( "movl (%%ecx), %%eax \n"
+ "movl %%eax, 24(%%edi) \n"
+ "movl 4(%%ecx), %%eax \n"
+ "movl %%eax, 28(%%edi)"
+ :
+ : "c" (tex0_data), "D" (f)
+ : "%eax" );
+#else
+ *(GLuint *)(f+CLIP_S0) = *(GLuint *)tex0_data;
+ *(GLuint *)(f+CLIP_T0) = *(GLuint *)(tex0_data+1);
+#endif
+ }
+ if ( TYPE & RADEON_TEX1_BIT ) {
+ /* Hits a second cache line.
+ */
+#if defined (USE_X86_ASM)
+ __asm__ ( "movl (%%esi), %%eax \n"
+ "movl %%eax, 32(%%edi) \n"
+ "movl 4(%%esi), %%eax \n"
+ "movl %%eax, 36(%%edi)"
+ :
+ : "S" (tex1_data), "D" (f)
+ : "%eax" );
+#else
+ *(GLuint *)(f+CLIP_S1) = *(GLuint *)tex1_data;
+ *(GLuint *)(f+CLIP_T1) = *(GLuint *)(tex1_data+1);
+#endif
+ }
+ if ( TYPE & RADEON_RGBA_BIT ) color += color_stride;
+ if ( TYPE & RADEON_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride );
+ if ( TYPE & RADEON_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride );
+ f += 16;
+ }
+ }
+
+ rvb->clipped_elements.count = start;
+ rvb->last_vert = count;
+}
+
+
+/* Changed to just put the interp func instead of the whole clip
+ * routine into the header. Less code and better chance of doing some
+ * of this stuff in assembly.
+ */
+static void TAG(radeon_interp_vert)( GLfloat t,
+ GLfloat *O,
+ const GLfloat *I,
+ const GLfloat *J )
+{
+ O[0] = LINTERP( t, I[0], J[0] );
+ O[1] = LINTERP( t, I[1], J[1] );
+ O[2] = LINTERP( t, I[2], J[2] );
+ O[3] = LINTERP( t, I[3], J[3] );
+
+ if ( TYPE & RADEON_RGBA_BIT ) {
+ INTERP_RGBA( t,
+ ((GLubyte *)&(O[4])),
+ ((GLubyte *)&(I[4])),
+ ((GLubyte *)&(J[4])) );
+ }
+
+ if ( TYPE & RADEON_TEX0_BIT ) {
+ O[6] = LINTERP( t, I[6], J[6] );
+ O[7] = LINTERP( t, I[7], J[7] );
+ }
+
+ if ( TYPE & RADEON_TEX1_BIT ) {
+ O[8] = LINTERP( t, I[8], J[8] );
+ O[9] = LINTERP( t, I[9], J[9] );
+ }
+}
+
+
+static void TAG(radeon_init_fastpath)( struct radeon_fast_tab *tab )
+{
+ tab->build_vertices = TAG(radeon_setup_full);
+ tab->interp = TAG(radeon_interp_vert);
+}
+
+#undef TYPE
+#undef TAG
+#undef SIZE
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
new file mode 100644
index 000000000..5273072e7
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
@@ -0,0 +1,703 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+
+#include "mem.h"
+
+#define RADEON_TIMEOUT 2048
+#define USE_IN_MEMORY_SCRATCH_REGS 0
+
+
+/* =============================================================
+ * Hardware vertex buffer handling
+ */
+
+/* Get a new VB from the pool of vertex buffers in AGP space.
+ */
+drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa )
+{
+ int fd = rmesa->radeonScreen->driScreen->fd;
+ int index = 0;
+ int size = 0;
+ drmDMAReq dma;
+ drmBufPtr buf = NULL;
+ int to = 0;
+ int ret;
+
+ dma.context = rmesa->hHWContext;
+ dma.send_count = 0;
+ dma.send_list = NULL;
+ dma.send_sizes = NULL;
+ dma.flags = 0;
+ dma.request_count = 1;
+ dma.request_size = RADEON_BUFFER_SIZE;
+ dma.request_list = &index;
+ dma.request_sizes = &size;
+ dma.granted_count = 0;
+
+ while ( !buf && ( to++ < RADEON_TIMEOUT ) ) {
+ ret = drmDMA( fd, &dma );
+
+ if ( ret == 0 ) {
+ buf = &rmesa->radeonScreen->buffers->list[index];
+ buf->used = 0;
+#if ENABLE_PERF_BOXES
+ /* Bump the performance counter */
+ rmesa->c_vertexBuffers++;
+#endif
+ return buf;
+ }
+ }
+
+ if ( !buf ) {
+ drmRadeonEngineReset( fd );
+ UNLOCK_HARDWARE( rmesa );
+ fprintf( stderr, "Error: Could not get new VB... exiting\n" );
+ exit( -1 );
+ }
+
+ return buf;
+}
+
+static GLboolean intersect_rect( XF86DRIClipRectPtr out,
+ XF86DRIClipRectPtr a,
+ XF86DRIClipRectPtr b )
+{
+ *out = *a;
+ if ( b->x1 > out->x1 ) out->x1 = b->x1;
+ if ( b->y1 > out->y1 ) out->y1 = b->y1;
+ if ( b->x2 < out->x2 ) out->x2 = b->x2;
+ if ( b->y2 < out->y2 ) out->y2 = b->y2;
+ if ( out->x1 >= out->x2 ) return GL_FALSE;
+ if ( out->y1 >= out->y2 ) return GL_FALSE;
+ return GL_TRUE;
+}
+
+void radeonFlushVerticesLocked( radeonContextPtr rmesa )
+{
+ XF86DRIClipRectPtr pbox = rmesa->pClipRects;
+ int nbox = rmesa->numClipRects;
+ drmBufPtr buffer = rmesa->vert_buf;
+ int count = rmesa->num_verts;
+ int prim = RADEON_TRIANGLES;
+ int fd = rmesa->driScreen->fd;
+ int i;
+
+ rmesa->vert_buf = NULL;
+ rmesa->num_verts = 0;
+
+ if ( !buffer )
+ return;
+
+ if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS )
+ radeonEmitHwStateLocked( rmesa );
+
+ if ( !nbox )
+ count = 0;
+
+ if ( nbox >= RADEON_NR_SAREA_CLIPRECTS )
+ rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS;
+
+ if ( !count || !(rmesa->dirty & RADEON_UPLOAD_CLIPRECTS) )
+ {
+ if ( nbox == 1 ) {
+ rmesa->sarea->nbox = 0;
+ } else {
+ rmesa->sarea->nbox = nbox;
+ }
+
+ drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, 1 );
+ }
+ else
+ {
+ for ( i = 0 ; i < nbox ; ) {
+ int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox );
+ XF86DRIClipRectPtr b = rmesa->sarea->boxes;
+ int discard = 0;
+
+ if ( rmesa->scissor ) {
+ rmesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++ ) {
+ *b = pbox[i];
+ if ( intersect_rect( b, b, &rmesa->scissor_rect ) ) {
+ rmesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if ( !rmesa->sarea->nbox ) {
+ if ( nr < nbox ) continue;
+ count = 0;
+ }
+ } else {
+ rmesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++) {
+ *b++ = pbox[i];
+ }
+ }
+
+ /* Finished with the buffer?
+ */
+ if ( nr == nbox ) {
+ discard = 1;
+ }
+
+ rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS;
+ drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, discard );
+ }
+ }
+
+ rmesa->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
+}
+
+
+
+/* ================================================================
+ * Indexed vertex buffer handling
+ */
+
+void radeonGetEltBufLocked( radeonContextPtr rmesa )
+{
+ rmesa->elt_buf = radeonGetBufferLocked( rmesa );
+}
+
+void radeonFireEltsLocked( radeonContextPtr rmesa,
+ GLuint start, GLuint end,
+ GLuint discard )
+{
+ XF86DRIClipRectPtr pbox = rmesa->pClipRects;
+ int nbox = rmesa->numClipRects;
+ drmBufPtr buffer = rmesa->elt_buf;
+ int prim = RADEON_TRIANGLES;
+ int fd = rmesa->driScreen->fd;
+ int i;
+
+ if ( !buffer )
+ return;
+
+ if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS )
+ radeonEmitHwStateLocked( rmesa );
+
+ if ( !nbox )
+ end = start;
+
+ if ( nbox >= RADEON_NR_SAREA_CLIPRECTS )
+ rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS;
+
+ if ( start == end || !(rmesa->dirty & RADEON_UPLOAD_CLIPRECTS) )
+ {
+ if ( nbox == 1 ) {
+ rmesa->sarea->nbox = 0;
+ } else {
+ rmesa->sarea->nbox = nbox;
+ }
+
+ drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard );
+ }
+ else
+ {
+ for ( i = 0 ; i < nbox ; ) {
+ int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox );
+ XF86DRIClipRectPtr b = rmesa->sarea->boxes;
+ int d = 0;
+
+ if ( rmesa->scissor ) {
+ rmesa->sarea->nbox = 0;
+
+ for ( ; i < nr ; i++ ) {
+ *b = pbox[i];
+ if ( intersect_rect( b, b, &rmesa->scissor_rect ) ) {
+ rmesa->sarea->nbox++;
+ b++;
+ }
+ }
+
+ /* Culled?
+ */
+ if ( !rmesa->sarea->nbox ) {
+ if ( nr < nbox ) continue;
+ end = start;
+ }
+ } else {
+ rmesa->sarea->nbox = nr - i;
+ for ( ; i < nr ; i++) {
+ *b++ = pbox[i];
+ }
+ }
+
+ /* Finished with the buffer?
+ */
+ if ( nr == nbox ) {
+ d = discard;
+ }
+
+ rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS;
+ drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard );
+ }
+ }
+
+ rmesa->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
+}
+
+void radeonFlushEltsLocked( radeonContextPtr rmesa )
+{
+ if ( rmesa->first_elt != rmesa->next_elt ) {
+ radeonFireEltsLocked( rmesa,
+ ((GLuint)rmesa->first_elt -
+ (GLuint)rmesa->elt_buf->address),
+ ((GLuint)rmesa->next_elt -
+ (GLuint)rmesa->elt_buf->address),
+ 0 );
+
+ ALIGN_NEXT_ELT( rmesa );
+ rmesa->first_elt = rmesa->next_elt;
+ }
+}
+
+void radeonReleaseBufLocked( radeonContextPtr rmesa, drmBufPtr buffer )
+{
+ int fd = rmesa->driScreen->fd;
+
+ if ( !buffer )
+ return;
+
+ drmRadeonFlushVertexBuffer( fd, RADEON_TRIANGLES, buffer->idx, 0, 1 );
+}
+
+
+/* Allocate some space in the current vertex buffer. If the current
+ * buffer is full, flush it and grab another one.
+ */
+CARD32 *radeonAllocVertices( radeonContextPtr rmesa, GLuint count )
+{
+ return radeonAllocVerticesInline( rmesa, count );
+}
+
+
+/* ================================================================
+ * Texture uploads
+ */
+
+void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer,
+ GLint offset, GLint pitch, GLint format,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ GLint ret;
+
+ ret = drmRadeonTextureBlit( rmesa->driFd, buffer->idx,
+ offset, pitch, format,
+ x, y, width, height );
+
+ if ( ret ) {
+ UNLOCK_HARDWARE( rmesa );
+ fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret );
+ exit( 1 );
+ }
+}
+
+
+/* ================================================================
+ * SwapBuffers with client-side throttling
+ */
+
+#define RADEON_MAX_OUTSTANDING 2
+
+/* Throttle the frame rate -- only allow one pending swap buffers
+ * request at a time.
+ * GH: We probably don't want a timeout here, as we can wait as
+ * long as we want for a frame to complete. If it never does, then
+ * the card has locked.
+ */
+#if USE_IN_MEMORY_SCRATCH_REGS
+static int radeonWaitForFrameCompletion( radeonContextPtr rmesa )
+{
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+ __volatile__ CARD32 *scratch = rmesa->radeonScreen->scratch;
+ CARD32 frame;
+ int wait = 0;
+
+ while ( 1 ) {
+ /* Read the frame counter from the in-memory copy of the scratch
+ * register. Nifty, eh? Should significantly reduce the bus
+ * traffic for SwapBuffers-limited apps (generally pretty trivial
+ * ones, but anyway).
+ */
+ frame = scratch[0];
+ if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) {
+ break;
+ }
+ wait++;
+ }
+
+ return wait;
+}
+#else
+static void delay( void ) {
+/* Prevent an optimizing compiler from removing a spin loop */
+}
+
+static int radeonWaitForFrameCompletion( radeonContextPtr rmesa )
+{
+ unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+ CARD32 frame;
+ int wait = 0;
+ int i;
+
+ while ( 1 ) {
+ frame = INREG( RADEON_LAST_FRAME_REG );
+ if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) {
+ break;
+ }
+ wait++;
+ /* Spin in place a bit so we aren't hammering the bus */
+ for ( i = 0 ; i < 1024 ; i++ ) {
+ delay();
+ }
+ }
+
+ return wait;
+}
+#endif
+
+/* Copy the back color buffer to the front color buffer.
+ */
+void radeonSwapBuffers( radeonContextPtr rmesa )
+{
+ GLint nbox = rmesa->numClipRects;
+ GLint i;
+ GLint ret;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx );
+ }
+
+ FLUSH_BATCH( rmesa );
+
+ LOCK_HARDWARE( rmesa );
+
+ /* Throttle the frame rate -- only allow one pending swap buffers
+ * request at a time.
+ */
+ if ( !radeonWaitForFrameCompletion( rmesa ) ) {
+ rmesa->hardwareWentIdle = 1;
+ } else {
+ rmesa->hardwareWentIdle = 0;
+ }
+
+ for ( i = 0 ; i < nbox ; ) {
+ GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
+ XF86DRIClipRectPtr box = rmesa->pClipRects;
+ XF86DRIClipRectPtr b = rmesa->sarea->boxes;
+ GLint n = 0;
+
+ for ( ; i < nr ; i++ ) {
+ *b++ = *(XF86DRIClipRectRec *)&box[i];
+ n++;
+ }
+ rmesa->sarea->nbox = n;
+
+ ret = drmRadeonSwapBuffers( rmesa->driFd );
+
+ if ( ret ) {
+ fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret );
+ UNLOCK_HARDWARE( rmesa );
+ exit( 1 );
+ }
+ }
+
+ UNLOCK_HARDWARE( rmesa );
+
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= (RADEON_UPLOAD_CONTEXT |
+ RADEON_UPLOAD_MASKS |
+ RADEON_UPLOAD_CLIPRECTS);
+
+#if ENABLE_PERF_BOXES
+ /* Log the performance counters if necessary */
+ radeonPerformanceCounters( rmesa );
+#endif
+}
+
+void radeonPageFlip( radeonContextPtr rmesa )
+{
+ GLint ret;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "\n%s( %p ): page=%d\n\n",
+ __FUNCTION__, rmesa->glCtx, rmesa->currentPage );
+ }
+
+ FLUSH_BATCH( rmesa );
+
+ LOCK_HARDWARE( rmesa );
+
+ /* Throttle the frame rate -- only allow one pending swap buffers
+ * request at a time.
+ */
+ if ( !radeonWaitForFrameCompletion( rmesa ) ) {
+ rmesa->hardwareWentIdle = 1;
+ } else {
+ rmesa->hardwareWentIdle = 0;
+ }
+
+ /* The kernel will have been initialized to perform page flipping
+ * on a swapbuffers ioctl.
+ */
+ ret = drmRadeonSwapBuffers( rmesa->driFd );
+
+ UNLOCK_HARDWARE( rmesa );
+
+ if ( ret ) {
+ fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret );
+ exit( 1 );
+ }
+
+ if ( rmesa->currentPage == 0 ) {
+ rmesa->drawOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->drawPitch = rmesa->radeonScreen->frontPitch;
+ rmesa->currentPage = 1;
+ } else {
+ rmesa->drawOffset = rmesa->radeonScreen->backOffset;
+ rmesa->drawPitch = rmesa->radeonScreen->backPitch;
+ rmesa->currentPage = 0;
+ }
+
+ rmesa->setup.rb3d_coloroffset = rmesa->drawOffset;
+ rmesa->setup.rb3d_colorpitch = rmesa->drawPitch;
+
+ rmesa->new_state |= RADEON_NEW_WINDOW;
+
+ /* FIXME: Do we need this anymore? */
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= (RADEON_UPLOAD_CONTEXT |
+ RADEON_UPLOAD_MASKS |
+ RADEON_UPLOAD_CLIPRECTS);
+
+#if ENABLE_PERF_BOXES
+ /* Log the performance counters if necessary */
+ radeonPerformanceCounters( rmesa );
+#endif
+}
+
+
+/* ================================================================
+ * Buffer clear
+ */
+#define RADEON_MAX_CLEARS 256
+
+static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask,
+ GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+#if USE_IN_MEMORY_SCRATCH_REGS
+ __volatile__ CARD32 *scratch = rmesa->radeonScreen->scratch;
+#else
+ unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
+#endif
+ CARD32 clear;
+ GLuint flags = 0;
+ GLint ret, i;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n",
+ __FUNCTION__, all, cx, cy, cw, ch );
+ }
+
+ FLUSH_BATCH( rmesa );
+
+ /* Update and emit any new state. We need to do this here to catch
+ * changes to the masks.
+ * FIXME: Just update the masks?
+ */
+ if ( rmesa->new_state )
+ radeonDDUpdateHWState( ctx );
+
+ if ( mask & DD_FRONT_LEFT_BIT ) {
+ flags |= DRM_RADEON_FRONT;
+ mask &= ~DD_FRONT_LEFT_BIT;
+ }
+
+ if ( mask & DD_BACK_LEFT_BIT ) {
+ flags |= DRM_RADEON_BACK;
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
+
+ if ( mask & DD_DEPTH_BIT ) {
+ if ( ctx->Depth.Mask ) {
+ flags |= DRM_RADEON_DEPTH;
+ }
+ mask &= ~DD_DEPTH_BIT;
+ }
+#if 0
+ /* FIXME: Add stencil support */
+ if ( mask & DD_STENCIL_BIT ) {
+ flags |= DRM_RADEON_DEPTH;
+ mask &= ~DD_STENCIL_BIT;
+ }
+#endif
+
+ if ( !flags )
+ return mask;
+
+ /* Flip top to bottom */
+ cx += dPriv->x;
+ cy = dPriv->y + dPriv->h - cy - ch;
+
+ LOCK_HARDWARE( rmesa );
+
+ /* Throttle the number of clear ioctls we do.
+ */
+#if USE_IN_MEMORY_SCRATCH_REGS
+ while ( 1 ) {
+ clear = scratch[2];
+ if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
+ break;
+ }
+ }
+#else
+ while ( 1 ) {
+ clear = INREG( RADEON_LAST_CLEAR_REG );
+ if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
+ break;
+ }
+ /* Spin in place a bit so we aren't hammering the bus */
+ for ( i = 0 ; i < 1024 ; i++ ) {
+ delay();
+ }
+ }
+#endif
+
+ if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
+ radeonEmitHwStateLocked( rmesa );
+ }
+
+ for ( i = 0 ; i < rmesa->numClipRects ; ) {
+ GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, rmesa->numClipRects );
+ XF86DRIClipRectPtr box = rmesa->pClipRects;
+ XF86DRIClipRectPtr b = rmesa->sarea->boxes;
+ GLint n = 0;
+
+ if ( !all ) {
+ for ( ; i < nr ; i++ ) {
+ GLint x = box[i].x1;
+ GLint y = box[i].y1;
+ GLint w = box[i].x2 - x;
+ GLint h = box[i].y2 - y;
+
+ if ( x < cx ) w -= cx - x, x = cx;
+ if ( y < cy ) h -= cy - y, y = cy;
+ if ( x + w > cx + cw ) w = cx + cw - x;
+ if ( y + h > cy + ch ) h = cy + ch - y;
+ if ( w <= 0 ) continue;
+ if ( h <= 0 ) continue;
+
+ b->x1 = x;
+ b->y1 = y;
+ b->x2 = x + w;
+ b->y2 = y + h;
+ b++;
+ n++;
+ }
+ } else {
+ for ( ; i < nr ; i++ ) {
+ *b++ = *(XF86DRIClipRectRec *)&box[i];
+ n++;
+ }
+ }
+
+ rmesa->sarea->nbox = n;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) {
+ fprintf( stderr,
+ "drmRadeonClear: flag 0x%x color %x depth %x nbox %d\n",
+ flags,
+ (GLuint)rmesa->ClearColor,
+ (GLuint)rmesa->ClearDepth,
+ rmesa->sarea->nbox );
+ }
+
+ ret = drmRadeonClear( rmesa->driFd, flags,
+ cx, cy, cw, ch,
+ rmesa->ClearColor, rmesa->ClearDepth );
+
+ if ( ret ) {
+ UNLOCK_HARDWARE( rmesa );
+ fprintf( stderr, "drmRadeonClear: return = %d\n", ret );
+ exit( 1 );
+ }
+ }
+
+ UNLOCK_HARDWARE( rmesa );
+
+ rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS;
+
+ return mask;
+}
+
+
+void radeonWaitForIdleLocked( radeonContextPtr rmesa )
+{
+ int fd = rmesa->radeonScreen->driScreen->fd;
+ int to = 0;
+ int ret;
+
+ do {
+ ret = drmRadeonWaitForIdleCP( fd );
+ } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) );
+
+ if ( ret < 0 ) {
+ drmRadeonEngineReset( fd );
+ UNLOCK_HARDWARE( rmesa );
+ fprintf( stderr, "Error: Radeon timed out... exiting\n" );
+ exit( -1 );
+ }
+}
+
+
+void radeonDDInitIoctlFuncs( GLcontext *ctx )
+{
+ ctx->Driver.Clear = radeonDDClear;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h
new file mode 100644
index 000000000..7b22a8766
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h
@@ -0,0 +1,161 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_IOCTL_H__
+#define __RADEON_IOCTL_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "radeon_dri.h"
+#include "radeon_lock.h"
+
+#include "xf86drm.h"
+#include "xf86drmRadeon.h"
+
+#define RADEON_BUFFER_MAX_DWORDS (RADEON_BUFFER_SIZE / sizeof(CARD32))
+
+
+extern drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa );
+extern void radeonFlushVerticesLocked( radeonContextPtr rmesa );
+
+extern void radeonGetEltBufLocked( radeonContextPtr rmesa );
+extern void radeonFlushEltsLocked( radeonContextPtr rmesa );
+extern void radeonFireEltsLocked( radeonContextPtr rmesa,
+ GLuint start, GLuint end,
+ GLuint discard );
+extern void radeonReleaseBufLocked( radeonContextPtr rmesa, drmBufPtr buffer );
+
+/* Make this available as both a regular and an inline function.
+ */
+extern CARD32 *radeonAllocVertices( radeonContextPtr rmesa, GLuint count );
+
+static __inline CARD32 *radeonAllocVerticesInline( radeonContextPtr rmesa,
+ GLuint count )
+{
+ int bytes = count * rmesa->vertsize * 4;
+ CARD32 *head;
+
+ if ( !rmesa->vert_buf ) {
+ LOCK_HARDWARE( rmesa );
+
+ if ( rmesa->first_elt != rmesa->next_elt ) {
+ radeonFlushEltsLocked( rmesa );
+ }
+
+ rmesa->vert_buf = radeonGetBufferLocked( rmesa );
+
+ UNLOCK_HARDWARE( rmesa );
+ } else if ( rmesa->vert_buf->used + bytes > rmesa->vert_buf->total ) {
+ LOCK_HARDWARE( rmesa );
+
+ radeonFlushVerticesLocked( rmesa );
+ rmesa->vert_buf = radeonGetBufferLocked( rmesa );
+
+ UNLOCK_HARDWARE( rmesa );
+ }
+
+ head = (CARD32 *)((char *)rmesa->vert_buf->address +
+ rmesa->vert_buf->used);
+
+ rmesa->vert_buf->used += bytes;
+ rmesa->num_verts += count;
+ return head;
+}
+
+extern void radeonFireBlitLocked( radeonContextPtr rmesa,
+ drmBufPtr buffer,
+ GLint offset, GLint pitch, GLint format,
+ GLint x, GLint y,
+ GLint width, GLint height );
+
+extern void radeonSwapBuffers( radeonContextPtr rmesa );
+extern void radeonPageFlip( radeonContextPtr rmesa );
+
+extern void radeonWaitForIdleLocked( radeonContextPtr rmesa );
+
+
+extern void radeonDDInitIoctlFuncs( GLcontext *ctx );
+
+
+/* ================================================================
+ * Helper macros:
+ */
+
+#define FLUSH_BATCH( rmesa ) \
+do { \
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) \
+ fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \
+ if ( rmesa->vert_buf ) { \
+ radeonFlushVertices( rmesa ); \
+ } else if ( rmesa->next_elt != rmesa->first_elt ) { \
+ radeonFlushElts( rmesa ); \
+ } \
+} while (0)
+
+/* 64-bit align the next element address, and then make room for the
+ * next indexed prim packet header.
+ */
+#define ALIGN_NEXT_ELT( rmesa ) \
+do { \
+ rmesa->next_elt = (GLushort *) \
+ (((GLuint)rmesa->next_elt + 7) & ~0x7); \
+ rmesa->next_elt = (GLushort *) \
+ ((GLubyte *)rmesa->next_elt + RADEON_INDEX_PRIM_OFFSET); \
+} while (0)
+
+#define radeonFlushVertices( rmesa ) \
+do { \
+ LOCK_HARDWARE( rmesa ); \
+ radeonFlushVerticesLocked( rmesa ); \
+ UNLOCK_HARDWARE( rmesa ); \
+} while (0)
+
+#define radeonFlushElts( rmesa ) \
+do { \
+ LOCK_HARDWARE( rmesa ); \
+ radeonFlushEltsLocked( rmesa ); \
+ UNLOCK_HARDWARE( rmesa ); \
+} while (0)
+
+#define radeonWaitForIdle( rmesa ) \
+do { \
+ LOCK_HARDWARE( rmesa ); \
+ radeonWaitForIdleLocked( rmesa ); \
+ UNLOCK_HARDWARE( rmesa ); \
+} while (0)
+
+#endif
+#endif /* __RADEON_IOCTL_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c
new file mode 100644
index 000000000..65658e997
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c
@@ -0,0 +1,95 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_lock.h"
+#include "radeon_tex.h"
+
+#if DEBUG_LOCKING
+char *prevLockFile = NULL;
+int prevLockLine = 0;
+#endif
+
+
+/* Update the hardware state. This is called if another context has
+ * grabbed the hardware lock, which includes the X server. This
+ * function also updates the driver's window state after the X server
+ * moves, resizes or restacks a window -- the change will be reflected
+ * in the drawable position and clip rects. Since the X server grabs
+ * the hardware lock when it changes the window state, this routine will
+ * automatically be called after such a change.
+ */
+void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
+{
+ __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
+ __DRIscreenPrivate *sPriv = rmesa->driScreen;
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+ int stamp = dPriv->lastStamp;
+ int i;
+
+ drmGetLock( rmesa->driFd, rmesa->hHWContext, flags );
+
+ /* The window might have moved, so we might need to get new clip
+ * rects.
+ *
+ * NOTE: This releases and regrabs the hw lock to allow the X server
+ * to respond to the DRI protocol request for new drawable info.
+ * Since the hardware state depends on having the latest drawable
+ * clip rects, all state checking must be done _after_ this call.
+ */
+ XMESA_VALIDATE_DRAWABLE_INFO( rmesa->display, sPriv, dPriv );
+
+ if ( stamp != dPriv->lastStamp ) {
+ rmesa->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP;
+ rmesa->SetupDone = 0;
+ }
+
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_CLIPRECTS;
+
+ rmesa->numClipRects = dPriv->numClipRects;
+ rmesa->pClipRects = dPriv->pClipRects;
+
+ if ( sarea->ctxOwner != rmesa->hHWContext ) {
+ sarea->ctxOwner = rmesa->hHWContext;
+ rmesa->dirty = RADEON_UPLOAD_ALL;
+ }
+
+ for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) {
+ if ( sarea->texAge[i] != rmesa->lastTexAge[i] ) {
+ radeonAgeTextures( rmesa, i );
+ }
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h
new file mode 100644
index 000000000..7cdb1b23d
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h
@@ -0,0 +1,112 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_LOCK_H__
+#define __RADEON_LOCK_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags );
+
+/* Turn DEBUG_LOCKING on to find locking conflicts.
+ */
+#define DEBUG_LOCKING 0
+
+#if DEBUG_LOCKING
+extern char *prevLockFile;
+extern int prevLockLine;
+
+#define DEBUG_LOCK() \
+ do { \
+ prevLockFile = (__FILE__); \
+ prevLockLine = (__LINE__); \
+ } while (0)
+
+#define DEBUG_RESET() \
+ do { \
+ prevLockFile = 0; \
+ prevLockLine = 0; \
+ } while (0)
+
+#define DEBUG_CHECK_LOCK() \
+ do { \
+ if ( prevLockFile ) { \
+ fprintf( stderr, \
+ "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
+ prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
+ exit( 1 ); \
+ } \
+ } while (0)
+
+#else
+
+#define DEBUG_LOCK()
+#define DEBUG_RESET()
+#define DEBUG_CHECK_LOCK()
+
+#endif
+
+/*
+ * !!! We may want to separate locks from locks with validation. This
+ * could be used to improve performance for those things commands that
+ * do not do any drawing !!!
+ */
+
+/* Lock the hardware and validate our state.
+ */
+#define LOCK_HARDWARE( rmesa ) \
+ do { \
+ char __ret = 0; \
+ DEBUG_CHECK_LOCK(); \
+ DRM_CAS( rmesa->driHwLock, rmesa->hHWContext, \
+ (DRM_LOCK_HELD | rmesa->hHWContext), __ret ); \
+ if ( __ret ) \
+ radeonGetLock( rmesa, 0 ); \
+ DEBUG_LOCK(); \
+ } while (0)
+
+/* Unlock the hardware.
+ */
+#define UNLOCK_HARDWARE( rmesa ) \
+ do { \
+ DRM_UNLOCK( rmesa->driFd, \
+ rmesa->driHwLock, \
+ rmesa->hHWContext ); \
+ DEBUG_RESET(); \
+ } while (0)
+
+#endif
+#endif /* __RADEON_LOCK_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c
new file mode 100644
index 000000000..fe0eb013e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c
@@ -0,0 +1,168 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_vb.h"
+#include "radeon_pipeline.h"
+
+#include "types.h"
+#include "fog.h"
+
+static struct gl_pipeline_stage radeon_fast_stage = {
+ "Radeon Fast Path",
+ (PIPE_OP_VERT_XFORM |
+ PIPE_OP_RAST_SETUP_0 |
+ PIPE_OP_RAST_SETUP_1 |
+ PIPE_OP_RENDER),
+ PIPE_PRECALC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ radeonDDFastPath
+};
+
+#define ILLEGAL_ENABLES (TEXTURE0_3D | \
+ TEXTURE1_3D | \
+ ENABLE_TEXMAT0 | \
+ ENABLE_TEXMAT1 | \
+ ENABLE_TEXGEN0 | \
+ ENABLE_TEXGEN1 | \
+ ENABLE_USERCLIP | \
+ ENABLE_LIGHT | \
+ ENABLE_FOG)
+
+/* Build the PRECALC pipeline with our stage, if possible. Otherwise,
+ * return GL_FALSE.
+ */
+GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct gl_pipeline *pipe = &ctx->CVA.pre;
+
+ if ( rmesa->RenderIndex == 0 &&
+ (ctx->Enabled & ILLEGAL_ENABLES) == 0 &&
+ (ctx->Array.Flags & (VERT_OBJ_234 |
+ VERT_TEX0_4 |
+ VERT_TEX1_4 |
+ VERT_ELT)) == (VERT_OBJ_23 | VERT_ELT) )
+ {
+ pipe->stages[0] = &radeon_fast_stage;
+ pipe->stages[1] = 0;
+ pipe->new_inputs = ctx->RenderFlags & VERT_DATA;
+ pipe->ops = pipe->stages[0]->ops;
+
+ rmesa->OnFastPath = GL_TRUE;
+ return GL_TRUE;
+ }
+
+ if ( rmesa->OnFastPath ) {
+ rmesa->OnFastPath = GL_FALSE;
+
+ ctx->CVA.VB->ClipOrMask = 0;
+ ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS;
+ ctx->Array.NewArrayState |= ctx->Array.Summary;
+ }
+
+ return GL_FALSE;
+}
+
+
+/* Still do the normal fixup and copy-to-current, so this isn't so
+ * bad.
+ */
+#define ILLEGAL_INPUTS_IMM (VERT_OBJ_4 | \
+ VERT_TEX0_4 | \
+ VERT_TEX1_4 | \
+ VERT_MATERIAL)
+
+static void radeonDDCheckRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *d )
+{
+ d->type = PIPE_IMMEDIATE | PIPE_PRECALC;
+ d->inputs = ctx->RenderFlags;
+
+ /* Radeon requires an extra input:
+ */
+ if ( ctx->FogMode == FOG_FRAGMENT )
+ d->inputs |= VERT_FOG_COORD;
+
+ d->outputs = VERT_SETUP_FULL;
+
+ if ( ctx->IndirectTriangles & DD_SW_SETUP )
+ d->type = PIPE_IMMEDIATE;
+}
+
+
+GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr )
+{
+ int i, o;
+
+ for ( i = o = 0 ; i < nr ; i++ ) {
+ switch ( in[i].ops ) {
+ /* Completely replace Mesa's fog processing to generate fog
+ * coordinates instead of messing with colors.
+ */
+ case PIPE_OP_FOG:
+ out[o] = gl_fog_coord_stage;
+ o++;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0:
+ out[o] = in[i];
+ out[o].cva_state_change = (NEW_LIGHTING |
+ NEW_TEXTURING |
+ NEW_RASTER_OPS);
+ out[o].state_change = ~0;
+ out[o].check = radeonDDCheckPartialRasterSetup;
+ out[o].run = radeonDDPartialRasterSetup;
+ o++;
+ break;
+
+ case PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1:
+ out[o] = in[i];
+ out[o].check = radeonDDCheckRasterSetup;
+ out[o].run = radeonDDDoRasterSetup;
+ o++;
+ break;
+
+ default:
+ out[o++] = in[i];
+ break;
+ }
+ }
+
+ return o;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h
new file mode 100644
index 000000000..1af4e3eec
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h
@@ -0,0 +1,54 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_PIPELINE_H__
+#define __RADEON_PIPELINE_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx );
+extern GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out,
+ const struct gl_pipeline_stage *in,
+ GLuint nr );
+
+extern void radeonDDFastPathInit( void );
+extern void radeonDDFastPath( struct vertex_buffer *VB );
+
+extern void radeonDDEltPathInit( void );
+extern void radeonDDEltPath( struct vertex_buffer *VB );
+
+#endif
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c
new file mode 100644
index 000000000..e3cb90812
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c
@@ -0,0 +1,220 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_dri.h"
+
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_tris.h"
+#include "radeon_vb.h"
+#include "radeon_pipeline.h"
+
+#include "mem.h"
+
+#if 1
+/* Including xf86PciInfo.h introduces a bunch of errors...
+ */
+#define PCI_CHIP_RADEON_QD 0x5144
+#define PCI_CHIP_RADEON_QE 0x5145
+#define PCI_CHIP_RADEON_QF 0x5146
+#define PCI_CHIP_RADEON_QG 0x5147
+#endif
+
+
+/* Create the device specific screen private data struct.
+ */
+radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
+{
+ radeonScreenPtr radeonScreen;
+ RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv;
+
+ /* Check the DRI version */
+ {
+ int major, minor, patch;
+ if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) {
+ if ( major != 3 || minor != 1 || patch < 0 ) {
+ char msg[128];
+ sprintf( msg, "Radeon DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch );
+ __driMesaMessage( msg );
+ return GL_FALSE;
+ }
+ }
+ }
+
+ /* Check that the DDX driver version is compatible */
+ if ( sPriv->ddxMajor != 4 ||
+ sPriv->ddxMinor != 0 ||
+ sPriv->ddxPatch < 0 ) {
+ char msg[128];
+ sprintf( msg, "Radeon DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
+ __driMesaMessage( msg );
+ return GL_FALSE;
+ }
+
+ /* Check that the DRM driver version is compatible */
+ if ( sPriv->drmMajor != 1 ||
+ sPriv->drmMinor != 0 ||
+ sPriv->drmPatch < 0 ) {
+ char msg[128];
+ sprintf( msg, "Radeon DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
+ __driMesaMessage( msg );
+ return GL_FALSE;
+ }
+
+ /* Allocate the private area */
+ radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) );
+ if ( !radeonScreen ) return NULL;
+
+ /* This is first since which regions we map depends on whether or
+ * not we are using a PCI card.
+ */
+ radeonScreen->IsPCI = radeonDRIPriv->IsPCI;
+
+ radeonScreen->mmio.handle = radeonDRIPriv->registerHandle;
+ radeonScreen->mmio.size = radeonDRIPriv->registerSize;
+ if ( drmMap( sPriv->fd,
+ radeonScreen->mmio.handle,
+ radeonScreen->mmio.size,
+ &radeonScreen->mmio.map ) ) {
+ FREE( radeonScreen );
+ return NULL;
+ }
+
+ radeonScreen->status.handle = radeonDRIPriv->statusHandle;
+ radeonScreen->status.size = radeonDRIPriv->statusSize;
+ if ( drmMap( sPriv->fd,
+ radeonScreen->status.handle,
+ radeonScreen->status.size,
+ &radeonScreen->status.map ) ) {
+ drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
+ FREE( radeonScreen );
+ return NULL;
+ }
+ radeonScreen->scratch = (__volatile__ CARD32 *)
+ ((GLubyte *)radeonScreen->status.map + RADEON_SCRATCH_REG_OFFSET);
+
+ radeonScreen->buffers = drmMapBufs( sPriv->fd );
+ if ( !radeonScreen->buffers ) {
+ drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
+ drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
+ FREE( radeonScreen );
+ return NULL;
+ }
+
+ if ( !radeonScreen->IsPCI ) {
+ radeonScreen->agpTextures.handle = radeonDRIPriv->agpTexHandle;
+ radeonScreen->agpTextures.size = radeonDRIPriv->agpTexMapSize;
+ if ( drmMap( sPriv->fd,
+ radeonScreen->agpTextures.handle,
+ radeonScreen->agpTextures.size,
+ (drmAddressPtr)&radeonScreen->agpTextures.map ) ) {
+ drmUnmapBufs( radeonScreen->buffers );
+ drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
+ drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
+ FREE( radeonScreen );
+ return NULL;
+ }
+ }
+
+
+ switch ( radeonDRIPriv->deviceID ) {
+ case PCI_CHIP_RADEON_QD:
+ case PCI_CHIP_RADEON_QE:
+ case PCI_CHIP_RADEON_QF:
+ case PCI_CHIP_RADEON_QG:
+ radeonScreen->chipset = RADEON_CARD_TYPE_RADEON;
+ break;
+ default:
+ radeonScreen->chipset = RADEON_CARD_TYPE_RADEON;
+ break;
+ }
+
+ radeonScreen->cpp = radeonDRIPriv->bpp / 8;
+ radeonScreen->AGPMode = radeonDRIPriv->AGPMode;
+
+ radeonScreen->frontOffset = radeonDRIPriv->frontOffset;
+ radeonScreen->frontPitch = radeonDRIPriv->frontPitch;
+ radeonScreen->backOffset = radeonDRIPriv->backOffset;
+ radeonScreen->backPitch = radeonDRIPriv->backPitch;
+ radeonScreen->depthOffset = radeonDRIPriv->depthOffset;
+ radeonScreen->depthPitch = radeonDRIPriv->depthPitch;
+
+ radeonScreen->texOffset[RADEON_CARD_HEAP] = radeonDRIPriv->textureOffset;
+ radeonScreen->texSize[RADEON_CARD_HEAP] = radeonDRIPriv->textureSize;
+ radeonScreen->logTexGranularity[RADEON_CARD_HEAP] =
+ radeonDRIPriv->log2TexGran;
+
+ if ( radeonScreen->IsPCI ) {
+ radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
+ radeonScreen->texOffset[RADEON_AGP_HEAP] = 0;
+ radeonScreen->texSize[RADEON_AGP_HEAP] = 0;
+ radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = 0;
+ } else {
+ radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS;
+ radeonScreen->texOffset[RADEON_AGP_HEAP] =
+ radeonDRIPriv->agpTexOffset + RADEON_AGP_TEX_OFFSET;
+ radeonScreen->texSize[RADEON_AGP_HEAP] = radeonDRIPriv->agpTexMapSize;
+ radeonScreen->logTexGranularity[RADEON_AGP_HEAP] =
+ radeonDRIPriv->log2AGPTexGran;
+ }
+
+ radeonScreen->driScreen = sPriv;
+
+ radeonDDSetupInit();
+ radeonDDTriangleFuncsInit();
+ radeonDDFastPathInit();
+ radeonDDEltPathInit();
+
+ return radeonScreen;
+}
+
+/* Destroy the device specific screen private data struct.
+ */
+void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+ radeonScreenPtr radeonScreen = (radeonScreenPtr)sPriv->private;
+
+ if ( !radeonScreen->IsPCI ) {
+ drmUnmap( radeonScreen->agpTextures.map,
+ radeonScreen->agpTextures.size );
+ }
+ drmUnmapBufs( radeonScreen->buffers );
+ drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
+ drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
+
+ FREE( radeonScreen );
+ sPriv->private = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h
new file mode 100644
index 000000000..852e4f30a
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h
@@ -0,0 +1,87 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_SCREEN_H__
+#define __RADEON_SCREEN_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "radeon_sarea.h"
+
+typedef struct {
+ drmHandle handle; /* Handle to the DRM region */
+ drmSize size; /* Size of the DRM region */
+ drmAddress map; /* Mapping of the DRM region */
+} radeonRegionRec, *radeonRegionPtr;
+
+typedef struct {
+
+ GLint chipset;
+ GLint cpp;
+ GLint IsPCI; /* Current card is a PCI card */
+ GLint AGPMode;
+
+ GLuint frontOffset;
+ GLuint frontPitch;
+ GLuint backOffset;
+ GLuint backPitch;
+
+ GLuint depthOffset;
+ GLuint depthPitch;
+
+ /* Shared texture data */
+ int numTexHeaps;
+ int texOffset[RADEON_NR_TEX_HEAPS];
+ int texSize[RADEON_NR_TEX_HEAPS];
+ int logTexGranularity[RADEON_NR_TEX_HEAPS];
+
+ radeonRegionRec mmio;
+ radeonRegionRec status;
+ radeonRegionRec agpTextures;
+
+ drmBufMapPtr buffers;
+
+ __volatile__ CARD32 *scratch;
+
+ __DRIscreenPrivate *driScreen;
+
+} radeonScreenRec, *radeonScreenPtr;
+
+extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv );
+extern void radeonDestroyScreen( __DRIscreenPrivate *sPriv );
+
+#endif
+#endif /* __RADEON_SCREEN_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c
new file mode 100644
index 000000000..74ce2c827
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c
@@ -0,0 +1,346 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.c,v 1.2 2001/01/16 05:10:58 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ * Keith Whitwell <keithw@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_state.h"
+#include "radeon_span.h"
+
+#define DBG 0
+
+#define LOCAL_VARS \
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
+ radeonScreenPtr radeonScreen = rmesa->radeonScreen; \
+ __DRIscreenPrivate *sPriv = rmesa->driScreen; \
+ __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \
+ GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; \
+ GLuint height = dPriv->h; \
+ char *buf = (char *)(sPriv->pFB + \
+ rmesa->drawOffset + \
+ (dPriv->x * radeonScreen->cpp) + \
+ (dPriv->y * pitch)); \
+ char *read_buf = (char *)(sPriv->pFB + \
+ rmesa->readOffset + \
+ (dPriv->x * radeonScreen->cpp) + \
+ (dPriv->y * pitch)); \
+ GLushort p; \
+ (void) read_buf; (void) buf; (void) p
+
+#define LOCAL_DEPTH_VARS \
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
+ radeonScreenPtr radeonScreen = rmesa->radeonScreen; \
+ __DRIscreenPrivate *sPriv = rmesa->driScreen; \
+ __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \
+ GLuint height = dPriv->h; \
+ GLuint xo = dPriv->x; \
+ GLuint yo = dPriv->y; \
+ char *buf = (char *)(sPriv->pFB + radeonScreen->depthOffset); \
+ (void) buf
+
+#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
+
+#define INIT_MONO_PIXEL( p ) p = rmesa->Color
+
+#define CLIPPIXEL( _x, _y ) \
+ ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy))
+
+
+#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
+ if ((_y < miny) || (_y >= maxy)) { \
+ _n1 = 0, _x1 = x; \
+ } else { \
+ _n1 = _n; \
+ _x1 = _x; \
+ if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \
+ if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \
+ }
+
+#define Y_FLIP( _y ) (height - _y - 1)
+
+
+#define HW_LOCK() \
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \
+ FLUSH_BATCH( rmesa ); \
+ LOCK_HARDWARE( rmesa ); \
+ radeonWaitForIdleLocked( rmesa );
+
+#define HW_CLIPLOOP() \
+ do { \
+ __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \
+ int _nc = dPriv->numClipRects; \
+ \
+ while ( _nc-- ) { \
+ int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
+ int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
+ int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
+ int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;
+
+#define HW_ENDCLIPLOOP() \
+ } \
+ } while (0)
+
+#define HW_UNLOCK() \
+ UNLOCK_HARDWARE( rmesa )
+
+
+
+/* ================================================================
+ * Color buffer
+ */
+
+/* 16 bit, RGB565 color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
+ (((int)g & 0xfc) << 3) | \
+ (((int)b & 0xf8) >> 3))
+
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLushort *)(buf + _x*2 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+ do { \
+ GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \
+ rgba[0] = (p >> 8) & 0xf8; \
+ rgba[1] = (p >> 3) & 0xfc; \
+ rgba[2] = (p << 3) & 0xf8; \
+ rgba[3] = 0xff; \
+ if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \
+ if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \
+ if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \
+ } while (0)
+
+#define TAG(x) radeon##x##_RGB565
+#include "spantmp.h"
+
+/* 32 bit, ARGB8888 color spanline and pixel functions
+ */
+#define WRITE_RGBA( _x, _y, r, g, b, a ) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
+ (g << 8) | \
+ (r << 16) | \
+ (a << 24) )
+
+#define WRITE_PIXEL( _x, _y, p ) \
+ *(GLuint *)(buf + _x*4 + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y ) \
+do { \
+ GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \
+ rgba[0] = (p >> 16) & 0xff; \
+ rgba[1] = (p >> 8) & 0xff; \
+ rgba[2] = (p >> 0) & 0xff; \
+ rgba[3] = (p >> 24) & 0xff; \
+} while (0)
+
+#define TAG(x) radeon##x##_ARGB8888
+#include "spantmp.h"
+
+
+
+/* ================================================================
+ * Depth buffer
+ */
+
+/* The Radeon has depth tiling on all the time, so we have to convert
+ * the x,y coordinates into the memory bus address (mba) in the same
+ * manner as the engine. In each case, the linear block address (ba)
+ * is calculated, and then wired with x and y to produce the final
+ * memory address.
+ */
+static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa,
+ GLint x, GLint y )
+{
+ radeonScreenPtr radeonScreen = rmesa->radeonScreen;
+ GLuint pitch = radeonScreen->frontPitch;
+ GLuint ba, address = 0; /* a[0] = 0 */
+
+ ba = (y / 16) * (pitch / 32) + (x / 32);
+
+ address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */
+ address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */
+ address |= (x & 0x8) << 4; /* a[7] = x[3] */
+ address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */
+ address |= (y & 0x8) << 7; /* a[10] = y[3] */
+ address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */
+ address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */
+
+ return address;
+}
+
+static GLuint radeon_mba_z32( radeonContextPtr rmesa,
+ GLint x, GLint y )
+{
+ radeonScreenPtr radeonScreen = rmesa->radeonScreen;
+ GLuint pitch = radeonScreen->frontPitch;
+ GLuint ba, address = 0; /* a[0..1] = 0 */
+
+ ba = (y / 16) * (pitch / 16) + (x / 16);
+
+ address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */
+ address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */
+ address |=
+ (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */
+ address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */
+
+ address |= (y & 0x8) << 7; /* a[10] = y[3] */
+ address |=
+ (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */
+ address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */
+
+ return address;
+}
+
+
+/* 16-bit depth buffer functions
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLushort *)(buf + radeon_mba_z16( rmesa, _x+xo, _y+yo )) = d;
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLushort *)(buf + radeon_mba_z16( rmesa, _x+xo, _y+yo ));
+
+#define TAG(x) radeon##x##_16
+#include "depthtmp.h"
+
+/* 24 bit depth, 8 bit stencil depthbuffer functions
+ */
+#define WRITE_DEPTH( _x, _y, d ) \
+do { \
+ GLuint offset = radeon_mba_z32( rmesa, _x+xo, _y+yo ); \
+ GLuint tmp = *(GLuint *)(buf + offset); \
+ tmp &= 0xff000000; \
+ tmp |= ((d) & 0x00ffffff); \
+ *(GLuint *)(buf + offset) = tmp; \
+} while (0)
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x+xo, _y+yo )) & 0x00ffffff;
+
+#define TAG(x) radeon##x##_24_8
+#include "depthtmp.h"
+
+
+/* ================================================================
+ * Stencil buffer
+ */
+
+/* 24 bit depth, 8 bit stencil depthbuffer functions
+ */
+#define WRITE_STENCIL( _x, _y, d ) \
+do { \
+ GLuint offset = radeon_mba_z32( rmesa, _x+xo, _y+yo ); \
+ GLuint tmp = *(GLuint *)(buf + offset); \
+ tmp &= 0x00ffffff; \
+ tmp |= (((d) & 0xff) << 24); \
+ *(GLuint *)(buf + offset) = tmp; \
+} while (0)
+
+#define READ_STENCIL( d, _x, _y ) \
+do { \
+ GLuint offset = radeon_mba_z32( rmesa, _x+xo, _y+yo ); \
+ GLuint tmp = *(GLuint *)(buf + offset); \
+ tmp &= 0xff000000; \
+ d = tmp >> 24; \
+} while (0)
+
+#define TAG(x) radeon##x##_24_8
+#include "stenciltmp.h"
+
+
+
+void radeonDDInitSpanFuncs( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ switch ( rmesa->radeonScreen->cpp ) {
+ case 2:
+ ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_RGB565;
+ ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_RGB565;
+ ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB565;
+ ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_RGB565;
+ ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB565;
+ ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_RGB565;
+ ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_RGB565;
+ break;
+
+ case 4:
+ ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_ARGB8888;
+ ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_ARGB8888;
+ ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB8888;
+ ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_ARGB8888;
+ ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB8888;
+ ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_ARGB8888;
+ ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_ARGB8888;
+ break;
+
+ default:
+ break;
+ }
+
+ switch ( rmesa->glCtx->Visual->DepthBits ) {
+ case 16:
+ ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_16;
+ ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_16;
+ ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_16;
+ ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_16;
+ break;
+
+ case 24:
+ ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_24_8;
+ ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_24_8;
+ ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_24_8;
+ ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_24_8;
+
+ ctx->Driver.ReadStencilSpan = radeonReadStencilSpan_24_8;
+ ctx->Driver.WriteStencilSpan = radeonWriteStencilSpan_24_8;
+ ctx->Driver.ReadStencilPixels = radeonReadStencilPixels_24_8;
+ ctx->Driver.WriteStencilPixels = radeonWriteStencilPixels_24_8;
+ break;
+
+ default:
+ break;
+ }
+
+ ctx->Driver.WriteCI8Span = NULL;
+ ctx->Driver.WriteCI32Span = NULL;
+ ctx->Driver.WriteMonoCISpan = NULL;
+ ctx->Driver.WriteCI32Pixels = NULL;
+ ctx->Driver.WriteMonoCIPixels = NULL;
+ ctx->Driver.ReadCI32Span = NULL;
+ ctx->Driver.ReadCI32Pixels = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h
new file mode 100644
index 000000000..241f11c1e
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h
@@ -0,0 +1,45 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_SPAN_H__
+#define __RADEON_SPAN_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void radeonDDInitSpanFuncs( GLcontext *ctx );
+
+#endif
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
new file mode 100644
index 000000000..8cec8ff52
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
@@ -0,0 +1,1338 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ * Keith Whitwell <keithw@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+#include "radeon_tris.h"
+#include "radeon_vb.h"
+#include "radeon_tex.h"
+
+#include "mmath.h"
+#include "pb.h"
+#include "enums.h"
+
+
+/* =============================================================
+ * Alpha blending
+ */
+
+static void radeonUpdateAlphaMode( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ CARD32 a = rmesa->setup.pp_misc;
+ CARD32 p = rmesa->setup.pp_cntl;
+ CARD32 b = rmesa->setup.rb3d_blendcntl;
+ CARD32 c = rmesa->setup.rb3d_cntl;
+
+ if ( ctx->Color.AlphaEnabled ) {
+ GLubyte ref = ctx->Color.AlphaRef;
+
+ a &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
+
+ switch ( ctx->Color.AlphaFunc ) {
+ case GL_NEVER:
+ a |= RADEON_ALPHA_TEST_FAIL;
+ break;
+ case GL_LESS:
+ a |= RADEON_ALPHA_TEST_LESS;
+ break;
+ case GL_LEQUAL:
+ a |= RADEON_ALPHA_TEST_LEQUAL;
+ break;
+ case GL_EQUAL:
+ a |= RADEON_ALPHA_TEST_EQUAL;
+ break;
+ case GL_GEQUAL:
+ a |= RADEON_ALPHA_TEST_GEQUAL;
+ break;
+ case GL_GREATER:
+ a |= RADEON_ALPHA_TEST_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ a |= RADEON_ALPHA_TEST_NEQUAL;
+ break;
+ case GL_ALWAYS:
+ a |= RADEON_ALPHA_TEST_PASS;
+ break;
+ }
+
+ a |= (ref & RADEON_REF_ALPHA_MASK);
+ p |= RADEON_ALPHA_TEST_ENABLE;
+ } else {
+ p &= ~RADEON_ALPHA_TEST_ENABLE;
+ }
+
+ if ( ctx->Color.BlendEnabled ) {
+ b &= ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
+
+ switch ( ctx->Color.BlendSrcRGB ) {
+ case GL_ZERO:
+ b |= RADEON_SRC_BLEND_GL_ZERO;
+ break;
+ case GL_ONE:
+ b |= RADEON_SRC_BLEND_GL_ONE;
+ break;
+ case GL_DST_COLOR:
+ b |= RADEON_SRC_BLEND_GL_DST_COLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
+ break;
+ case GL_SRC_ALPHA:
+ b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case GL_DST_ALPHA:
+ b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
+ break;
+ }
+
+ switch ( ctx->Color.BlendDstRGB ) {
+ case GL_ZERO:
+ b |= RADEON_DST_BLEND_GL_ZERO;
+ break;
+ case GL_ONE:
+ b |= RADEON_DST_BLEND_GL_ONE;
+ break;
+ case GL_SRC_COLOR:
+ b |= RADEON_DST_BLEND_GL_SRC_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
+ break;
+ case GL_SRC_ALPHA:
+ b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ case GL_DST_ALPHA:
+ b |= RADEON_DST_BLEND_GL_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
+ break;
+ }
+
+ c |= RADEON_ALPHA_BLEND_ENABLE;
+ } else {
+ c &= ~RADEON_ALPHA_BLEND_ENABLE;
+ }
+
+ if ( rmesa->setup.pp_misc != a ) {
+ rmesa->setup.pp_misc = a;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+ }
+ if ( rmesa->setup.pp_cntl != p ) {
+ rmesa->setup.pp_cntl = p;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+ }
+ if ( rmesa->setup.rb3d_blendcntl != b ) {
+ rmesa->setup.rb3d_blendcntl = b;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+ }
+ if ( rmesa->setup.rb3d_cntl != c ) {
+ rmesa->setup.rb3d_cntl = c;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+ }
+}
+
+static void radeonDDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_ALPHA;
+}
+
+static void radeonDDBlendEquation( GLcontext *ctx, GLenum mode )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_ALPHA;
+}
+
+static void radeonDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_ALPHA;
+}
+
+static void radeonDDBlendFuncSeparate( GLcontext *ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_ALPHA;
+}
+
+
+/* =============================================================
+ * Depth testing
+ */
+
+static void radeonUpdateZMode( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ CARD32 z = rmesa->setup.rb3d_zstencilcntl;
+ CARD32 c = rmesa->setup.rb3d_cntl;
+
+ if ( ctx->Depth.Test ) {
+ z &= ~RADEON_Z_TEST_MASK;
+
+ switch ( ctx->Depth.Func ) {
+ case GL_NEVER:
+ z |= RADEON_Z_TEST_NEVER;
+ break;
+ case GL_ALWAYS:
+ z |= RADEON_Z_TEST_ALWAYS;
+ break;
+ case GL_LESS:
+ z |= RADEON_Z_TEST_LESS;
+ break;
+ case GL_LEQUAL:
+ z |= RADEON_Z_TEST_LEQUAL;
+ break;
+ case GL_EQUAL:
+ z |= RADEON_Z_TEST_EQUAL;
+ break;
+ case GL_GEQUAL:
+ z |= RADEON_Z_TEST_GEQUAL;
+ break;
+ case GL_GREATER:
+ z |= RADEON_Z_TEST_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ z |= RADEON_Z_TEST_NEQUAL;
+ break;
+ }
+
+ c |= RADEON_Z_ENABLE;
+ } else {
+ c &= ~RADEON_Z_ENABLE;
+ }
+
+ if ( ctx->Depth.Mask ) {
+ z |= RADEON_Z_WRITE_ENABLE;
+ } else {
+ z &= ~RADEON_Z_WRITE_ENABLE;
+ }
+
+ if ( rmesa->setup.rb3d_zstencilcntl != z ) {
+ rmesa->setup.rb3d_zstencilcntl = z;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+ if ( rmesa->setup.rb3d_cntl != c ) {
+ rmesa->setup.rb3d_cntl = c;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+}
+
+static void radeonDDDepthFunc( GLcontext *ctx, GLenum func )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_DEPTH;
+}
+
+static void radeonDDDepthMask( GLcontext *ctx, GLboolean flag )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_DEPTH;
+}
+
+static void radeonDDClearDepth( GLcontext *ctx, GLclampd d )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ switch ( rmesa->setup.rb3d_zstencilcntl & RADEON_DEPTH_FORMAT_MASK ) {
+ case RADEON_DEPTH_FORMAT_16BIT_INT_Z:
+ rmesa->ClearDepth = d * 0x0000ffff;
+ break;
+ case RADEON_DEPTH_FORMAT_24BIT_INT_Z:
+ rmesa->ClearDepth = d * 0x00ffffff;
+ break;
+ }
+}
+
+
+/* =============================================================
+ * Fog
+ */
+
+static void radeonUpdateFogAttrib( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ CARD32 p = rmesa->setup.pp_cntl;
+ GLubyte c[4];
+ CARD32 col;
+
+ if ( ctx->FogMode == FOG_FRAGMENT ) {
+ p |= RADEON_FOG_ENABLE;
+ } else {
+ p &= ~RADEON_FOG_ENABLE;
+ }
+
+ FLOAT_RGB_TO_UBYTE_RGB( c, ctx->Fog.Color );
+ col = radeonPackColor( 4, c[0], c[1], c[2], 0 );
+
+ if ( rmesa->setup.pp_fog_color != col ) {
+ rmesa->setup.pp_fog_color = col;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+ if ( rmesa->setup.pp_cntl != p ) {
+ rmesa->setup.pp_cntl = p;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+}
+
+static void radeonDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_FOG;
+}
+
+
+/* =============================================================
+ * Clipping
+ */
+
+static void radeonUpdateClipping( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if ( rmesa->driDrawable ) {
+ __DRIdrawablePrivate *drawable = rmesa->driDrawable;
+ int x = 0;
+ int y = 0;
+ int w = drawable->w - 1;
+ int h = drawable->h - 1;
+
+ if ( ctx->Scissor.Enabled ) {
+ if ( ctx->Scissor.X > x ) {
+ x = ctx->Scissor.X;
+ }
+ if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y ) {
+ y = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height;
+ }
+ if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < w ) {
+ w = ctx->Scissor.X + ctx->Scissor.Width - 1;
+ }
+ if ( drawable->h - ctx->Scissor.Y - 1 < h ) {
+ h = drawable->h - ctx->Scissor.Y - 1;
+ }
+ }
+
+ rmesa->scissor_rect.x1 = x + rmesa->driDrawable->x;
+ rmesa->scissor_rect.y1 = y + rmesa->driDrawable->y;
+ rmesa->scissor_rect.x2 = w + rmesa->driDrawable->x;
+ rmesa->scissor_rect.y2 = h + rmesa->driDrawable->y;
+
+ rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS;
+ }
+}
+
+static void radeonDDScissor( GLcontext *ctx,
+ GLint x, GLint y, GLsizei w, GLsizei h )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_CLIP;
+}
+
+
+/* =============================================================
+ * Culling
+ */
+
+static void radeonUpdateCull( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ CARD32 s = rmesa->setup.se_cntl;
+
+ s &= ~RADEON_FFACE_CULL_DIR_MASK;
+
+ switch ( ctx->Polygon.FrontFace ) {
+ case GL_CW:
+ s |= RADEON_FFACE_CULL_CW;
+ break;
+ case GL_CCW:
+ s |= RADEON_FFACE_CULL_CCW;
+ break;
+ }
+
+ s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
+
+ if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) {
+ switch ( ctx->Polygon.CullFaceMode ) {
+ case GL_FRONT:
+ s &= ~RADEON_FFACE_SOLID;
+ break;
+ case GL_BACK:
+ s &= ~RADEON_BFACE_SOLID;
+ break;
+ case GL_FRONT_AND_BACK:
+ s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
+ break;
+ }
+ }
+
+ if ( rmesa->setup.se_cntl != s ) {
+ rmesa->setup.se_cntl = s;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_SETUP;
+ }
+}
+
+static void radeonDDCullFace( GLcontext *ctx, GLenum mode )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_CULL;
+}
+
+static void radeonDDFrontFace( GLcontext *ctx, GLenum mode )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_CULL;
+}
+
+
+/* =============================================================
+ * Masks
+ */
+
+static void radeonUpdateMasks( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ GLuint mask = radeonPackColor( rmesa->radeonScreen->cpp,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] );
+
+ if ( rmesa->setup.rb3d_planemask != mask ) {
+ rmesa->setup.rb3d_planemask = mask;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+ }
+}
+
+static GLboolean radeonDDColorMask( GLcontext *ctx,
+ GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_MASKS;
+
+ return GL_TRUE;
+}
+
+
+/* =============================================================
+ * Rendering attributes
+ *
+ * We really don't want to recalculate all this every time we bind a
+ * texture. These things shouldn't change all that often, so it makes
+ * sense to break them out of the core texture state update routines.
+ */
+
+static void radeonDDLightModelfv( GLcontext *ctx, GLenum pname,
+ const GLfloat *param )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
+ CARD32 p = rmesa->setup.pp_cntl;
+
+ FLUSH_BATCH( rmesa );
+
+ if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) {
+ p |= RADEON_SPECULAR_ENABLE;
+ } else {
+ p &= ~RADEON_SPECULAR_ENABLE;
+ }
+
+ if ( rmesa->setup.pp_cntl != p ) {
+ rmesa->setup.pp_cntl = p;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+ }
+}
+
+static void radeonDDShadeModel( GLcontext *ctx, GLenum mode )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ CARD32 s = rmesa->setup.se_cntl;
+
+ s &= ~(RADEON_DIFFUSE_SHADE_MASK |
+ RADEON_ALPHA_SHADE_MASK |
+ RADEON_SPECULAR_SHADE_MASK |
+ RADEON_FOG_SHADE_MASK);
+
+ switch ( mode ) {
+ case GL_FLAT:
+ s |= (RADEON_DIFFUSE_SHADE_FLAT |
+ RADEON_ALPHA_SHADE_FLAT |
+ RADEON_SPECULAR_SHADE_FLAT |
+ RADEON_FOG_SHADE_FLAT);
+ break;
+ case GL_SMOOTH:
+ s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
+ RADEON_ALPHA_SHADE_GOURAUD |
+ RADEON_SPECULAR_SHADE_GOURAUD |
+ RADEON_FOG_SHADE_GOURAUD);
+ break;
+ default:
+ return;
+ }
+
+ if ( rmesa->setup.se_cntl != s ) {
+ FLUSH_BATCH( rmesa );
+ rmesa->setup.se_cntl = s;
+
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= RADEON_UPLOAD_SETUP;
+ }
+}
+
+
+/* =============================================================
+ * Window position
+ */
+
+void radeonUpdateWindow( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
+ GLfloat xoffset = (GLfloat)dPriv->x;
+ GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
+ const GLfloat one = 1.0;
+#if 0
+ CARD32 m = rmesa->setup.re_misc;
+ CARD32 sx, sy;
+#endif
+
+ rmesa->setup.se_vport_xscale = *(GLuint *)&one;
+ rmesa->setup.se_vport_xoffset = *(GLuint *)&xoffset;
+ rmesa->setup.se_vport_yscale = *(GLuint *)&one;
+ rmesa->setup.se_vport_yoffset = *(GLuint *)&yoffset;
+ rmesa->setup.se_vport_zscale = *(GLuint *)&rmesa->depth_scale;
+ rmesa->setup.se_vport_zoffset = 0x00000000;
+
+#if 0
+ /* FIXME: This appears to be broken...
+ */
+ m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
+ RADEON_STIPPLE_Y_OFFSET_MASK);
+
+ sx = rmesa->driDrawable->x & RADEON_STIPPLE_COORD_MASK;
+ sy = rmesa->driDrawable->y & RADEON_STIPPLE_COORD_MASK;
+
+ m |= ((sx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
+ (sy << RADEON_STIPPLE_Y_OFFSET_SHIFT));
+
+ if ( rmesa->setup.re_misc != m ) {
+ rmesa->setup.re_misc = m;
+ rmesa->dirty |= RADEON_UPLOAD_MISC;
+ }
+#endif
+ rmesa->dirty |= RADEON_UPLOAD_VIEWPORT;
+}
+
+
+/* =============================================================
+ * Miscellaneous
+ */
+
+static void radeonDDClearColor( GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ rmesa->ClearColor = radeonPackColor( rmesa->radeonScreen->cpp,
+ r, g, b, a );
+}
+
+static void radeonDDColor( GLcontext *ctx,
+ GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ rmesa->Color = radeonPackColor( rmesa->radeonScreen->cpp,
+ r, g, b, a );
+}
+
+static void radeonDDLogicOpCode( GLcontext *ctx, GLenum opcode )
+{
+ if ( ctx->Color.ColorLogicOpEnabled ) {
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ FLUSH_BATCH( rmesa );
+
+ /* FIXME: We can do color logic ops.
+ */
+ if ( opcode == GL_COPY ) {
+ rmesa->Fallback &= ~RADEON_FALLBACK_LOGICOP;
+ } else {
+ rmesa->Fallback |= RADEON_FALLBACK_LOGICOP;
+ }
+ }
+}
+
+static GLboolean radeonDDSetDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ int found = GL_TRUE;
+
+ FLUSH_BATCH( rmesa );
+
+ if ( rmesa->DrawBuffer != mode ) {
+ rmesa->DrawBuffer = mode;
+ rmesa->Fallback &= ~RADEON_FALLBACK_DRAW_BUFFER;
+
+ switch ( mode ) {
+ case GL_FRONT_LEFT:
+ rmesa->drawOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->drawPitch = rmesa->radeonScreen->frontPitch;
+ break;
+ case GL_BACK_LEFT:
+ rmesa->drawOffset = rmesa->radeonScreen->backOffset;
+ rmesa->drawPitch = rmesa->radeonScreen->backPitch;
+ break;
+ default:
+ rmesa->Fallback |= RADEON_FALLBACK_DRAW_BUFFER;
+ found = GL_FALSE;
+ break;
+ }
+
+ rmesa->setup.rb3d_coloroffset =
+ (rmesa->drawOffset & RADEON_COLOROFFSET_MASK);
+ rmesa->setup.rb3d_colorpitch = rmesa->drawPitch;
+
+ rmesa->new_state |= RADEON_NEW_WINDOW;
+ }
+
+ return found;
+}
+
+static void radeonDDSetReadBuffer( GLcontext *ctx,
+ GLframebuffer *colorBuffer,
+ GLenum mode )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ rmesa->Fallback &= ~RADEON_FALLBACK_READ_BUFFER;
+
+ switch ( mode ) {
+ case GL_FRONT_LEFT:
+ rmesa->readOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->readPitch = rmesa->radeonScreen->frontPitch;
+ break;
+ case GL_BACK_LEFT:
+ rmesa->readOffset = rmesa->radeonScreen->backOffset;
+ rmesa->readPitch = rmesa->radeonScreen->backPitch;
+ break;
+ default:
+ rmesa->Fallback |= RADEON_FALLBACK_READ_BUFFER;
+ break;
+ }
+}
+
+
+/* =============================================================
+ * Polygon stipple
+ */
+
+static void radeonDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLuint *stipple = (GLuint *)mask;
+
+ FLUSH_BATCH( rmesa );
+
+ if ( ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON ) {
+ rmesa->setup.pp_cntl |= RADEON_STIPPLE_ENABLE;
+ } else {
+ rmesa->setup.pp_cntl &= ~RADEON_STIPPLE_ENABLE;
+ }
+
+ LOCK_HARDWARE( rmesa );
+
+ /* FIXME: Use window x,y offsets into stipple RAM.
+ */
+ drmRadeonPolygonStipple( rmesa->driFd, stipple );
+
+ UNLOCK_HARDWARE( rmesa );
+
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+}
+
+
+/* =============================================================
+ * State enable/disable
+ */
+
+static void radeonDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ switch ( cap ) {
+ case GL_ALPHA_TEST:
+ case GL_BLEND:
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_ALPHA;
+ break;
+
+ case GL_CULL_FACE:
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_CULL;
+ break;
+
+ case GL_DEPTH_TEST:
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_DEPTH;
+ break;
+
+ case GL_DITHER:
+ do {
+ CARD32 r = rmesa->setup.rb3d_cntl;
+ FLUSH_BATCH( rmesa );
+
+ if ( ctx->Color.DitherFlag ) {
+ r |= RADEON_DITHER_ENABLE;
+ } else {
+ r &= ~RADEON_DITHER_ENABLE;
+ }
+
+ if ( rmesa->setup.rb3d_cntl != r ) {
+ rmesa->setup.rb3d_cntl = r;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+ } while (0);
+ break;
+
+ case GL_FOG:
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_FOG;
+ break;
+
+ case GL_INDEX_LOGIC_OP:
+ case GL_COLOR_LOGIC_OP:
+ FLUSH_BATCH( rmesa );
+ if ( state && ctx->Color.LogicOp != GL_COPY ) {
+ rmesa->Fallback |= RADEON_FALLBACK_LOGICOP;
+ } else {
+ rmesa->Fallback &= ~RADEON_FALLBACK_LOGICOP;
+ }
+ break;
+
+ case GL_SCISSOR_TEST:
+ FLUSH_BATCH( rmesa );
+ rmesa->scissor = state;
+ rmesa->new_state |= RADEON_NEW_CLIP;
+ break;
+
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ break;
+
+ case GL_POLYGON_STIPPLE:
+ if ( ctx->PB->primitive == GL_POLYGON ) {
+ FLUSH_BATCH( rmesa );
+ if ( state ) {
+ rmesa->setup.pp_cntl |= RADEON_STIPPLE_ENABLE;
+ } else {
+ rmesa->setup.pp_cntl &= ~RADEON_STIPPLE_ENABLE;
+ }
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+ break;
+
+ default:
+ return;
+ }
+}
+
+
+/* =============================================================
+ * State initialization, management
+ */
+
+static void radeonDDPrintDirty( const char *msg, GLuint state )
+{
+ fprintf( stderr,
+ "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ msg,
+ state,
+ (state & RADEON_UPLOAD_CONTEXT) ? "context, " : "",
+ (state & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "",
+ (state & RADEON_UPLOAD_LINE) ? "line, " : "",
+ (state & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "",
+ (state & RADEON_UPLOAD_MASKS) ? "masks, " : "",
+ (state & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "",
+ (state & RADEON_UPLOAD_SETUP) ? "setup, " : "",
+ (state & RADEON_UPLOAD_TCL) ? "tcl, " : "",
+ (state & RADEON_UPLOAD_MISC) ? "misc, " : "",
+ (state & RADEON_UPLOAD_TEX0) ? "tex0, " : "",
+ (state & RADEON_UPLOAD_TEX1) ? "tex1, " : "",
+ (state & RADEON_UPLOAD_TEX2) ? "tex2, " : "",
+ (state & RADEON_UPLOAD_TEX0IMAGES) ? "tex0 images, " : "",
+ (state & RADEON_UPLOAD_TEX1IMAGES) ? "tex1 images, " : "",
+ (state & RADEON_UPLOAD_TEX2IMAGES) ? "tex2 images, " : "",
+ (state & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
+ (state & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
+}
+
+/*
+ * Load the current context's state into the hardware.
+ *
+ * NOTE: Be VERY careful about ensuring the context state is marked for
+ * upload, the only place it shouldn't be uploaded is when the setup
+ * state has changed in ReducedPrimitiveChange as this comes right after
+ * a state update.
+ *
+ * Blits of any type should always upload the context and masks after
+ * they are done.
+ */
+void radeonEmitHwStateLocked( radeonContextPtr rmesa )
+{
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+ radeon_context_regs_t *regs = &(rmesa->setup);
+ radeonTexObjPtr t0 = rmesa->CurrentTexObj[0];
+ radeonTexObjPtr t1 = rmesa->CurrentTexObj[1];
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ radeonDDPrintDirty( "radeonEmitHwStateLocked", rmesa->dirty );
+ }
+
+ if ( (rmesa->dirty & RADEON_UPLOAD_TEX0IMAGES) && t0 ) {
+ radeonUploadTexImages( rmesa, t0 );
+ rmesa->dirty &= ~RADEON_UPLOAD_TEX0IMAGES;
+ }
+ if ( (rmesa->dirty & RADEON_UPLOAD_TEX1IMAGES) && t1 ) {
+ radeonUploadTexImages( rmesa, t1 );
+ rmesa->dirty &= ~RADEON_UPLOAD_TEX1IMAGES;
+ }
+ if ( rmesa->dirty & RADEON_UPLOAD_TEX2IMAGES ) {
+ /* FIXME: Enable the third texture unit... */
+ rmesa->dirty &= ~RADEON_UPLOAD_TEX2IMAGES;
+ }
+
+ if ( rmesa->dirty & (RADEON_UPLOAD_CONTEXT |
+ RADEON_UPLOAD_VERTFMT |
+ RADEON_UPLOAD_LINE |
+ RADEON_UPLOAD_BUMPMAP |
+ RADEON_UPLOAD_MASKS |
+ RADEON_UPLOAD_VIEWPORT |
+ RADEON_UPLOAD_SETUP |
+ RADEON_UPLOAD_TCL |
+ RADEON_UPLOAD_MISC) ) {
+ memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) );
+ }
+
+ /* Assemble the texture state, combining the texture object and
+ * texture environment state into the hardware texture unit state.
+ */
+ if ( (rmesa->dirty & RADEON_UPLOAD_TEX0) && t0 ) {
+ radeon_texture_regs_t *tex = &sarea->TexState[0];
+
+ tex->pp_txfilter = t0->setup.pp_txfilter | rmesa->lod_bias[0] << 8;
+ tex->pp_txformat = t0->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ0;
+ tex->pp_txoffset = t0->setup.pp_txoffset;
+
+ tex->pp_txcblend = rmesa->color_combine[0];
+ tex->pp_txablend = rmesa->alpha_combine[0];
+ tex->pp_tfactor = rmesa->env_color[0];
+
+ tex->pp_border_color = t0->setup.pp_border_color;
+ }
+
+ if ( (rmesa->dirty & RADEON_UPLOAD_TEX1) && t1 ) {
+ radeon_texture_regs_t *tex = &sarea->TexState[1];
+
+ tex->pp_txfilter = t1->setup.pp_txfilter | rmesa->lod_bias[1] << 8;
+ tex->pp_txformat = t1->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ1;
+ tex->pp_txoffset = t1->setup.pp_txoffset;
+
+ tex->pp_txcblend = rmesa->color_combine[1];
+ tex->pp_txablend = rmesa->alpha_combine[1];
+ tex->pp_tfactor = rmesa->env_color[1];
+
+ tex->pp_border_color = t1->setup.pp_border_color;
+ }
+
+ if ( rmesa->dirty & RADEON_UPLOAD_TEX2 ) {
+ /* FIXME: Enable the third texture unit... */
+ memset( &sarea->TexState[2], 0, sizeof(sarea->TexState[2]) );
+ }
+
+ sarea->vertsize = rmesa->vertsize;
+ sarea->vc_format = rmesa->vc_format;
+
+ sarea->dirty |= rmesa->dirty;
+ rmesa->dirty &= RADEON_UPLOAD_CLIPRECTS;
+}
+
+static void radeonDDPrintState( const char *msg, GLuint flags )
+{
+ fprintf( stderr,
+ "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
+ msg,
+ flags,
+ (flags & RADEON_NEW_CONTEXT) ? "context, " : "",
+ (flags & RADEON_NEW_ALPHA) ? "alpha, " : "",
+ (flags & RADEON_NEW_DEPTH) ? "depth, " : "",
+ (flags & RADEON_NEW_FOG) ? "fog, " : "",
+ (flags & RADEON_NEW_CLIP) ? "clip, " : "",
+ (flags & RADEON_NEW_TEXTURE) ? "texture, " : "",
+ (flags & RADEON_NEW_CULL) ? "cull, " : "",
+ (flags & RADEON_NEW_MASKS) ? "masks, " : "",
+ (flags & RADEON_NEW_WINDOW) ? "window, " : "" );
+}
+
+void radeonDDUpdateHWState( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ int new_state = rmesa->new_state;
+
+ if ( new_state ) {
+ FLUSH_BATCH( rmesa );
+
+ rmesa->new_state = 0;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG )
+ radeonDDPrintState( "radeonUpdateHwState", new_state );
+
+ /* Update the various parts of the context's state.
+ */
+ if ( new_state & RADEON_NEW_ALPHA )
+ radeonUpdateAlphaMode( ctx );
+
+ if ( new_state & RADEON_NEW_DEPTH )
+ radeonUpdateZMode( ctx );
+
+ if ( new_state & RADEON_NEW_FOG )
+ radeonUpdateFogAttrib( ctx );
+
+ if ( new_state & RADEON_NEW_CLIP )
+ radeonUpdateClipping( ctx );
+
+ if ( new_state & RADEON_NEW_CULL )
+ radeonUpdateCull( ctx );
+
+ if ( new_state & RADEON_NEW_MASKS )
+ radeonUpdateMasks( ctx );
+
+ if ( new_state & RADEON_NEW_WINDOW )
+ radeonUpdateWindow( ctx );
+
+ if ( new_state & RADEON_NEW_TEXTURE )
+ radeonUpdateTextureState( ctx );
+ }
+}
+
+/* This is called when Mesa switches between rendering triangle
+ * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
+ * and lines, points and bitmaps.
+ *
+ * As the radeon uses triangles to render lines and points, it is
+ * necessary to turn off hardware culling when rendering these
+ * primitives.
+ */
+static void radeonDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ CARD32 s = rmesa->setup.se_cntl;
+
+ s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
+
+ if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) {
+ switch ( ctx->Polygon.CullFaceMode ) {
+ case GL_FRONT:
+ s &= ~RADEON_FFACE_SOLID;
+ break;
+ case GL_BACK:
+ s &= ~RADEON_BFACE_SOLID;
+ break;
+ case GL_FRONT_AND_BACK:
+ s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
+ break;
+ }
+ }
+
+ if ( rmesa->setup.se_cntl != s ) {
+ FLUSH_BATCH( rmesa );
+ rmesa->setup.se_cntl = s;
+
+ /* NOTE: Only upload the setup state, everything else has been
+ * uploaded by the usual means already. Also, note that this is
+ * an optimization (see comment in the kernel's radeon_state.c),
+ * which will not be necessary when/if we use the Radeon's
+ * native point/line support.
+ */
+ rmesa->dirty |= RADEON_UPLOAD_SETUP;
+ }
+}
+
+
+#define INTERESTED (~(NEW_MODELVIEW | \
+ NEW_PROJECTION | \
+ NEW_TEXTURE_MATRIX | \
+ NEW_USER_CLIP | \
+ NEW_CLIENT_STATE))
+
+void radeonDDUpdateState( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if ( ctx->NewState & INTERESTED ) {
+ radeonDDChooseRenderState( ctx );
+ radeonDDChooseRasterSetupFunc( ctx );
+ }
+
+ /* Need to do this here to detect texture fallbacks before
+ * setting triangle functions.
+ * GH: Do we need this anymore? The Radeon doesn't really have
+ * texturing fallbacks like the r128...
+ */
+ if ( rmesa->new_state & RADEON_NEW_TEXTURE ) {
+ radeonDDUpdateHWState( ctx );
+ }
+
+ if ( !rmesa->Fallback ) {
+ ctx->IndirectTriangles &= ~DD_SW_RASTERIZE;
+ ctx->IndirectTriangles |= rmesa->IndirectTriangles;
+
+ ctx->Driver.PointsFunc = rmesa->PointsFunc;
+ ctx->Driver.LineFunc = rmesa->LineFunc;
+ ctx->Driver.TriangleFunc = rmesa->TriangleFunc;
+ ctx->Driver.QuadFunc = rmesa->QuadFunc;
+ }
+}
+
+
+/* Initialize the context's hardware state.
+ */
+void radeonDDInitState( radeonContextPtr rmesa )
+{
+ GLuint color_fmt, depth_fmt;
+
+ switch ( rmesa->radeonScreen->cpp ) {
+ case 2:
+ color_fmt = RADEON_COLOR_FORMAT_RGB565;
+ break;
+ case 4:
+ color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
+ break;
+ default:
+ fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
+ exit( -1 );
+ }
+
+ rmesa->ClearColor = 0x00000000;
+
+ switch ( rmesa->glCtx->Visual->DepthBits ) {
+ case 16:
+ rmesa->ClearDepth = 0x0000ffff;
+ depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
+ rmesa->depth_scale = 1.0 / (GLfloat)0xffff;
+ break;
+ case 24:
+ rmesa->ClearDepth = 0x00ffffff;
+ depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
+ rmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
+ break;
+ default:
+ fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
+ rmesa->glCtx->Visual->DepthBits );
+ exit( -1 );
+ }
+
+ rmesa->RenderIndex = RADEON_FALLBACK_BIT;
+ rmesa->PointsFunc = NULL;
+ rmesa->LineFunc = NULL;
+ rmesa->TriangleFunc = NULL;
+ rmesa->QuadFunc = NULL;
+
+ rmesa->IndirectTriangles = 0;
+ rmesa->Fallback = 0;
+
+ if ( rmesa->glCtx->Visual->DBflag ) {
+ rmesa->DrawBuffer = GL_BACK_LEFT;
+ rmesa->drawOffset = rmesa->readOffset = rmesa->radeonScreen->backOffset;
+ rmesa->drawPitch = rmesa->readPitch = rmesa->radeonScreen->backPitch;
+ } else {
+ rmesa->DrawBuffer = GL_FRONT_LEFT;
+ rmesa->drawOffset = rmesa->readOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->drawPitch = rmesa->readPitch = rmesa->radeonScreen->frontPitch;
+ }
+
+ /* Harware state:
+ */
+ rmesa->setup.pp_misc = (RADEON_ALPHA_TEST_PASS |
+ RADEON_CHROMA_FUNC_FAIL |
+ RADEON_CHROMA_KEY_NEAREST |
+ RADEON_SHADOW_FUNC_EQUAL |
+ RADEON_SHADOW_PASS_1 |
+ RADEON_RIGHT_HAND_CUBE_OGL);
+
+ rmesa->setup.pp_fog_color = ((0x00000000 & RADEON_FOG_COLOR_MASK) |
+ RADEON_FOG_VERTEX |
+ RADEON_FOG_USE_DEPTH);
+
+ rmesa->setup.re_solid_color = 0x00000000;
+
+ rmesa->setup.rb3d_blendcntl = (RADEON_SRC_BLEND_GL_ONE |
+ RADEON_DST_BLEND_GL_ZERO );
+
+ rmesa->setup.rb3d_depthoffset = rmesa->radeonScreen->depthOffset;
+
+ rmesa->setup.rb3d_depthpitch = ((rmesa->radeonScreen->depthPitch &
+ RADEON_DEPTHPITCH_MASK) |
+ RADEON_DEPTH_ENDIAN_NO_SWAP);
+
+ rmesa->setup.rb3d_zstencilcntl = (depth_fmt |
+ RADEON_Z_TEST_LESS |
+ RADEON_STENCIL_TEST_ALWAYS |
+ RADEON_STENCIL_S_FAIL_KEEP |
+ RADEON_STENCIL_ZPASS_KEEP |
+ RADEON_STENCIL_ZFAIL_KEEP |
+ RADEON_Z_WRITE_ENABLE);
+
+ rmesa->setup.pp_cntl = (RADEON_SCISSOR_ENABLE |
+ RADEON_ANTI_ALIAS_NONE);
+
+ rmesa->setup.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
+ color_fmt |
+ RADEON_ZBLOCK16);
+
+ rmesa->setup.rb3d_coloroffset = (rmesa->drawOffset &
+ RADEON_COLOROFFSET_MASK);
+
+ rmesa->setup.re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) |
+ (0x7ff << RADEON_RE_HEIGHT_SHIFT));
+
+ rmesa->setup.rb3d_colorpitch = ((rmesa->drawPitch &
+ RADEON_COLORPITCH_MASK) |
+ RADEON_COLOR_ENDIAN_NO_SWAP);
+
+ rmesa->setup.se_cntl = (RADEON_FFACE_CULL_CW |
+ RADEON_BFACE_SOLID |
+ RADEON_FFACE_SOLID |
+ RADEON_FLAT_SHADE_VTX_LAST |
+ RADEON_DIFFUSE_SHADE_GOURAUD |
+ RADEON_ALPHA_SHADE_GOURAUD |
+ RADEON_SPECULAR_SHADE_GOURAUD |
+ RADEON_FOG_SHADE_GOURAUD |
+ RADEON_VPORT_XY_XFORM_ENABLE |
+ RADEON_VPORT_Z_XFORM_ENABLE |
+ RADEON_VTX_PIX_CENTER_OGL |
+ RADEON_ROUND_MODE_TRUNC |
+ RADEON_ROUND_PREC_8TH_PIX);
+
+ rmesa->setup.se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
+ RADEON_VTX_Z_PRE_MULT_1_OVER_W0 |
+ RADEON_TEX1_W_ROUTING_USE_Q1);
+
+ rmesa->setup.re_line_pattern = ((0x0000 & RADEON_LINE_PATTERN_MASK) |
+ (0 << RADEON_LINE_REPEAT_COUNT_SHIFT) |
+ (0 << RADEON_LINE_PATTERN_START_SHIFT) |
+ RADEON_LINE_PATTERN_LITTLE_BIT_ORDER);
+
+ rmesa->setup.re_line_state = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) |
+ (0 << RADEON_LINE_CURRENT_COUNT_SHIFT));
+
+ rmesa->setup.se_line_width = 0x0000000;
+
+ rmesa->setup.pp_lum_matrix = 0x00000000;
+
+ rmesa->setup.pp_rot_matrix_0 = 0x00000000;
+ rmesa->setup.pp_rot_matrix_1 = 0x00000000;
+
+ rmesa->setup.rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) |
+ (0xff << RADEON_STENCIL_MASK_SHIFT) |
+ (0xff << RADEON_STENCIL_WRITEMASK_SHIFT));
+
+ rmesa->setup.rb3d_ropcntl = 0x00000000;
+ rmesa->setup.rb3d_planemask = 0xffffffff;
+
+ rmesa->setup.se_vport_xscale = 0x00000000;
+ rmesa->setup.se_vport_xoffset = 0x00000000;
+ rmesa->setup.se_vport_yscale = 0x00000000;
+ rmesa->setup.se_vport_yoffset = 0x00000000;
+ rmesa->setup.se_vport_zscale = 0x00000000;
+ rmesa->setup.se_vport_zoffset = 0x00000000;
+
+ rmesa->setup.se_cntl_status = (RADEON_VC_NO_SWAP |
+ RADEON_TCL_BYPASS);
+
+#ifdef TCL_ENABLE
+ /* FIXME: Obviously these need to be properly initialized */
+ rmesa->setup.se_tcl_material_emmissive.red = 0x00000000;
+ rmesa->setup.se_tcl_material_emmissive.green = 0x00000000;
+ rmesa->setup.se_tcl_material_emmissive.blue = 0x00000000;
+ rmesa->setup.se_tcl_material_emmissive.alpha = 0x00000000;
+
+ rmesa->setup.se_tcl_material_ambient.red = 0x00000000;
+ rmesa->setup.se_tcl_material_ambient.green = 0x00000000;
+ rmesa->setup.se_tcl_material_ambient.blue = 0x00000000;
+ rmesa->setup.se_tcl_material_ambient.alpha = 0x00000000;
+
+ rmesa->setup.se_tcl_material_diffuse.red = 0x00000000;
+ rmesa->setup.se_tcl_material_diffuse.green = 0x00000000;
+ rmesa->setup.se_tcl_material_diffuse.blue = 0x00000000;
+ rmesa->setup.se_tcl_material_diffuse.alpha = 0x00000000;
+
+ rmesa->setup.se_tcl_material_specular.red = 0x00000000;
+ rmesa->setup.se_tcl_material_specular.green = 0x00000000;
+ rmesa->setup.se_tcl_material_specular.blue = 0x00000000;
+ rmesa->setup.se_tcl_material_specular.alpha = 0x00000000;
+
+ rmesa->setup.se_tcl_shininess = 0x00000000;
+ rmesa->setup.se_tcl_output_vtx_fmt = 0x00000000;
+ rmesa->setup.se_tcl_output_vtx_sel = 0x00000000;
+ rmesa->setup.se_tcl_matrix_select_0 = 0x00000000;
+ rmesa->setup.se_tcl_matrix_select_1 = 0x00000000;
+ rmesa->setup.se_tcl_ucp_vert_blend_ctl = 0x00000000;
+ rmesa->setup.se_tcl_texture_proc_ctl = 0x00000000;
+ rmesa->setup.se_tcl_light_model_ctl = 0x00000000;
+ for ( i = 0 ; i < 4 ; i++ ) {
+ rmesa->setup.se_tcl_per_light_ctl[i] = 0x00000000;
+ }
+#endif
+
+ rmesa->setup.re_top_left = ((0 << RADEON_RE_LEFT_SHIFT) |
+ (0 << RADEON_RE_TOP_SHIFT) );
+
+ rmesa->setup.re_misc = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) |
+ (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) |
+ RADEON_STIPPLE_LITTLE_BIT_ORDER);
+
+ rmesa->env_color[0] = 0x00000000;
+ rmesa->env_color[1] = 0x00000000;
+ rmesa->env_color[2] = 0x00000000;
+
+ rmesa->new_state = RADEON_NEW_ALL;
+}
+
+/* Initialize the driver's state functions.
+ */
+void radeonDDInitStateFuncs( GLcontext *ctx )
+{
+ ctx->Driver.UpdateState = radeonDDUpdateState;
+
+ ctx->Driver.ClearIndex = NULL;
+ ctx->Driver.ClearColor = radeonDDClearColor;
+ ctx->Driver.Index = NULL;
+ ctx->Driver.Color = radeonDDColor;
+ ctx->Driver.SetDrawBuffer = radeonDDSetDrawBuffer;
+ ctx->Driver.SetReadBuffer = radeonDDSetReadBuffer;
+
+ ctx->Driver.IndexMask = NULL;
+ ctx->Driver.ColorMask = radeonDDColorMask;
+ ctx->Driver.LogicOp = NULL;
+ ctx->Driver.Dither = NULL;
+
+ ctx->Driver.NearFar = NULL;
+
+ ctx->Driver.RenderStart = radeonDDUpdateHWState;
+ ctx->Driver.RenderFinish = NULL;
+ ctx->Driver.RasterSetup = NULL;
+
+ ctx->Driver.RenderVBClippedTab = NULL;
+ ctx->Driver.RenderVBCulledTab = NULL;
+ ctx->Driver.RenderVBRawTab = NULL;
+
+ ctx->Driver.ReducedPrimitiveChange = radeonDDReducedPrimitiveChange;
+ ctx->Driver.MultipassFunc = NULL;
+
+ ctx->Driver.AlphaFunc = radeonDDAlphaFunc;
+ ctx->Driver.BlendEquation = radeonDDBlendEquation;
+ ctx->Driver.BlendFunc = radeonDDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = radeonDDBlendFuncSeparate;
+ ctx->Driver.ClearDepth = radeonDDClearDepth;
+ ctx->Driver.CullFace = radeonDDCullFace;
+ ctx->Driver.FrontFace = radeonDDFrontFace;
+ ctx->Driver.DepthFunc = radeonDDDepthFunc;
+ ctx->Driver.DepthMask = radeonDDDepthMask;
+ ctx->Driver.DepthRange = NULL;
+ ctx->Driver.Enable = radeonDDEnable;
+ ctx->Driver.Fogfv = radeonDDFogfv;
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.Lightfv = NULL;
+ ctx->Driver.LightModelfv = radeonDDLightModelfv;
+ ctx->Driver.LogicOpcode = radeonDDLogicOpCode;
+ ctx->Driver.PolygonMode = NULL;
+ ctx->Driver.PolygonStipple = radeonDDPolygonStipple;
+ ctx->Driver.Scissor = radeonDDScissor;
+ ctx->Driver.ShadeModel = radeonDDShadeModel;
+ ctx->Driver.ClearStencil = NULL;
+ ctx->Driver.StencilFunc = NULL;
+ ctx->Driver.StencilMask = NULL;
+ ctx->Driver.StencilOp = NULL;
+ ctx->Driver.Viewport = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h
new file mode 100644
index 000000000..9a368d989
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h
@@ -0,0 +1,55 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_STATE_H__
+#define __RADEON_STATE_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "radeon_context.h"
+
+extern void radeonDDInitState( radeonContextPtr rmesa );
+extern void radeonDDInitStateFuncs( GLcontext *ctx );
+
+extern void radeonDDUpdateState( GLcontext *ctx );
+extern void radeonDDUpdateHWState( GLcontext *ctx );
+
+extern void radeonUpdateWindow( GLcontext *ctx );
+
+extern void radeonEmitHwStateLocked( radeonContextPtr rmesa );
+
+#endif
+#endif
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c
new file mode 100644
index 000000000..32709537b
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c
@@ -0,0 +1,2253 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.2 2001/01/16 05:10:59 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+#include "radeon_vb.h"
+#include "radeon_tex.h"
+
+#include "mmath.h"
+#include "simple_list.h"
+#include "enums.h"
+#include "mem.h"
+
+
+static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap )
+{
+ t->setup.pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK);
+
+ switch ( swrap ) {
+ case GL_REPEAT:
+ t->setup.pp_txfilter |= RADEON_CLAMP_S_WRAP;
+ break;
+ case GL_CLAMP:
+ t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST;
+ break;
+ }
+
+ switch ( twrap ) {
+ case GL_REPEAT:
+ t->setup.pp_txfilter |= RADEON_CLAMP_T_WRAP;
+ break;
+ case GL_CLAMP:
+ t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST;
+ break;
+ }
+}
+
+static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf )
+{
+ t->setup.pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK);
+
+ switch ( minf ) {
+ case GL_NEAREST:
+ t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR;
+ break;
+ }
+
+ switch ( magf ) {
+ case GL_NEAREST:
+ t->setup.pp_txfilter |= RADEON_MAG_FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ t->setup.pp_txfilter |= RADEON_MAG_FILTER_LINEAR;
+ break;
+ }
+}
+
+static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] )
+{
+ t->setup.pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
+}
+
+
+/* Allocate and initialize hardware state associated with texture `t'.
+ */
+static radeonTexObjPtr radeonCreateTexObj( radeonContextPtr rmesa,
+ struct gl_texture_object *tObj )
+{
+ radeonTexObjPtr t;
+ struct gl_texture_image *image;
+ GLint log2Width, log2Height, log2Size, log2MinSize;
+ GLint totalSize;
+ GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0;
+ GLint x, y, width, height;
+ GLint i;
+ GLuint txformat, txalpha;
+
+ image = tObj->Image[0];
+ if ( !image )
+ return NULL;
+
+ t = (radeonTexObjPtr) CALLOC( sizeof(*t) );
+ if ( !t )
+ return NULL;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API )
+ fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj );
+
+ switch ( image->Format ) {
+ case GL_RGBA:
+ if ( image->IntFormat != GL_RGBA4 &&
+ ( image->IntFormat == GL_RGBA8 ||
+ rmesa->radeonScreen->cpp == 4 ) ) {
+ t->texelBytes = 4;
+ txformat = RADEON_TXF_32BPP_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ txformat = RADEON_TXF_16BPP_ARGB4444;
+ }
+ txalpha = RADEON_TXF_ALPHA_IN_MAP;
+ break;
+
+ case GL_RGB:
+ if ( image->IntFormat != GL_RGB5 &&
+ ( image->IntFormat == GL_RGB8 ||
+ rmesa->radeonScreen->cpp == 4 ) ) {
+ t->texelBytes = 4;
+ txformat = RADEON_TXF_32BPP_ARGB8888;
+ } else {
+ t->texelBytes = 2;
+ txformat = RADEON_TXF_16BPP_RGB565;
+ }
+ txalpha = 0;
+ break;
+
+ case GL_ALPHA:
+ case GL_LUMINANCE_ALPHA:
+ t->texelBytes = 2;
+ txformat = RADEON_TXF_16BPP_AI88;
+ txalpha = RADEON_TXF_ALPHA_IN_MAP;
+ break;
+
+ case GL_LUMINANCE:
+ t->texelBytes = 2;
+ txformat = RADEON_TXF_16BPP_AI88;
+ txalpha = 0;
+ break;
+
+ case GL_INTENSITY:
+ t->texelBytes = 1;
+ txformat = RADEON_TXF_8BPP_I;
+ txalpha = 0;
+ break;
+
+ case GL_COLOR_INDEX:
+ default:
+ fprintf( stderr, "%s: bad image->Format\n", __FUNCTION__ );
+ FREE( t );
+ return NULL;
+ }
+
+ /* Calculate dimensions in log domain.
+ */
+ for ( i = 1, log2Height = 0 ; i < image->Height ; i *= 2 ) {
+ log2Height++;
+ }
+ for ( i = 1, log2Width = 0 ; i < image->Width ; i *= 2 ) {
+ log2Width++;
+ }
+ if ( image->Width > image->Height ) {
+ log2Size = log2Width;
+ } else {
+ log2Size = log2Height;
+ }
+
+ t->dirty_images = 0;
+
+ /* The Radeon has a 64-byte minimum pitch for all blits. We
+ * calculate the equivalent number of texels to simplify the
+ * calculation of the texture image area.
+ */
+ switch ( t->texelBytes ) {
+ case 1:
+ texelsPerDword = 4;
+ blitPitch = 64;
+ break;
+ case 2:
+ texelsPerDword = 2;
+ blitPitch = 32;
+ break;
+ case 4:
+ texelsPerDword = 1;
+ blitPitch = 16;
+ break;
+ }
+
+ /* Select the larger of the two widths for our global texture image
+ * coordinate space. As the Radeon has very strict offset rules, we
+ * can't upload mipmaps directly and have to reference their location
+ * from the aligned start of the whole image.
+ */
+ blitWidth = MAX2( image->Width, blitPitch );
+
+ /* Calculate mipmap offsets and dimensions.
+ */
+ totalSize = 0;
+ x = 0;
+ y = 0;
+
+ for ( i = 0 ; i <= log2Size ; i++ ) {
+ GLuint size;
+
+ image = tObj->Image[i];
+ if ( !image )
+ break;
+
+ width = image->Width;
+ height = image->Height;
+
+ /* Texture images have a minimum pitch of 32 bytes (half of the
+ * 64-byte minimum pitch for blits). For images that have a
+ * width smaller than this, we must pad each texture image
+ * scanline out to this amount.
+ */
+ if ( width < blitPitch / 2 ) {
+ width = blitPitch / 2;
+ }
+
+ size = width * height * t->texelBytes;
+ totalSize += size;
+
+ t->dirty_images |= (1 << i);
+
+ while ( width < blitWidth && height > 1 ) {
+ width *= 2;
+ height /= 2;
+ }
+
+ t->image[i].x = x;
+ t->image[i].y = y;
+
+ t->image[i].width = width;
+ t->image[i].height = height;
+
+ t->image[i].dwords = size / sizeof(CARD32);
+
+ /* While blits must have a pitch of at least 64 bytes, mipmaps
+ * must be aligned on a 32-byte boundary (just like each texture
+ * image scanline).
+ */
+ if ( width >= blitWidth ) {
+ y += height;
+ } else {
+ x += width;
+ if ( x >= blitWidth ) {
+ x = 0;
+ y++;
+ }
+ }
+
+ if ( 0 )
+ fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d) %d dwords\n",
+ i, blitWidth, image->Width, image->Height,
+ t->image[i].width, t->image[i].height,
+ t->image[i].x, t->image[i].y,
+ t->image[i].dwords );
+ }
+
+ log2MinSize = log2Size - i + 1;
+
+ /* Align the total size of texture memory block.
+ */
+ totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
+
+ t->totalSize = totalSize;
+
+ t->bound = 0;
+ t->heap = 0;
+ t->tObj = tObj;
+
+ t->memBlock = NULL;
+ t->bufAddr = 0;
+
+ /* Hardware state:
+ */
+ t->setup.pp_txfilter = ((log2Size << RADEON_MAX_MIP_LEVEL_SHIFT) |
+ RADEON_BORDER_MODE_OGL);
+
+ t->setup.pp_txformat = (txformat | txalpha |
+ (log2Width << RADEON_TXF_WIDTH_SHIFT) |
+ (log2Height << RADEON_TXF_HEIGHT_SHIFT) |
+ RADEON_TXF_ENDIAN_NO_SWAP |
+ RADEON_TXF_PERSPECTIVE_ENABLE);
+
+ t->setup.pp_txoffset = 0x00000000;
+ t->setup.pp_txcblend = 0x00000000;
+ t->setup.pp_txablend = 0x00000000;
+ t->setup.pp_tfactor = 0x00000000;
+ t->setup.pp_border_color = 0x00000000;
+
+ radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT );
+ radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+ radeonSetTexBorderColor( t, tObj->BorderColor );
+
+ tObj->DriverData = t;
+
+ make_empty_list( t );
+
+ return t;
+}
+
+/* Destroy hardware state associated with texture `t'.
+ */
+void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+#if ENABLE_PERF_BOXES
+ /* Bump the performace counter */
+ rmesa->c_textureSwaps++;
+#endif
+ if ( !t ) return;
+
+ if ( t->memBlock ) {
+ mmFreeMem( t->memBlock );
+ t->memBlock = NULL;
+ }
+
+ if ( t->tObj )
+ t->tObj->DriverData = NULL;
+ if ( t->bound )
+ rmesa->CurrentTexObj[t->bound-1] = NULL;
+
+ remove_from_list( t );
+ FREE( t );
+}
+
+/* Keep track of swapped out texture objects.
+ */
+static void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+#if ENABLE_PERF_BOXES
+ /* Bump the performace counter */
+ rmesa->c_textureSwaps++;
+#endif
+ if ( t->memBlock ) {
+ mmFreeMem( t->memBlock );
+ t->memBlock = NULL;
+ }
+
+ t->dirty_images = ~0;
+ move_to_tail( &rmesa->SwappedOut, t );
+}
+
+/* Print out debugging information about texture LRU.
+ */
+void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap )
+{
+ radeonTexObjPtr t;
+ int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]);
+
+ fprintf( stderr, "\nLocal LRU, heap %d:\n", heap );
+
+ foreach ( t, &rmesa->TexObjList[heap] ) {
+ if (!t->tObj) {
+ fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n",
+ t->memBlock->ofs / sz,
+ t->memBlock->ofs,
+ t->memBlock->size );
+ } else {
+ fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n",
+ t->bound,
+ t->memBlock->ofs,
+ t->memBlock->size );
+ }
+ }
+
+ fprintf( stderr, "\n" );
+}
+
+void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap )
+{
+ radeon_tex_region_t *list = rmesa->sarea->texList[heap];
+ int i, j;
+
+ fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list );
+
+ for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
+ fprintf( stderr, "list[%d] age %d next %d prev %d\n",
+ j, list[j].age, list[j].next, list[j].prev );
+ j = list[j].next;
+ if ( j == RADEON_NR_TEX_REGIONS ) break;
+ }
+
+ if ( j != RADEON_NR_TEX_REGIONS ) {
+ fprintf( stderr, "Loop detected in global LRU\n" );
+ for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) {
+ fprintf( stderr, "list[%d] age %d next %d prev %d\n",
+ i, list[i].age, list[i].next, list[i].prev );
+ }
+ }
+
+ fprintf( stderr, "\n" );
+}
+
+/* Reset the global texture LRU.
+ */
+static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap )
+{
+ radeon_tex_region_t *list = rmesa->sarea->texList[heap];
+ int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
+ int i;
+
+ /*
+ * (Re)initialize the global circular LRU list. The last element in
+ * the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at
+ * the end of the array allows it to be addressed rationally when
+ * looking up objects at a particular location in texture memory.
+ */
+ for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) {
+ list[i].prev = i-1;
+ list[i].next = i+1;
+ list[i].age = 0;
+ }
+
+ i--;
+ list[0].prev = RADEON_NR_TEX_REGIONS;
+ list[i].prev = i-1;
+ list[i].next = RADEON_NR_TEX_REGIONS;
+ list[RADEON_NR_TEX_REGIONS].prev = i;
+ list[RADEON_NR_TEX_REGIONS].next = 0;
+ rmesa->sarea->texAge[heap] = 0;
+}
+
+/* Update the local and glock texture LRUs.
+ */
+static void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+ int heap = t->heap;
+ radeon_tex_region_t *list = rmesa->sarea->texList[heap];
+ int sz = rmesa->radeonScreen->logTexGranularity[heap];
+ int start = t->memBlock->ofs >> sz;
+ int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz;
+ int i;
+
+ rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap];
+
+ if ( !t->memBlock ) {
+ fprintf( stderr, "no memblock\n\n" );
+ return;
+ }
+
+ /* Update our local LRU */
+ move_to_head( &rmesa->TexObjList[heap], t );
+
+ /* Update the global LRU */
+ for ( i = start ; i <= end ; i++ ) {
+ list[i].in_use = 1;
+ list[i].age = rmesa->lastTexAge[heap];
+
+ /* remove_from_list(i) */
+ list[(CARD32)list[i].next].prev = list[i].prev;
+ list[(CARD32)list[i].prev].next = list[i].next;
+
+ /* insert_at_head(list, i) */
+ list[i].prev = RADEON_NR_TEX_REGIONS;
+ list[i].next = list[RADEON_NR_TEX_REGIONS].next;
+ list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i;
+ list[RADEON_NR_TEX_REGIONS].next = i;
+ }
+
+ if ( 0 ) {
+ radeonPrintGlobalLRU( rmesa, t->heap );
+ radeonPrintLocalLRU( rmesa, t->heap );
+ }
+}
+
+/* Update our notion of what textures have been changed since we last
+ * held the lock. This pertains to both our local textures and the
+ * textures belonging to other clients. Keep track of other client's
+ * textures by pushing a placeholder texture onto the LRU list -- these
+ * are denoted by (tObj == NULL).
+ */
+static void radeonTexturesGone( radeonContextPtr rmesa, int heap,
+ int offset, int size, int in_use )
+{
+ radeonTexObjPtr t, tmp;
+
+ foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) {
+ if ( t->memBlock->ofs >= offset + size ||
+ t->memBlock->ofs + t->memBlock->size <= offset )
+ continue;
+
+ /* It overlaps - kick it out. Need to hold onto the currently
+ * bound objects, however.
+ */
+ if ( t->bound ) {
+ radeonSwapOutTexObj( rmesa, t );
+ } else {
+ radeonDestroyTexObj( rmesa, t );
+ }
+ }
+
+ if ( in_use ) {
+ t = (radeonTexObjPtr) CALLOC( sizeof(*t) );
+ if ( !t ) return;
+
+ t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset );
+ if ( !t->memBlock ) {
+ fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n",
+ (int)size, (int)offset );
+ mmDumpMemInfo( rmesa->texHeap[heap] );
+ return;
+ }
+ insert_at_head( &rmesa->TexObjList[heap], t );
+ }
+}
+
+/* Update our client's shared texture state. If another client has
+ * modified a region in which we have textures, then we need to figure
+ * out which of our textures has been removed, and update our global
+ * LRU.
+ */
+void radeonAgeTextures( radeonContextPtr rmesa, int heap )
+{
+ RADEONSAREAPrivPtr sarea = rmesa->sarea;
+
+ if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) {
+ int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap];
+ int nr = 0;
+ int idx;
+
+ for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ;
+ idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ;
+ idx = sarea->texList[heap][idx].prev, nr++ )
+ {
+ /* If switching texturing schemes, then the SAREA might not
+ * have been properly cleared, so we need to reset the
+ * global texture LRU.
+ */
+ if ( idx * sz > rmesa->radeonScreen->texSize[heap] ) {
+ nr = RADEON_NR_TEX_REGIONS;
+ break;
+ }
+
+ if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) {
+ radeonTexturesGone( rmesa, heap, idx * sz, sz,
+ sarea->texList[heap][idx].in_use );
+ }
+ }
+
+ if ( nr == RADEON_NR_TEX_REGIONS ) {
+ radeonTexturesGone( rmesa, heap, 0,
+ rmesa->radeonScreen->texSize[heap], 0 );
+ radeonResetGlobalLRU( rmesa, heap );
+ }
+
+ rmesa->dirty |= (RADEON_UPLOAD_CONTEXT |
+ RADEON_UPLOAD_TEX0IMAGES |
+ RADEON_UPLOAD_TEX1IMAGES);
+ rmesa->lastTexAge[heap] = sarea->texAge[heap];
+ }
+}
+
+
+/* ================================================================
+ * Texture image conversions
+ */
+
+/* Convert a block of Mesa-formatted texture to an 8bpp hardware format.
+ */
+static void radeonConvertTexture8bpp( CARD32 *dst,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch )
+{
+ CARD8 *src;
+ int i, j;
+
+ if ( width < 4 ) {
+ width = 4;
+ }
+
+#define ALIGN_DST \
+ do { \
+ if ( width < 32 ) { \
+ dst += ((32 - width) / 4); \
+ } \
+ } while (0)
+
+ switch ( image->Format ) {
+ case GL_INTENSITY:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for ( j = width >> 2 ; j ; j-- ) {
+ *dst++ = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+ src += 4;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ case GL_COLOR_INDEX:
+ default:
+ fprintf( stderr, "%s: unsupported format 0x%x\n",
+ __FUNCTION__, image->Format );
+ break;
+ }
+}
+#undef ALIGN_DST
+
+/* Convert a block of Mesa-formatted texture to a 16bpp hardware format.
+ */
+static void radeonConvertTexture16bpp( CARD32 *dst,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch )
+{
+ CARD8 *src;
+ int i, j;
+
+ if ( width < 2 ) {
+ width = 2;
+ }
+
+#define ALIGN_DST \
+ do { \
+ if ( width < 16 ) { \
+ dst += ((16 - width) / 2); \
+ } \
+ } while (0)
+
+ switch ( image->Format ) {
+ case GL_RGBA:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
+ for ( j = width >> 1 ; j ; j-- ) {
+ *dst++ = ((RADEONPACKCOLOR4444( src[0], src[1], src[2], src[3] )) |
+ (RADEONPACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16));
+ src += 8;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ case GL_RGB:
+ {
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for ( j = width >> 1 ; j ; j-- ) {
+ *dst++ = ((RADEONPACKCOLOR565( src[0], src[1], src[2] )) |
+ (RADEONPACKCOLOR565( src[3], src[4], src[5] ) << 16));
+ src += 6;
+ }
+ ALIGN_DST;
+ }
+ }
+ break;
+
+ case GL_ALPHA:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for ( j = width >> 1 ; j ; j-- ) {
+ *dst++ = ((RADEONPACKCOLOR88( 0x00, src[0] )) |
+ (RADEONPACKCOLOR88( 0x00, src[1] ) << 16));
+ src += 2;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ case GL_LUMINANCE:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x);
+ for ( j = width >> 1 ; j ; j-- ) {
+ *dst++ = ((RADEONPACKCOLOR88( src[0], 0xff )) |
+ (RADEONPACKCOLOR88( src[1], 0xff ) << 16));
+ src += 2;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2;
+ for ( j = width >> 1 ; j ; j-- ) {
+ *dst++ = ((RADEONPACKCOLOR88( src[0], src[1] )) |
+ (RADEONPACKCOLOR88( src[2], src[3] ) << 16));
+ src += 4;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ default:
+ fprintf( stderr, "%s: unsupported format 0x%x\n",
+ __FUNCTION__, image->Format );
+ break;
+ }
+}
+#undef ALIGN_DST
+
+/* Convert a block of Mesa-formatted texture to a 32bpp hardware format.
+ */
+static void radeonConvertTexture32bpp( CARD32 *dst,
+ struct gl_texture_image *image,
+ int x, int y, int width, int height,
+ int pitch )
+{
+ CARD8 *src;
+ int i, j;
+
+#define ALIGN_DST \
+ do { \
+ if ( width < 8 ) { \
+ dst += (8 - width); \
+ } \
+ } while (0)
+
+ switch ( image->Format ) {
+ case GL_RGBA:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4;
+ for ( j = width ; j ; j-- ) {
+ *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], src[3] );
+ src += 4;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ case GL_RGB:
+ for ( i = 0 ; i < height ; i++ ) {
+ src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3;
+ for ( j = width ; j ; j-- ) {
+ *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], 0xff );
+ src += 3;
+ }
+ ALIGN_DST;
+ }
+ break;
+
+ default:
+ fprintf( stderr, "%s: unsupported format 0x%x\n",
+ __FUNCTION__, image->Format );
+ break;
+ }
+}
+
+/* Upload the texture image associated with texture `t' at level `level'
+ * at the address relative to `start'.
+ */
+static void radeonUploadSubImage( radeonContextPtr rmesa,
+ radeonTexObjPtr t, GLint level,
+ GLint x, GLint y, GLint width, GLint height )
+{
+ struct gl_texture_image *image;
+ GLint texelsPerDword = 0;
+ GLint imageX, imageY, imageWidth, imageHeight;
+ GLint blitX, blitY, blitWidth, blitHeight;
+ GLint imageRows, blitRows;
+ GLint remaining ;
+ GLint format, dwords;
+ CARD32 pitch, offset;
+ drmBufPtr buffer;
+ CARD32 *dst;
+
+ /* Ensure we have a valid texture to upload */
+ if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) )
+ return;
+
+ image = t->tObj->Image[level];
+ if ( !image )
+ return;
+
+ switch ( t->texelBytes ) {
+ case 1:
+ texelsPerDword = 4;
+ break;
+ case 2:
+ texelsPerDword = 2;
+ break;
+ case 4:
+ texelsPerDword = 1;
+ break;
+ }
+
+ format = t->setup.pp_txformat & RADEON_TXF_FORMAT_MASK;
+
+ imageX = 0;
+ imageY = 0;
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+
+ blitX = t->image[level].x;
+ blitY = t->image[level].y;
+ blitWidth = t->image[level].width;
+ blitHeight = t->image[level].height;
+
+ dwords = t->image[level].dwords;
+ offset = t->bufAddr;
+ pitch = (t->image[0].width * t->texelBytes) / 64;
+
+#if ENABLE_PERF_BOXES
+ /* Bump the performace counter */
+ rmesa->c_textureBytes += (dwords << 2);
+#endif
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ fprintf( stderr, " upload image: %d,%d at %d,%d\n",
+ imageWidth, imageHeight, imageX, imageY );
+ fprintf( stderr, " upload blit: %d,%d at %d,%d\n",
+ blitWidth, blitHeight, blitX, blitY );
+ fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d "
+ "level: %d format: %x\n",
+ (GLuint)offset, (GLuint)pitch, dwords, level, format );
+ }
+
+ /* Subdivide the texture if required */
+ if ( dwords <= RADEON_BUFFER_MAX_DWORDS / 2 ) {
+ imageRows = imageHeight;
+ blitRows = blitHeight;
+ } else {
+ imageRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword)/(2 * imageWidth);
+ blitRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * blitWidth);
+ }
+
+ for ( remaining = imageHeight ;
+ remaining > 0 ;
+ remaining -= imageRows, imageY += imageRows, blitY += blitRows )
+ {
+ if ( remaining >= imageRows ) {
+ imageHeight = imageRows;
+ blitHeight = blitRows;
+ } else {
+ imageHeight = remaining;
+ blitHeight = blitRows;
+ }
+ dwords = blitWidth * blitHeight / texelsPerDword;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ fprintf( stderr, " blitting: %d,%d at %d,%d\n",
+ imageWidth, imageHeight, imageX, imageY );
+ fprintf( stderr, " %d,%d at %d,%d - %d dwords\n",
+ blitWidth, blitHeight, blitX, blitY, dwords );
+ }
+
+ /* Grab the indirect buffer for the texture blit */
+ buffer = radeonGetBufferLocked( rmesa );
+
+ dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET);
+
+ /* Actually do the texture conversion */
+ switch ( t->texelBytes ) {
+ case 1:
+ radeonConvertTexture8bpp( dst, image,
+ imageX, imageY, imageWidth, imageHeight,
+ imageWidth );
+ break;
+ case 2:
+ radeonConvertTexture16bpp( dst, image,
+ imageX, imageY, imageWidth, imageHeight,
+ imageWidth );
+ break;
+ case 4:
+ radeonConvertTexture32bpp( dst, image,
+ imageX, imageY, imageWidth, imageHeight,
+ imageWidth );
+ break;
+ }
+
+ radeonFireBlitLocked( rmesa, buffer,
+ offset, pitch, format,
+ blitX, blitY, blitWidth, blitHeight );
+ }
+
+ rmesa->new_state |= RADEON_NEW_CONTEXT;
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS;
+}
+
+/* Upload the texture images associated with texture `t'. This might
+ * require removing our own and/or other client's texture objects to
+ * make room for these images.
+ */
+/* NOTE: This function is only called while holding the hardware lock */
+int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t )
+{
+ int i;
+ int heap;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p, %p )\n",
+ __FUNCTION__, rmesa->glCtx, t );
+ }
+
+ if ( !t )
+ return 0;
+
+ /* Choose the heap appropriately */
+ heap = t->heap = RADEON_CARD_HEAP;
+#if 0
+ if ( !rmesa->radeonScreen->IsPCI &&
+ t->totalSize > rmesa->radeonScreen->texSize[heap] ) {
+ heap = t->heap = RADEON_AGP_HEAP;
+ }
+#endif
+
+ /* Do we need to eject LRU texture objects? */
+ if ( !t->memBlock ) {
+ /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */
+ t->memBlock = mmAllocMem( rmesa->texHeap[heap],
+ t->totalSize, 12, 0 );
+
+#if 0
+ /* Try AGP before kicking anything out of local mem */
+ if ( !t->memBlock && heap == RADEON_CARD_HEAP ) {
+ t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP],
+ t->totalSize, 12, 0 );
+
+ if ( t->memBlock )
+ heap = t->heap = RADEON_AGP_HEAP;
+ }
+#endif
+
+ /* Kick out textures until the requested texture fits */
+ while ( !t->memBlock ) {
+ if ( rmesa->TexObjList[heap].prev->bound ) {
+ fprintf( stderr,
+ "radeonUploadTexImages: ran into bound texture\n" );
+ return -1;
+ }
+ if ( rmesa->TexObjList[heap].prev ==
+ &rmesa->TexObjList[heap] ) {
+ if ( rmesa->radeonScreen->IsPCI ) {
+ fprintf( stderr, "radeonUploadTexImages: upload texture "
+ "failure on local texture heaps, sz=%d\n",
+ t->totalSize );
+ return -1;
+#if 0
+ } else if ( heap == RADEON_CARD_HEAP ) {
+ heap = t->heap = RADEON_AGP_HEAP;
+ continue;
+#endif
+ } else {
+ fprintf( stderr, "radeonUploadTexImages: upload texture "
+ "failure on both local and AGP texture heaps, "
+ "sz=%d\n",
+ t->totalSize );
+ return -1;
+ }
+ }
+
+ radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev );
+
+ t->memBlock = mmAllocMem( rmesa->texHeap[heap],
+ t->totalSize, 12, 0 );
+ }
+
+ /* Set the base offset of the texture image */
+ t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs;
+
+ t->setup.pp_txoffset = t->bufAddr;
+#if 0
+ /* Fix AGP texture offsets */
+ if ( heap == RADEON_AGP_HEAP ) {
+ t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET +
+ rmesa->radeonScreen->agpTexOffset;
+ }
+#endif
+
+ /* Force loading the new state into the hardware */
+ switch ( t->bound ) {
+ case 1:
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0;
+ break;
+
+ case 2:
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1;
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ /* Let the world know we've used this memory recently */
+ radeonUpdateTexLRU( rmesa, t );
+
+ /* Upload any images that are new */
+ if ( t->dirty_images ) {
+ int num_levels = ((t->setup.pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >>
+ RADEON_MAX_MIP_LEVEL_SHIFT);
+
+ for ( i = 0 ; i <= num_levels ; i++ ) {
+ if ( t->dirty_images & (1 << i) ) {
+ radeonUploadSubImage( rmesa, t, i, 0, 0,
+ t->image[i].width, t->image[i].height );
+ }
+ }
+
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+ }
+
+ t->dirty_images = 0;
+ return 0;
+}
+
+
+/* ================================================================
+ * Texture combine functions
+ */
+
+#define RADEON_DISABLE 0
+#define RADEON_REPLACE 1
+#define RADEON_MODULATE 2
+#define RADEON_DECAL 3
+#define RADEON_BLEND 4
+#define RADEON_ADD 5
+#define RADEON_MAX_COMBFUNC 6
+
+static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] =
+{
+ /* Unit 0:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_CURRENT_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00802800
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T0_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800142
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T0_COLOR |
+ RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x008c2d42
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T0_COLOR |
+ RADEON_COLOR_ARG_C_T0_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x008c2902
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_TFACTOR_COLOR |
+ RADEON_COLOR_ARG_C_T0_COLOR |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00812802
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T0_COLOR |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 1:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_CURRENT_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00803000
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T1_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800182
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T1_COLOR |
+ RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x008c3582
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T1_COLOR |
+ RADEON_COLOR_ARG_C_T1_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x008c3102
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_TFACTOR_COLOR |
+ RADEON_COLOR_ARG_C_T1_COLOR |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00813002
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T1_COLOR |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 2:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_CURRENT_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00803800
+ */
+ (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T2_COLOR |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x008001c2
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T2_COLOR |
+ RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x008c3dc2
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_T2_COLOR |
+ RADEON_COLOR_ARG_C_T2_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x008c3902
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_TFACTOR_COLOR |
+ RADEON_COLOR_ARG_C_T2_COLOR |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00813802
+ */
+ (RADEON_COLOR_ARG_A_CURRENT_COLOR |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COLOR_ARG_C_T2_COLOR |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ }
+};
+
+static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] =
+{
+ /* Unit 0:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00800500
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T0_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800051
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_T0_ALPHA |
+ RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x00800100
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x00800051
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
+ RADEON_ALPHA_ARG_C_T0_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00800051
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T0_ALPHA |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 1:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00800600
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T1_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800061
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_T1_ALPHA |
+ RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x00800100
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x00800061
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
+ RADEON_ALPHA_ARG_C_T1_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00800061
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T1_ALPHA |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ },
+
+ /* Unit 2:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_REPLACE = 0x00800700
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T2_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_MODULATE = 0x00800071
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_T2_ALPHA |
+ RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_DECAL = 0x00800100
+ */
+ (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_CURRENT_ALPHA |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_BLEND = 0x00800071
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_TFACTOR_ALPHA |
+ RADEON_ALPHA_ARG_C_T2_ALPHA |
+ RADEON_BLEND_CTL_BLEND |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+
+ /* GL_ADD = 0x00800021
+ */
+ (RADEON_ALPHA_ARG_A_CURRENT_ALPHA |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_ALPHA_ARG_C_T2_ALPHA |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_SCALE_1X |
+ RADEON_CLAMP_TX),
+ }
+};
+
+
+/* GL_EXT_texture_env_combine support
+ */
+
+/* The color tables have combine functions for GL_SRC_COLOR,
+ * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
+ */
+static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
+{
+ {
+ RADEON_COLOR_ARG_A_T0_COLOR,
+ RADEON_COLOR_ARG_A_T1_COLOR,
+ RADEON_COLOR_ARG_A_T2_COLOR
+ },
+ {
+ RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
+ },
+ {
+ RADEON_COLOR_ARG_A_T0_ALPHA,
+ RADEON_COLOR_ARG_A_T1_ALPHA,
+ RADEON_COLOR_ARG_A_T2_ALPHA
+ },
+ {
+ RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
+ },
+};
+
+static GLuint radeon_tfactor_color[] =
+{
+ RADEON_COLOR_ARG_A_TFACTOR_COLOR,
+ RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
+ RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_primary_color[] =
+{
+ RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
+ RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
+ RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_previous_color[] =
+{
+ RADEON_COLOR_ARG_A_CURRENT_COLOR,
+ RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_CURRENT_ALPHA,
+ RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
+};
+
+/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
+ */
+static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
+{
+ {
+ RADEON_ALPHA_ARG_A_T0_ALPHA,
+ RADEON_ALPHA_ARG_A_T1_ALPHA,
+ RADEON_ALPHA_ARG_A_T2_ALPHA
+ },
+ {
+ RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
+ RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
+ },
+};
+
+static GLuint radeon_tfactor_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
+ RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_primary_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
+ RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
+};
+
+static GLuint radeon_previous_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
+ RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
+};
+
+
+/* Extract the arg from slot A, shift it into the correct argument slot
+ * and set the corresponding complement bit.
+ */
+#define RADEON_COLOR_ARG( n, arg ) \
+do { \
+ color_combine |= \
+ ((color_arg[n] & RADEON_COLOR_ARG_MASK) \
+ << RADEON_COLOR_ARG_##arg##_SHIFT); \
+ color_combine |= \
+ ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \
+ << RADEON_COMP_ARG_##arg##_SHIFT); \
+} while (0)
+
+#define RADEON_ALPHA_ARG( n, arg ) \
+do { \
+ alpha_combine |= \
+ ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \
+ << RADEON_ALPHA_ARG_##arg##_SHIFT); \
+ alpha_combine |= \
+ ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \
+ << RADEON_COMP_ARG_##arg##_SHIFT); \
+} while (0)
+
+
+/* ================================================================
+ * Texture unit state management
+ */
+
+static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ int source = rmesa->tmu_source[unit];
+ struct gl_texture_object *tObj;
+ struct gl_texture_unit *texUnit;
+ GLuint enabled;
+ GLuint color_combine, alpha_combine;
+ GLuint color_arg[3], alpha_arg[3];
+ GLuint i, numColorArgs = 0, numAlphaArgs = 0;
+ GLuint op;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p, %d )\n",
+ __FUNCTION__, ctx, unit );
+ }
+
+ enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY;
+ if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D )
+ return;
+
+ /* Only update the hardware texture state if the texture is current,
+ * complete and enabled.
+ */
+ texUnit = &ctx->Texture.Unit[source];
+ tObj = texUnit->Current;
+ if ( !tObj || !tObj->Complete )
+ return;
+
+ if ( ( tObj != texUnit->CurrentD[2] ) &&
+ ( tObj != texUnit->CurrentD[1] ) )
+ return;
+
+ /* Set the texture environment state. Isn't this nice and clean?
+ * The Radeon will automagically set the texture alpha to 0xff when
+ * the texture format does not include an alpha component. This
+ * reduces the amount of special-casing we have to do, alpha-only
+ * textures being a notable exception.
+ */
+ switch ( texUnit->EnvMode ) {
+ case GL_REPLACE:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_REPLACE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_MODULATE:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_MODULATE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_DECAL:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ color_combine = radeon_color_combine[unit][RADEON_DECAL];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ break;
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_BLEND:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_BLEND];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_BLEND];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_ADD:
+ switch ( tObj->Image[0]->Format ) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_ADD];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_ALPHA:
+ color_combine = radeon_color_combine[unit][RADEON_DISABLE];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE];
+ break;
+ case GL_INTENSITY:
+ color_combine = radeon_color_combine[unit][RADEON_ADD];
+ alpha_combine = radeon_alpha_combine[unit][RADEON_ADD];
+ break;
+ case GL_COLOR_INDEX:
+ default:
+ return;
+ }
+ break;
+
+ case GL_COMBINE_EXT:
+ /* Step 0:
+ * Calculate how many arguments we need to process.
+ */
+ switch ( texUnit->CombineModeRGB ) {
+ case GL_REPLACE:
+ numColorArgs = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED_EXT:
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ numColorArgs = 2;
+ break;
+ case GL_INTERPOLATE_EXT:
+ numColorArgs = 3;
+ break;
+ default:
+ return;
+ }
+
+ switch ( texUnit->CombineModeA ) {
+ case GL_REPLACE:
+ numAlphaArgs = 1;
+ break;
+ case GL_MODULATE:
+ case GL_ADD:
+ case GL_ADD_SIGNED_EXT:
+ numAlphaArgs = 2;
+ break;
+ case GL_INTERPOLATE_EXT:
+ numAlphaArgs = 3;
+ break;
+ default:
+ return;
+ }
+
+ /* Step 1:
+ * Extract the color and alpha combine function arguments.
+ */
+ for ( i = 0 ; i < numColorArgs ; i++ ) {
+ op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
+ switch ( texUnit->CombineSourceRGB[i] ) {
+ case GL_TEXTURE:
+ color_arg[i] = radeon_texture_color[op][unit];
+ break;
+ case GL_CONSTANT_EXT:
+ color_arg[i] = radeon_tfactor_color[op];
+ break;
+ case GL_PRIMARY_COLOR_EXT:
+ color_arg[i] = radeon_primary_color[op];
+ break;
+ case GL_PREVIOUS_EXT:
+ color_arg[i] = radeon_previous_color[op];
+ break;
+ default:
+ return;
+ }
+ }
+
+ for ( i = 0 ; i < numAlphaArgs ; i++ ) {
+ op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
+ switch ( texUnit->CombineSourceA[i] ) {
+ case GL_TEXTURE:
+ alpha_arg[i] = radeon_texture_alpha[op][unit];
+ break;
+ case GL_CONSTANT_EXT:
+ alpha_arg[i] = radeon_tfactor_alpha[op];
+ break;
+ case GL_PRIMARY_COLOR_EXT:
+ alpha_arg[i] = radeon_primary_alpha[op];
+ break;
+ case GL_PREVIOUS_EXT:
+ alpha_arg[i] = radeon_previous_alpha[op];
+ break;
+ default:
+ return;
+ }
+ }
+
+ /* Step 2:
+ * Build up the color and alpha combine functions.
+ */
+ switch ( texUnit->CombineModeRGB ) {
+ case GL_REPLACE:
+ color_combine = (RADEON_COLOR_ARG_A_ZERO |
+ RADEON_COLOR_ARG_B_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, C );
+ break;
+ case GL_MODULATE:
+ color_combine = (RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, B );
+ break;
+ case GL_ADD:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_ADD_SIGNED_EXT:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE_EXT:
+ color_combine = (RADEON_BLEND_CTL_BLEND |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, B );
+ RADEON_COLOR_ARG( 1, A );
+ RADEON_COLOR_ARG( 2, C );
+ break;
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ color_combine = (RADEON_COLOR_ARG_C_ZERO |
+ RADEON_BLEND_CTL_DOT3 |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, B );
+ break;
+ default:
+ return;
+ }
+
+ switch ( texUnit->CombineModeA ) {
+ case GL_REPLACE:
+ alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
+ RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, C );
+ break;
+ case GL_MODULATE:
+ alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, B );
+ break;
+ case GL_ADD:
+ alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_ADD_SIGNED_EXT:
+ alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE_EXT:
+ alpha_combine = (RADEON_BLEND_CTL_BLEND |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, B );
+ RADEON_ALPHA_ARG( 1, A );
+ RADEON_ALPHA_ARG( 2, C );
+ break;
+ default:
+ return;
+ }
+
+ if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) {
+ alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
+ }
+
+ /* Step 3:
+ * Apply the scale factor. The EXT extension has a somewhat
+ * unnecessary restriction that the scale must be 4x. The ARB
+ * extension will likely drop this and we can just apply the
+ * scale factors regardless.
+ */
+ if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT &&
+ texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) {
+ color_combine |= (texUnit->CombineScaleShiftRGB << 21);
+ alpha_combine |= (texUnit->CombineScaleShiftA << 21);
+ } else {
+ color_combine |= RADEON_SCALE_4X;
+ alpha_combine |= RADEON_SCALE_4X;
+ }
+
+ /* All done!
+ */
+ break;
+
+ default:
+ return;
+ }
+
+ rmesa->color_combine[source] = color_combine;
+ rmesa->alpha_combine[source] = alpha_combine;
+}
+
+static void radeonUpdateTextureObject( GLcontext *ctx, int unit )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ int source = rmesa->tmu_source[unit];
+ struct gl_texture_object *tObj;
+ radeonTexObjPtr t;
+ GLuint enabled;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p, %d )\n",
+ __FUNCTION__, ctx, unit );
+ }
+
+ enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY;
+ if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) {
+ if ( enabled )
+ rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
+ return;
+ }
+
+ /* Only update the hardware texture state if the texture is current,
+ * complete and enabled.
+ */
+ tObj = ctx->Texture.Unit[source].Current;
+ if ( !tObj || !tObj->Complete )
+ return;
+
+ if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) &&
+ ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) )
+ return;
+
+ if ( !tObj->DriverData ) {
+ /* If this is the first time the texture has been used, then create
+ * a new texture object for it.
+ */
+ radeonCreateTexObj( rmesa, tObj );
+
+ if ( !tObj->DriverData ) {
+ /* Can't create a texture object... */
+ fprintf( stderr, "%s: texture object creation failed!\n",
+ __FUNCTION__ );
+ rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
+ return;
+ }
+ }
+
+ /* We definately have a valid texture now */
+ t = tObj->DriverData;
+
+ /* Force the texture unit state to be loaded into the hardware */
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit);
+
+ /* Force any texture images to be loaded into the hardware */
+ if ( t->dirty_images )
+ rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit);
+
+ /* Bind to the given texture unit */
+ rmesa->CurrentTexObj[unit] = t;
+ t->bound = unit + 1;
+
+ if ( t->memBlock )
+ radeonUpdateTexLRU( rmesa, t );
+
+ switch ( unit ) {
+ case 0:
+ rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE |
+ RADEON_TEX_BLEND_0_ENABLE);
+ break;
+ case 1:
+ rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE |
+ RADEON_TEX_BLEND_1_ENABLE);
+ break;
+ }
+}
+
+void radeonUpdateTextureState( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p ) en=0x%x\n",
+ __FUNCTION__, ctx, ctx->Texture.ReallyEnabled );
+ }
+
+ /* Clear any texturing fallbacks */
+ rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE;
+
+ /* Unbind any currently bound textures */
+ if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0;
+ if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0;
+ rmesa->CurrentTexObj[0] = NULL;
+ rmesa->CurrentTexObj[1] = NULL;
+
+ if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) )
+ rmesa->Fallback |= RADEON_FALLBACK_TEXTURE;
+
+ /* Disable all texturing until it is known to be good */
+ rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK |
+ RADEON_TEX_BLEND_ENABLE_MASK);
+
+ radeonUpdateTextureObject( ctx, 0 );
+ radeonUpdateTextureEnv( ctx, 0 );
+
+ if ( rmesa->multitex ) {
+ radeonUpdateTextureObject( ctx, 1 );
+ radeonUpdateTextureEnv( ctx, 1 );
+ }
+
+ rmesa->dirty |= RADEON_UPLOAD_CONTEXT;
+}
+
+
+/* ================================================================
+ * DD interface texturing functions
+ *
+ * FIXME: Many of these are deprecated -- we should move to the new
+ * single-copy texture interface.
+ */
+#define SCALED_FLOAT_TO_BYTE( x, scale ) \
+ ((((GLint)((256.0F / scale) * (x))) - 1) / 2)
+
+static void radeonDDTexEnv( GLcontext *ctx, GLenum target,
+ GLenum pname, const GLfloat *param )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit;
+ GLuint source;
+ GLubyte c[4];
+ GLuint col;
+ GLfloat bias;
+ GLubyte b;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %s )\n",
+ __FUNCTION__, gl_lookup_enum_by_nr( pname ) );
+ }
+
+ switch ( pname ) {
+ case GL_TEXTURE_ENV_MODE:
+ FLUSH_BATCH( rmesa );
+ rmesa->new_state |= RADEON_NEW_TEXTURE | RADEON_NEW_ALPHA;
+ break;
+
+ case GL_TEXTURE_ENV_COLOR:
+ source = rmesa->tmu_source[ctx->Texture.CurrentUnit];
+ texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ FLOAT_RGBA_TO_UBYTE_RGBA( c, texUnit->EnvColor );
+ col = radeonPackColor( 4, c[0], c[1], c[2], c[3] );
+ if ( rmesa->env_color[source] != col ) {
+ FLUSH_BATCH( rmesa );
+ rmesa->env_color[source] = col;
+
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ }
+ break;
+
+ case GL_TEXTURE_LOD_BIAS_EXT:
+ /* The Radeon's LOD bias is a signed 2's complement value with a
+ * range of -1.0 <= bias < 4.0. We break this into two linear
+ * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping
+ * [0.0,4.0] to [0,127].
+ */
+ source = rmesa->tmu_source[ctx->Texture.CurrentUnit];
+ bias = CLAMP( *param, -1.0, 4.0 );
+ if ( bias == 0 ) {
+ b = 0;
+ } else if ( bias > 0 ) {
+ b = (GLubyte) SCALED_FLOAT_TO_BYTE( bias, 4.0 );
+ } else {
+ b = (GLubyte) SCALED_FLOAT_TO_BYTE( bias, 1.0 );
+ }
+ if ( rmesa->lod_bias[source] != (GLuint)b ) {
+ FLUSH_BATCH( rmesa );
+ rmesa->lod_bias[source] = (GLuint)b;
+
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ }
+ break;
+
+ default:
+ return;
+ }
+}
+
+static void radeonDDTexImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API )
+ fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level );
+
+ if ( ( target != GL_TEXTURE_2D ) &&
+ ( target != GL_TEXTURE_1D ) )
+ return;
+
+ if ( level >= RADEON_MAX_TEXTURE_LEVELS )
+ return;
+
+ t = (radeonTexObjPtr)tObj->DriverData;
+ if ( t ) {
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+
+ /* Destroy the old texture, and upload a new one. The actual
+ * uploading of the texture image occurs in the UploadSubImage
+ * function.
+ */
+ radeonDestroyTexObj( rmesa, t );
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ }
+}
+
+static void radeonDDTexSubImage( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLint internalFormat,
+ const struct gl_texture_image *image )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p, level %d ) size: %d,%d of %d,%d\n",
+ __FUNCTION__, tObj, level, width, height,
+ image->Width, image->Height );
+ }
+
+ if ( ( target != GL_TEXTURE_2D ) &&
+ ( target != GL_TEXTURE_1D ) )
+ return;
+
+ if ( level >= RADEON_MAX_TEXTURE_LEVELS )
+ return;
+
+ t = (radeonTexObjPtr)tObj->DriverData;
+ if ( t ) {
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+
+#if 0
+ /* FIXME: Only upload textures if we already have space in the heap.
+ */
+ LOCK_HARDWARE( rmesa );
+ radeonUploadSubImage( rmesa, t, level,
+ xoffset, yoffset, width, height );
+ UNLOCK_HARDWARE( rmesa );
+#else
+ radeonDestroyTexObj( rmesa, t );
+#endif
+ /* Update the context state */
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ }
+}
+
+static void radeonDDTexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %s )\n",
+ __FUNCTION__, gl_lookup_enum_by_nr( pname ) );
+ }
+
+ /* If we don't have a hardware texture, it will be automatically
+ * created with current state before it is used, so we don't have
+ * to do anything now.
+ */
+ if ( !t || !t->bound )
+ return;
+
+ if ( ( target != GL_TEXTURE_2D ) &&
+ ( target != GL_TEXTURE_1D ) )
+ return;
+
+ switch ( pname ) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+ radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+ radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT );
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if ( t->bound ) FLUSH_BATCH( rmesa );
+ radeonSetTexBorderColor( t, tObj->BorderColor );
+ break;
+
+ default:
+ return;
+ }
+
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+}
+
+static void radeonDDBindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLint unit = ctx->Texture.CurrentUnit;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
+ fprintf( stderr, "%s( %p ) unit=%d\n",
+ __FUNCTION__, tObj, ctx->Texture.CurrentUnit );
+ }
+
+ FLUSH_BATCH( rmesa );
+
+ if ( rmesa->CurrentTexObj[unit] ) {
+ rmesa->CurrentTexObj[unit]->bound = 0;
+ rmesa->CurrentTexObj[unit] = NULL;
+ }
+
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+}
+
+static void radeonDDDeleteTexture( GLcontext *ctx,
+ struct gl_texture_object *tObj )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
+
+ if ( t ) {
+ if ( t->bound ) {
+ FLUSH_BATCH( rmesa );
+
+ rmesa->CurrentTexObj[t->bound-1] = 0;
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ }
+
+ radeonDestroyTexObj( rmesa, t );
+ tObj->DriverData = NULL;
+ }
+}
+
+static GLboolean radeonDDIsTextureResident( GLcontext *ctx,
+ struct gl_texture_object *tObj )
+{
+ radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData;
+
+ return ( t && t->memBlock );
+}
+
+
+
+void radeonDDInitTextureFuncs( GLcontext *ctx )
+{
+ ctx->Driver.TexEnv = radeonDDTexEnv;
+ ctx->Driver.TexImage = radeonDDTexImage;
+ ctx->Driver.TexSubImage = radeonDDTexSubImage;
+ ctx->Driver.TexParameter = radeonDDTexParameter;
+ ctx->Driver.BindTexture = radeonDDBindTexture;
+ ctx->Driver.DeleteTexture = radeonDDDeleteTexture;
+ ctx->Driver.UpdateTexturePalette = NULL;
+ ctx->Driver.ActiveTexture = NULL;
+ ctx->Driver.IsTextureResident = radeonDDIsTextureResident;
+ ctx->Driver.PrioritizeTexture = NULL;
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h
new file mode 100644
index 000000000..2534335aa
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h
@@ -0,0 +1,96 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_TEX_H__
+#define __RADEON_TEX_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+extern void radeonUpdateTextureState( GLcontext *ctx );
+
+extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t );
+
+extern void radeonAgeTextures( radeonContextPtr rmesa, int heap );
+extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t );
+
+extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap );
+extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap );
+
+extern void radeonDDInitTextureFuncs( GLcontext *ctx );
+
+
+/* ================================================================
+ * Color conversion macros:
+ */
+
+#define RADEONPACKCOLOR332( r, g, b ) \
+ (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
+
+#define RADEONPACKCOLOR1555( r, g, b, a ) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+
+#define RADEONPACKCOLOR565( r, g, b ) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+
+#define RADEONPACKCOLOR88( i, a ) \
+ (((a) << 8) | (i))
+
+#define RADEONPACKCOLOR888( r, g, b ) \
+ (((r) << 16) | ((g) << 8) | (b))
+
+#define RADEONPACKCOLOR8888( r, g, b, a ) \
+ (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+#define RADEONPACKCOLOR4444( r, g, b, a ) \
+ ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
+
+static __inline__ CARD32 radeonPackColor( GLuint cpp,
+ GLubyte r, GLubyte g,
+ GLubyte b, GLubyte a )
+{
+ switch ( cpp ) {
+ case 2:
+ return RADEONPACKCOLOR565( r, g, b );
+ case 4:
+ return RADEONPACKCOLOR8888( r, g, b, a );
+ default:
+ return 0;
+ }
+}
+
+#endif
+#endif /* __RADEON_TEX_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h
new file mode 100644
index 000000000..45368e076
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h
@@ -0,0 +1,87 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_TEXOBJ_H__
+#define __RADEON_TEXOBJ_H__
+
+#include "radeon_sarea.h"
+#include "mm.h"
+
+/* Handle the Radeon's tightly packed mipmaps and strict offset,
+ * pitch rules for blits by assigning each mipmap a set of
+ * coordinates that can be used for a hostdata blit.
+ */
+typedef struct {
+ GLuint x; /* Blit coordinates */
+ GLuint y;
+ GLuint width; /* Blit dimensions */
+ GLuint height;
+ GLuint dwords; /* Size of image level */
+} radeonTexImage;
+
+typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr;
+
+/* Texture object in locally shared texture space.
+ */
+struct radeon_tex_obj {
+ radeonTexObjPtr next, prev;
+
+ struct gl_texture_object *tObj; /* Mesa texture object */
+
+ PMemBlock memBlock; /* Memory block containing texture */
+ CARD32 bufAddr; /* Offset to start of locally
+ shared texture block */
+
+ CARD32 dirty_images; /* Flags for whether or not
+ images need to be uploaded to
+ local or AGP texture space */
+
+ GLint bound; /* Texture unit currently bound to */
+ GLint heap; /* Texture heap currently stored in */
+
+ radeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; /* Image data for all
+ mipmap levels */
+
+ GLint totalSize; /* Total size of the texture
+ including all mipmap levels */
+ GLint texelBytes; /* Number of bytes per texel */
+
+ GLboolean hasAlpha;
+
+ radeon_texture_regs_t setup; /* Setup regs for texture */
+};
+
+#endif /* __RADEON_TEXOBJ_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c
new file mode 100644
index 000000000..bbc766129
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c
@@ -0,0 +1,209 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_vb.h"
+#include "radeon_tris.h"
+#include "radeon_state.h"
+
+#include "pipeline.h"
+#include "vbindirect.h"
+
+static struct {
+ points_func points;
+ line_func line;
+ triangle_func triangle;
+ quad_func quad;
+} rast_tab[RADEON_MAX_TRIFUNC];
+
+#define RADEON_COLOR( to, from ) \
+do { \
+ *(GLuint *)(to) = *(GLuint *)(from); \
+} while (0)
+
+
+static void radeon_null_quad( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint v3, GLuint pv )
+{
+}
+static void radeon_null_triangle( GLcontext *ctx, GLuint v0,
+ GLuint v1, GLuint v2, GLuint pv )
+{
+}
+static void radeon_null_line( GLcontext *ctx,
+ GLuint v1, GLuint v2, GLuint pv )
+{
+}
+static void radeon_null_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+}
+
+static void radeonPrintRenderState( const char *msg, GLuint state )
+{
+ fprintf( stderr, "%s: (0x%x) %s%s%s%s%s\n",
+ msg, state,
+ (state & RADEON_FLAT_BIT) ? "flat, " : "",
+ (state & RADEON_OFFSET_BIT) ? "offset, " : "",
+ (state & RADEON_TWOSIDE_BIT) ? "twoside, " : "",
+ (state & RADEON_NODRAW_BIT) ? "no-draw, " : "",
+ (state & RADEON_FALLBACK_BIT) ? "fallback" : "" );
+}
+
+#define IND (0)
+#define TAG(x) x
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_OFFSET_BIT)
+#define TAG(x) x##_offset
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_OFFSET_BIT | RADEON_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT)
+#define TAG(x) x##_twoside
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT | RADEON_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)
+#define TAG(x) x##_twoside_offset
+#include "radeon_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT | RADEON_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "radeon_tritmp.h"
+
+
+void radeonDDTriangleFuncsInit( void )
+{
+ GLint i;
+
+ init();
+ init_flat();
+ init_offset();
+ init_offset_flat();
+ init_twoside();
+ init_twoside_flat();
+ init_twoside_offset();
+ init_twoside_offset_flat();
+
+ for ( i = 0 ; i < RADEON_MAX_TRIFUNC ; i++ ) {
+ if ( i & RADEON_NODRAW_BIT ) {
+ rast_tab[i].points = radeon_null_points;
+ rast_tab[i].line = radeon_null_line;
+ rast_tab[i].triangle = radeon_null_triangle;
+ rast_tab[i].quad = radeon_null_quad;
+ }
+ }
+}
+
+
+/* FIXME: Only enable software fallback for stencil in 16 bpp mode after
+ * we have hardware stencil support.
+ */
+#define ALL_FALLBACK (DD_SELECT | DD_FEEDBACK | DD_STENCIL)
+#define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH | DD_POINT_ATTEN)
+#define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE)
+#define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED)
+#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
+#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER)
+
+/* Setup the Point, Line, Triangle and Quad functions based on the
+ * current rendering state. Wherever possible, use the hardware to
+ * render the primitive. Otherwise, fallback to software rendering.
+ */
+void radeonDDChooseRenderState( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLuint flags = ctx->TriangleCaps;
+ GLuint index = 0;
+
+ if ( rmesa->Fallback ) {
+ rmesa->RenderIndex = RADEON_FALLBACK_BIT;
+ return;
+ }
+
+ if ( flags & ANY_RASTER_FLAGS ) {
+ if ( flags & DD_FLATSHADE ) index |= RADEON_FLAT_BIT;
+ if ( flags & DD_TRI_LIGHT_TWOSIDE ) index |= RADEON_TWOSIDE_BIT;
+ if ( flags & DD_TRI_OFFSET ) index |= RADEON_OFFSET_BIT;
+ if ( flags & DD_Z_NEVER ) index |= RADEON_NODRAW_BIT;
+ }
+
+ rmesa->PointsFunc = rast_tab[index].points;
+ rmesa->LineFunc = rast_tab[index].line;
+ rmesa->TriangleFunc = rast_tab[index].triangle;
+ rmesa->QuadFunc = rast_tab[index].quad;
+
+ rmesa->RenderIndex = index;
+ rmesa->IndirectTriangles = 0;
+
+ if ( flags & ANY_FALLBACK ) {
+ if ( flags & POINT_FALLBACK ) {
+ rmesa->RenderIndex |= RADEON_FALLBACK_BIT;
+ rmesa->PointsFunc = 0;
+ rmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE;
+ }
+
+ if ( flags & LINE_FALLBACK ) {
+ rmesa->RenderIndex |= RADEON_FALLBACK_BIT;
+ rmesa->LineFunc = 0;
+ rmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE;
+ }
+
+ if ( flags & TRI_FALLBACK ) {
+ rmesa->RenderIndex |= RADEON_FALLBACK_BIT;
+ rmesa->TriangleFunc = 0;
+ rmesa->QuadFunc = 0;
+ rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE |
+ DD_QUAD_SW_RASTERIZE);
+ }
+ }
+
+ if ( 0 ) {
+ gl_print_tri_caps( "tricaps", ctx->TriangleCaps );
+ radeonPrintRenderState( "radeon render state", rmesa->RenderIndex );
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h
new file mode 100644
index 000000000..57fadaeca
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h
@@ -0,0 +1,316 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_TRIS_H__
+#define __RADEON_TRIS_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include "radeon_vb.h"
+
+extern void radeonDDChooseRenderState( GLcontext *ctx );
+extern void radeonDDTriangleFuncsInit( void );
+
+#define RADEON_ANTIALIAS_BIT 0x00 /* GH: Do we need this? */
+#define RADEON_FLAT_BIT 0x01
+#define RADEON_OFFSET_BIT 0x02
+#define RADEON_TWOSIDE_BIT 0x04
+#define RADEON_NODRAW_BIT 0x08
+#define RADEON_FALLBACK_BIT 0x10
+#define RADEON_MAX_TRIFUNC 0x20
+
+
+static __inline void radeon_draw_triangle( radeonContextPtr rmesa,
+ radeonVertexPtr v0,
+ radeonVertexPtr v1,
+ radeonVertexPtr v2 )
+{
+ GLuint vertsize = rmesa->vertsize;
+ CARD32 *vb = radeonAllocVerticesInline( rmesa, 3 );
+ GLuint j;
+
+#if defined (USE_X86_ASM)
+ /* GH: We can safely assume the vertex stride is some number of
+ * dwords, and thus a "rep movsd" is okay. The vb pointer is
+ * automagically updated with this instruction, so we don't have
+ * to manually take care of incrementing it.
+ */
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "D" ((long)vb), "S" ((long)v0)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v1)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v2)
+ : "memory" );
+#else
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v0->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v1->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v2->ui[j];
+#endif
+}
+
+static __inline void radeon_draw_quad( radeonContextPtr rmesa,
+ radeonVertexPtr v0,
+ radeonVertexPtr v1,
+ radeonVertexPtr v2,
+ radeonVertexPtr v3 )
+{
+ GLuint vertsize = rmesa->vertsize;
+ CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 );
+ GLuint j;
+
+#if defined (USE_X86_ASM)
+ /* GH: We can safely assume the vertex stride is some number of
+ * dwords, and thus a "rep movsd" is okay. The vb pointer is
+ * automagically updated with this instruction, so we don't have
+ * to manually take care of incrementing it.
+ */
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "D" ((long)vb), "S" ((long)v0)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v1)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v3)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v1)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v2)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)v3)
+ : "memory" );
+#else
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v0->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v1->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v3->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v1->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v2->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = v3->ui[j];
+#endif
+}
+
+static __inline void radeon_draw_line( radeonContextPtr rmesa,
+ radeonVertexPtr tmp0,
+ radeonVertexPtr tmp1,
+ GLfloat width )
+{
+#if 1
+ GLuint vertsize = rmesa->vertsize;
+ CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 );
+ GLfloat dx, dy, ix, iy;
+ GLuint j;
+
+ dx = tmp0->v.x - tmp1->v.x;
+ dy = tmp0->v.y - tmp1->v.y;
+
+ ix = width * .5; iy = 0;
+
+ if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width
+ 0.5 also */
+
+ if (dx * dx > dy * dy) {
+ iy = ix; ix = 0;
+ }
+
+ *(float *)&vb[0] = tmp0->v.x - ix;
+ *(float *)&vb[1] = tmp0->v.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp0->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp1->v.x + ix;
+ *(float *)&vb[1] = tmp1->v.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp1->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp0->v.x + ix;
+ *(float *)&vb[1] = tmp0->v.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp0->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp0->v.x - ix;
+ *(float *)&vb[1] = tmp0->v.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp0->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp1->v.x - ix;
+ *(float *)&vb[1] = tmp1->v.y - iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp1->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp1->v.x + ix;
+ *(float *)&vb[1] = tmp1->v.y + iy;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp1->ui[j];
+#else
+ GLuint vertsize = rmesa->vertsize;
+ CARD32 *vb = radeonAllocVerticesInline( rmesa, RADEON_LINES, 2 );
+ GLuint j;
+
+#if defined (USE_X86_ASM)
+ /* GH: We can safely assume the vertex stride is some number of
+ * dwords, and thus a "rep movsd" is okay. The vb pointer is
+ * automagically updated with this instruction, so we don't have
+ * to manually take care of incrementing it.
+ */
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp0)
+ : "memory" );
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "S" ((long)tmp1)
+ : "memory" );
+#else
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = tmp0->ui[j];
+
+ vb += vertsize;
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = tmp1->ui[j];
+#endif
+#endif
+}
+
+static __inline void radeon_draw_point( radeonContextPtr rmesa,
+ radeonVertexPtr tmp, GLfloat sz )
+{
+#if 1
+ GLuint vertsize = rmesa->vertsize;
+ CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 );
+ GLuint j;
+
+ *(float *)&vb[0] = tmp->v.x - sz;
+ *(float *)&vb[1] = tmp->v.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->v.x + sz;
+ *(float *)&vb[1] = tmp->v.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->v.x + sz;
+ *(float *)&vb[1] = tmp->v.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->v.x + sz;
+ *(float *)&vb[1] = tmp->v.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->v.x - sz;
+ *(float *)&vb[1] = tmp->v.y + sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+ vb += vertsize;
+
+ *(float *)&vb[0] = tmp->v.x - sz;
+ *(float *)&vb[1] = tmp->v.y - sz;
+ for (j = 2 ; j < vertsize ; j++)
+ vb[j] = tmp->ui[j];
+
+#else
+ int vertsize = rmesa->vertsize;
+ CARD32 *vb = radeonAllocVerticesInline( rmesa, RADEON_3_VERTEX_POINTS, 1 );
+ int j;
+
+#if defined (USE_X86_ASM)
+ /* GH: We can safely assume the vertex stride is some number of
+ * dwords, and thus a "rep movsd" is okay. The vb pointer is
+ * automagically updated with this instruction, so we don't have
+ * to manually take care of incrementing it.
+ */
+ __asm__ __volatile__( "rep ; movsl"
+ : "=%c" (j)
+ : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp)
+ : "memory" );
+#else
+ for ( j = 0 ; j < vertsize ; j++ )
+ vb[j] = tmp->ui[j];
+#endif
+#endif
+}
+
+#endif
+#endif /* __RADEON_TRIS_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h
new file mode 100644
index 000000000..ffa0d4746
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h
@@ -0,0 +1,336 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+static __inline void TAG(triangle)( GLcontext *ctx,
+ GLuint e0, GLuint e1, GLuint e2,
+ GLuint pv )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts;
+ radeonVertexPtr v[3];
+
+#if (IND & RADEON_OFFSET_BIT)
+ GLfloat offset;
+ GLfloat z[3];
+#endif
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ GLuint c[3];
+#endif
+
+ v[0] = &verts[e0];
+ v[1] = &verts[e1];
+ v[2] = &verts[e2];
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ c[0] = v[0]->ui[4];
+ c[1] = v[1]->ui[4];
+ c[2] = v[2]->ui[4];
+#endif
+
+#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT))
+ {
+ GLfloat ex = v[0]->v.x - v[2]->v.x;
+ GLfloat ey = v[0]->v.y - v[2]->v.y;
+ GLfloat fx = v[1]->v.x - v[2]->v.x;
+ GLfloat fy = v[1]->v.y - v[2]->v.y;
+ GLfloat cc = ex*fy - ey*fx;
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ {
+ GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if ( IND & RADEON_FLAT_BIT ) {
+ RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] );
+ v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4];
+ } else {
+ RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] );
+ RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] );
+ RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] );
+ }
+ }
+#endif
+
+#if (IND & RADEON_OFFSET_BIT)
+ {
+ offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale;
+ z[0] = v[0]->v.z;
+ z[1] = v[1]->v.z;
+ z[2] = v[2]->v.z;
+ if ( cc * cc > 1e-16 ) {
+ GLfloat ez = z[0] - z[2];
+ GLfloat fz = z[1] - z[2];
+ GLfloat a = ey*fz - ez*fy;
+ GLfloat b = ez*fx - ex*fz;
+ GLfloat ic = 1.0 / cc;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if ( ac < 0.0f ) ac = -ac;
+ if ( bc < 0.0f ) bc = -bc;
+ offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
+ }
+ v[0]->v.z += offset;
+ v[1]->v.z += offset;
+ v[2]->v.z += offset;
+ }
+#endif
+ }
+#endif
+
+ radeon_draw_triangle( rmesa, v[0], v[1], v[2] );
+
+#if (IND & RADEON_OFFSET_BIT)
+ v[0]->v.z = z[0];
+ v[1]->v.z = z[1];
+ v[2]->v.z = z[2];
+#endif
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ v[0]->ui[4] = c[0];
+ v[1]->ui[4] = c[1];
+ v[2]->ui[4] = c[2];
+#endif
+}
+
+
+static void TAG(quad)( GLcontext *ctx,
+ GLuint e0, GLuint e1, GLuint e2, GLuint e3,
+ GLuint pv )
+{
+#if 0
+ TAG(triangle)( ctx, e0, e1, e3, pv );
+ TAG(triangle)( ctx, e1, e2, e3, pv );
+#else
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts;
+ radeonVertexPtr v[4];
+
+#if (IND & RADEON_OFFSET_BIT)
+ GLfloat offset;
+ GLfloat z[4];
+#endif
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ int c[4];
+#endif
+
+ v[0] = &verts[e0];
+ v[1] = &verts[e1];
+ v[2] = &verts[e2];
+ v[3] = &verts[e3];
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ c[0] = v[0]->ui[4];
+ c[1] = v[1]->ui[4];
+ c[2] = v[2]->ui[4];
+ c[3] = v[3]->ui[4];
+#endif
+
+#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT))
+ {
+ GLfloat ex = v[0]->v.x - v[2]->v.x;
+ GLfloat ey = v[0]->v.y - v[2]->v.y;
+ GLfloat fx = v[1]->v.x - v[2]->v.x;
+ GLfloat fy = v[1]->v.y - v[2]->v.y;
+ GLfloat cc = ex*fy - ey*fx;
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ {
+ GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit;
+ GLubyte (*vbcolor)[4] = VB->Color[facing]->data;
+ if ( IND & RADEON_FLAT_BIT ) {
+ RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] );
+ v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4];
+ } else {
+ RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] );
+ RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] );
+ RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] );
+ RADEON_COLOR( (char *)&v[3]->ui[4], vbcolor[e3] );
+ }
+ }
+#endif
+
+#if (IND & RADEON_OFFSET_BIT)
+ {
+ offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale;
+ z[0] = v[0]->v.z;
+ z[1] = v[1]->v.z;
+ z[2] = v[2]->v.z;
+ z[3] = v[3]->v.z;
+ if ( cc * cc > 1e-16 ) {
+ GLfloat ez = z[0] - z[2];
+ GLfloat fz = z[1] - z[2];
+ GLfloat a = ey*fz - ez*fy;
+ GLfloat b = ez*fx - ex*fz;
+ GLfloat ic = 1.0 / cc;
+ GLfloat ac = a * ic;
+ GLfloat bc = b * ic;
+ if ( ac < 0.0f ) ac = -ac;
+ if ( bc < 0.0f ) bc = -bc;
+ offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
+ }
+ v[0]->v.z += offset;
+ v[1]->v.z += offset;
+ v[2]->v.z += offset;
+ v[3]->v.z += offset;
+ }
+#endif
+ }
+#endif
+
+ radeon_draw_quad( rmesa, v[0], v[1], v[2], v[3] );
+
+#if (IND & RADEON_OFFSET_BIT)
+ v[0]->v.z = z[0];
+ v[1]->v.z = z[1];
+ v[2]->v.z = z[2];
+ v[3]->v.z = z[3];
+#endif
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ v[0]->ui[4] = c[0];
+ v[1]->ui[4] = c[1];
+ v[2]->ui[4] = c[2];
+ v[3]->ui[4] = c[3];
+#endif
+#endif
+}
+
+
+static void TAG(line)( GLcontext *ctx,
+ GLuint e0, GLuint e1,
+ GLuint pv )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts;
+ GLfloat width = ctx->Line.Width;
+ radeonVertexPtr v[2];
+
+#if (IND & RADEON_OFFSET_BIT)
+ GLfloat offset;
+ GLfloat z[2];
+#endif
+#if (IND & RADEON_TWOSIDE_BIT)
+ int c[2];
+#endif
+
+ v[0] = &verts[e0];
+ v[1] = &verts[e1];
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ c[0] = v[0]->ui[4];
+ c[1] = v[1]->ui[4];
+#endif
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ {
+ GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data;
+ if ( IND & RADEON_FLAT_BIT ) {
+ RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] );
+ v[1]->ui[4] = v[0]->ui[4];
+ } else {
+ RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] );
+ RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] );
+ }
+ }
+#endif
+
+#if (IND & RADEON_OFFSET_BIT)
+ offset = ctx->LineZoffset * rmesa->depth_scale;
+ z[0] = v[0]->v.z;
+ z[1] = v[1]->v.z;
+ v[0]->v.z += offset;
+ v[1]->v.z += offset;
+#endif
+
+ radeon_draw_line( rmesa, v[0], v[1], width );
+
+#if (IND & RADEON_OFFSET_BIT)
+ v[0]->v.z = z[0];
+ v[1]->v.z = z[1];
+#endif
+
+#if (IND & RADEON_TWOSIDE_BIT)
+ v[0]->ui[4] = c[0];
+ v[1]->ui[4] = c[1];
+#endif
+}
+
+
+static void TAG(points)( GLcontext *ctx,
+ GLuint first, GLuint last )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct vertex_buffer *VB = ctx->VB;
+ radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts;
+ GLfloat size = ctx->Point.Size * 0.5;
+ int i;
+
+ for ( i = first ; i < last ; i++ ) {
+ if ( VB->ClipMask[i] == 0 ) {
+ if ( IND & (RADEON_TWOSIDE_BIT|RADEON_OFFSET_BIT) ) {
+ radeonVertex tmp0 = verts[i];
+
+ if ( IND & RADEON_TWOSIDE_BIT ) {
+ GLubyte (*vbcolor)[4] = VB->ColorPtr->data;
+ RADEON_COLOR( (char *)&tmp0.v.color, vbcolor[i] );
+ }
+ if ( IND & RADEON_OFFSET_BIT ) {
+ GLfloat offset = ctx->PointZoffset * rmesa->depth_scale;
+ tmp0.v.z += offset;
+ }
+ radeon_draw_point( rmesa, &tmp0, size );
+ } else {
+ radeon_draw_point( rmesa, &verts[i], size );
+ }
+ }
+ }
+}
+
+
+static void TAG(init)( void )
+{
+ rast_tab[IND].points = TAG(points);
+ rast_tab[IND].line = TAG(line);
+ rast_tab[IND].triangle = TAG(triangle);
+ rast_tab[IND].quad = TAG(quad);
+}
+
+#undef IND
+#undef TAG
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c
new file mode 100644
index 000000000..bdf19b2d6
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c
@@ -0,0 +1,483 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c,v 1.2 2001/01/11 03:36:55 tsi Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_state.h"
+#include "radeon_vb.h"
+
+#include "mem.h"
+#include "stages.h"
+
+#define TEX0 \
+do { \
+ v->v.tu0 = tc0[i][0]; \
+ v->v.tv0 = tc0[i][1]; \
+} while (0)
+
+#define TEX1 \
+do { \
+ v->v.tu1 = tc1[i][0]; \
+ v->v.tv1 = tc1[i][1]; \
+} while (0)
+
+#define SPC \
+do { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.specular.red = spec[0]; \
+ v->v.specular.green = spec[1]; \
+ v->v.specular.blue = spec[2]; \
+} while (0)
+
+#define FOG \
+do { \
+ GLubyte *spec = &(VB->Spec[0][i][0]); \
+ v->v.specular.alpha = spec[3]; \
+} while (0)
+
+#define COL \
+do { \
+ GLubyte *col = &(VB->Color[0]->data[i][0]); \
+ v->ui[4] = *(GLuint *)col; \
+} while (0)
+
+#define TEX0_4 \
+do { \
+ if ( VB->TexCoordPtr[0]->size == 4 ) { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \
+ v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \
+ for ( i = start ; i < end ; i++, v++ ) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.rhw *= tc[i][3]; \
+ v->v.tu0 *= oow; \
+ v->v.tv0 *= oow; \
+ } \
+ } \
+} while (0)
+
+#ifdef USE_RHW2
+
+#define TEX1_4 \
+do { \
+ if ( VB->TexCoordPtr[1]->size == 4 ) { \
+ GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \
+ v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \
+ for ( i = start ; i < end ; i++, v++ ) { \
+ float oow = 1.0 / tc[i][3]; \
+ v->v.rhw2 *= tc[i][3]; \
+ v->v.tu1 *= oow; \
+ v->v.tv1 *= oow; \
+ } \
+ } \
+} while (0)
+
+#define COORD \
+do { \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = - win[1]; \
+ v->v.z = win[2]; \
+ v->v.rhw = v->v.rhw2 = win[3]; \
+} while (0)
+
+#else /* USE_RHW2 */
+
+#define TEX1_4
+
+#define COORD \
+do { \
+ GLfloat *win = VB->Win.data[i]; \
+ v->v.x = win[0]; \
+ v->v.y = - win[1]; \
+ v->v.z = win[2]; \
+ v->v.rhw = win[3]; \
+} while (0) \
+
+#endif /* USE_RHW2 */
+
+#define NOP
+
+
+#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \
+static void name( struct vertex_buffer *VB, GLuint start, GLuint end ) \
+{ \
+ radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \
+ radeonVertexPtr v; \
+ GLfloat (*tc0)[4]; \
+ GLfloat (*tc1)[4]; \
+ GLint i; \
+ \
+ gl_import_client_data( VB, VB->ctx->RenderFlags, \
+ (VB->ClipOrMask \
+ ? VEC_WRITABLE | VEC_GOOD_STRIDE \
+ : VEC_GOOD_STRIDE) ); \
+ \
+ tc0 = VB->TexCoordPtr[rmesa->tmu_source[0]]->data; \
+ tc1 = VB->TexCoordPtr[rmesa->tmu_source[1]]->data; \
+ \
+ v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \
+ \
+ if ( VB->ClipOrMask == 0 ) { \
+ for ( i = start ; i < end ; i++, v++ ) { \
+ win; \
+ col; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ } else { \
+ for ( i = start ; i < end ; i++, v++ ) { \
+ if ( VB->ClipMask[i] == 0 ) { \
+ win; \
+ spec; \
+ fog; \
+ tex0; \
+ tex1; \
+ } \
+ col; \
+ } \
+ } \
+ tex0_4; \
+ tex1_4; \
+}
+
+
+SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP)
+SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP)
+SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP)
+SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG)
+SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG)
+SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG)
+
+SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP)
+SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP)
+SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP)
+SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP)
+SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP)
+SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP)
+SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG)
+SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG)
+SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG)
+SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG)
+SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG)
+SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG)
+
+
+static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end )
+{
+ fprintf( stderr, "radeonRasterSetup(): invalid setup function\n" );
+}
+
+typedef void (*setupFunc)( struct vertex_buffer *, GLuint, GLuint );
+static setupFunc setup_func[RADEON_MAX_SETUPFUNC];
+
+
+void radeonDDSetupInit( void )
+{
+ GLint i;
+
+ for ( i = 0 ; i < RADEON_MAX_SETUPFUNC ; i++ ) {
+ setup_func[i] = rs_invalid;
+ }
+
+ /* Functions to build vertices from scratch
+ */
+ setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT] = rs_wt0;
+ setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wt0t1;
+ setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wft0;
+ setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wft0t1;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT] = rs_wg;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_wgs;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_wgt0;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgt0t1;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgst0;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgst0t1;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_wgf;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_wgfs;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wgft0;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgft0t1;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgfst0;
+ setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgfst0t1;
+
+ /* Repair functions
+ */
+ setup_func[RADEON_TEX0_BIT] = rs_t0;
+ setup_func[RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_t0t1;
+ setup_func[RADEON_FOG_BIT] = rs_f;
+ setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_ft0;
+ setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_ft0t1;
+ setup_func[RADEON_RGBA_BIT] = rs_g;
+ setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_gs;
+ setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_gt0;
+ setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gt0t1;
+ setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gst0;
+ setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gst0t1;
+ setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_gf;
+ setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_gfs;
+ setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_gft0;
+ setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gft0t1;
+ setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gfst0;
+ setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gfst0t1;
+}
+
+
+void radeonPrintSetupFlags( char *msg, GLuint flags )
+{
+ fprintf( stderr, "%s: %d %s%s%s%s%s%s\n",
+ msg,
+ (int)flags,
+ (flags & RADEON_WIN_BIT) ? " xyzw," : "",
+ (flags & RADEON_RGBA_BIT) ? " rgba," : "",
+ (flags & RADEON_SPEC_BIT) ? " spec," : "",
+ (flags & RADEON_FOG_BIT) ? " fog," : "",
+ (flags & RADEON_TEX0_BIT) ? " tex-0," : "",
+ (flags & RADEON_TEX1_BIT) ? " tex-1," : "" );
+}
+
+
+/* Initialize the vertex buffer setup functions based on the current
+ * rendering state.
+ */
+void radeonDDChooseRasterSetupFunc( GLcontext *ctx )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+ GLint index = RADEON_WIN_BIT | RADEON_RGBA_BIT;
+
+ rmesa->vertsize = 8;
+ rmesa->vc_format = RADEON_TEX0_VERTEX_FORMAT;
+ rmesa->tmu_source[0] = 0;
+ rmesa->tmu_source[1] = 1;
+ rmesa->tex_dest[0] = RADEON_TEX0_BIT;
+ rmesa->tex_dest[1] = RADEON_TEX1_BIT;
+ rmesa->multitex = 0;
+
+ if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) {
+ index |= RADEON_TEX0_BIT;
+ }
+
+ if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) {
+ if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) {
+ rmesa->multitex = 1;
+ rmesa->vertsize = 10;
+ rmesa->vc_format = RADEON_TEX1_VERTEX_FORMAT;
+ index |= RADEON_TEX1_BIT;
+ } else {
+ /* Just a funny way of doing single texturing.
+ */
+ rmesa->tmu_source[0] = 1;
+ rmesa->tex_dest[1] = RADEON_TEX0_BIT;
+ index |= RADEON_TEX0_BIT;
+ }
+ }
+
+ if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )
+ index |= RADEON_SPEC_BIT;
+
+ if ( ctx->Fog.Enabled )
+ index |= RADEON_FOG_BIT;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) {
+ radeonPrintSetupFlags( "full setup function", index );
+ }
+
+ rmesa->new_state |= RADEON_NEW_TEXTURE;
+ rmesa->SetupIndex = index;
+
+ ctx->Driver.RasterSetup = setup_func[index];
+}
+
+/* Check to see if any updates of the vertex buffer entries are needed.
+ */
+void radeonDDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *s )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLint tmp = rmesa->SetupDone;
+
+ s->type = 0;
+ rmesa->SetupDone = 0;
+
+ if ( (ctx->Array.Summary & VERT_OBJ_ANY) == 0 )
+ return;
+
+ if ( ctx->IndirectTriangles )
+ return;
+
+ rmesa->SetupDone = tmp;
+}
+
+/* Repair existing precalculated vertices with new data.
+ */
+void radeonDDPartialRasterSetup( struct vertex_buffer *VB )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx);
+ GLuint new = VB->pipeline->new_outputs;
+ GLuint available = VB->pipeline->outputs;
+ GLuint index = 0;
+
+ if ( new & VERT_WIN ) {
+ new = available;
+ index |= RADEON_WIN_BIT | RADEON_FOG_BIT;
+ }
+
+ if ( new & VERT_RGBA )
+ index |= RADEON_RGBA_BIT | RADEON_SPEC_BIT;
+
+ if ( new & VERT_TEX0_ANY )
+ index |= RADEON_TEX0_BIT;
+
+ if ( new & VERT_TEX1_ANY )
+ index |= rmesa->tex_dest[1];
+
+ if ( new & VERT_FOG_COORD )
+ index |= RADEON_FOG_BIT;
+
+ rmesa->SetupDone &= ~index;
+ index &= rmesa->SetupIndex;
+ rmesa->SetupDone |= index;
+
+ if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG )
+ radeonPrintSetupFlags( "partial setup function", index );
+
+ if ( index )
+ setup_func[index]( VB, VB->Start, VB->Count );
+}
+
+void radeonDDDoRasterSetup( struct vertex_buffer *VB )
+{
+ GLcontext *ctx = VB->ctx;
+
+ if ( VB->Type == VB_CVA_PRECALC ) {
+ radeonDDPartialRasterSetup( VB );
+ } else if ( ctx->Driver.RasterSetup ) {
+ ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count );
+ }
+}
+
+
+/* ================================================================
+ * Hardware-format vertex buffers
+ */
+
+void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size )
+{
+ radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB);
+
+ while ( rvb->size < size )
+ rvb->size *= 2;
+
+ ALIGN_FREE( rvb->vert_store );
+ rvb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * rvb->size, 32 );
+ if ( !rvb->vert_store ) {
+ fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" );
+ exit( 1 );
+ }
+
+ rvb->verts = (radeonVertexPtr)rvb->vert_store;
+
+ gl_vector1ui_free( &rvb->clipped_elements );
+ gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 );
+ if ( !rvb->clipped_elements.start ) {
+ fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" );
+ exit( 1 );
+ }
+
+ ALIGN_FREE( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 );
+ if ( !VB->ClipMask ) {
+ fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" );
+ exit( 1 );
+ }
+}
+
+void radeonDDRegisterVB( struct vertex_buffer *VB )
+{
+ radeonVertexBufferPtr rvb;
+
+ rvb = (radeonVertexBufferPtr)CALLOC( sizeof(*rvb) );
+
+ rvb->size = VB->Size * 2;
+ rvb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * rvb->size, 32 );
+ if ( !rvb->vert_store ) {
+ fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" );
+ exit( 1 );
+ }
+
+ rvb->verts = (radeonVertexPtr)rvb->vert_store;
+
+ gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 );
+ if ( !rvb->clipped_elements.start ) {
+ fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" );
+ exit( 1 );
+ }
+
+ ALIGN_FREE( VB->ClipMask );
+ VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 );
+ if ( !VB->ClipMask ) {
+ fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" );
+ exit( 1 );
+ }
+
+ VB->driver_data = rvb;
+}
+
+void radeonDDUnregisterVB( struct vertex_buffer *VB )
+{
+ radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB);
+
+ if ( rvb ) {
+ if ( rvb->vert_store ) ALIGN_FREE( rvb->vert_store );
+ gl_vector1ui_free( &rvb->clipped_elements );
+ FREE( rvb );
+ VB->driver_data = 0;
+ }
+}
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h
new file mode 100644
index 000000000..bd809efbb
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h
@@ -0,0 +1,136 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h,v 1.1 2001/01/08 01:07:29 martin Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef __RADEON_VB_H__
+#define __RADEON_VB_H__
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* FIXME: This is endian-specific */
+typedef struct {
+ GLubyte red;
+ GLubyte green;
+ GLubyte blue;
+ GLubyte alpha;
+} radeon_color_t;
+
+/* The vertex structure. The final tu1/tv1 values are only used in
+ * multitexture modes, and the rhw2 value is currently never used.
+ */
+typedef struct {
+ GLfloat x, y, z; /* Coordinates in screen space */
+ GLfloat rhw; /* Reciprocal homogeneous w */
+ radeon_color_t color; /* Diffuse color */
+ radeon_color_t specular; /* Specular color (alpha is fog) */
+ GLfloat tu0, tv0; /* Texture 0 coordinates */
+ GLfloat tu1, tv1; /* Texture 1 coordinates */
+ GLfloat rhw2; /* Reciprocal homogeneous w2 */
+} radeon_vertex;
+
+/* Format of vertices in radeon_vertex struct:
+ */
+#define RADEON_TEX0_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
+ RADEON_CP_VC_FRMT_Z | \
+ RADEON_CP_VC_FRMT_W0 | \
+ RADEON_CP_VC_FRMT_PKCOLOR | \
+ RADEON_CP_VC_FRMT_PKSPEC | \
+ RADEON_CP_VC_FRMT_ST0)
+
+#define RADEON_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
+ RADEON_CP_VC_FRMT_Z | \
+ RADEON_CP_VC_FRMT_W0 | \
+ RADEON_CP_VC_FRMT_PKCOLOR | \
+ RADEON_CP_VC_FRMT_PKSPEC | \
+ RADEON_CP_VC_FRMT_ST0 | \
+ RADEON_CP_VC_FRMT_ST1)
+
+#if 0
+#define RADEON_PROJ_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \
+ RADEON_CP_VC_FRMT_Z | \
+ RADEON_CP_VC_FRMT_W0 | \
+ RADEON_CP_VC_FRMT_PKCOLOR | \
+ RADEON_CP_VC_FRMT_PKSPEC | \
+ RADEON_CP_VC_FRMT_ST0 | \
+ RADEON_CP_VC_FRMT_ST1 | \
+ RADEON_CP_VC_FRMT_Q1)
+#endif
+
+
+/* The fastpath code still expects a 16-float stride vertex.
+ */
+union radeon_vertex_t {
+ radeon_vertex v;
+ GLfloat f[16];
+ GLuint ui[16];
+};
+
+typedef union radeon_vertex_t radeonVertex;
+typedef union radeon_vertex_t *radeonVertexPtr;
+
+typedef struct {
+ radeonVertexPtr verts;
+ GLvector1ui clipped_elements;
+ GLint last_vert;
+ void *vert_store;
+ GLuint size;
+} *radeonVertexBufferPtr;
+
+#define RADEON_DRIVER_DATA(vb) ((radeonVertexBufferPtr)((vb)->driver_data))
+
+#define RADEON_WIN_BIT 0x01
+#define RADEON_RGBA_BIT 0x02
+#define RADEON_FOG_BIT 0x04
+#define RADEON_SPEC_BIT 0x08
+#define RADEON_TEX0_BIT 0x10
+#define RADEON_TEX1_BIT 0x20
+#define RADEON_MAX_SETUPFUNC 0x40
+
+extern void radeonDDChooseRasterSetupFunc( GLcontext *ctx );
+extern void radeonPrintSetupFlags( char *msg, GLuint flags );
+
+extern void radeonDDCheckPartialRasterSetup( GLcontext *ctx,
+ struct gl_pipeline_stage *s );
+extern void radeonDDPartialRasterSetup( struct vertex_buffer *VB );
+extern void radeonDDDoRasterSetup( struct vertex_buffer *VB );
+
+extern void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size );
+extern void radeonDDRegisterVB( struct vertex_buffer *VB );
+extern void radeonDDUnregisterVB( struct vertex_buffer *VB );
+
+extern void radeonDDSetupInit( void );
+
+#endif
+#endif /* __RADEON_VB_H__ */
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c
new file mode 100644
index 000000000..1f24b8409
--- /dev/null
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c
@@ -0,0 +1,314 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c,v 1.2 2001/01/23 18:14:39 alanh Exp $ */
+/**************************************************************************
+
+Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
+ VA Linux Systems Inc., Fremont, California.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* Radeon Mesa driver includes */
+#include "radeon_context.h"
+#include "radeon_ioctl.h"
+#include "radeon_state.h"
+#include "radeon_tex.h"
+
+/* Mesa src includes */
+#include "context.h"
+#include "simple_list.h"
+#include "mmath.h"
+
+extern void __driRegisterExtensions( void );
+
+static radeonContextPtr radeonCtx = NULL;
+
+
+/* Initialize the driver specific screen private data.
+ */
+GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv )
+{
+ sPriv->private = (void *) radeonCreateScreen( sPriv );
+
+ /* Check the DRI version */
+ {
+ int major, minor, patch;
+ if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) {
+ if (major != 3 || minor != 1 || patch < 0) {
+ char msg[1000];
+ sprintf(msg, "RADEON DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch);
+ __driMesaMessage(msg);
+ return GL_FALSE;
+ }
+ }
+ }
+
+ /* Check that the DDX driver version is compatible */
+ if (sPriv->ddxMajor != 4 ||
+ sPriv->ddxMinor != 0 ||
+ sPriv->ddxPatch < 0) {
+ char msg[1000];
+ sprintf(msg, "RADEON DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch);
+ __driMesaMessage(msg);
+ return GL_FALSE;
+ }
+
+ /* Check that the DRM driver version is compatible */
+ if (sPriv->drmMajor != 1 ||
+ sPriv->drmMinor != 0 ||
+ sPriv->drmPatch < 0) {
+ char msg[1000];
+ sprintf(msg, "RADEON DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch);
+ __driMesaMessage(msg);
+ return GL_FALSE;
+ }
+
+ if ( !sPriv->private ) {
+ radeonDestroyScreen( sPriv );
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/* Reset the driver specific screen private data.
+ */
+void XMesaResetDriver( __DRIscreenPrivate *sPriv )
+{
+ radeonDestroyScreen( sPriv );
+}
+
+/* Create and initialize the Mesa and driver specific visual data.
+ */
+GLvisual *XMesaCreateVisual( Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ const XVisualInfo *visinfo,
+ const __GLXvisualConfig *config )
+{
+ /* Drivers may change the args to _mesa_create_visual() in order to
+ * setup special visuals.
+ */
+ return _mesa_create_visual( config->rgba,
+ config->doubleBuffer,
+ config->stereo,
+ _mesa_bitcount( visinfo->red_mask ),
+ _mesa_bitcount( visinfo->green_mask ),
+ _mesa_bitcount( visinfo->blue_mask ),
+ config->alphaSize,
+ 0, /* index bits */
+ config->depthSize,
+ config->stencilSize,
+ config->accumRedSize,
+ config->accumGreenSize,
+ config->accumBlueSize,
+ config->accumAlphaSize,
+ 0 /* num samples */);
+}
+
+/* Create and initialize the Mesa and driver specific context data.
+ */
+GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis,
+ __DRIcontextPrivate *driContextPriv )
+{
+ return radeonCreateContext( dpy, mesaVis, driContextPriv );
+}
+
+/* Destroy the Mesa and driver specific context data.
+ */
+void XMesaDestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate;
+
+ if ( rmesa == (void *)radeonCtx) radeonCtx = NULL;
+ radeonDestroyContext( rmesa );
+}
+
+/* Create and initialize the Mesa and driver specific pixmap buffer
+ * data.
+ */
+GLframebuffer *XMesaCreateWindowBuffer( Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ GLvisual *mesaVis )
+{
+ return gl_create_framebuffer( mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->StencilBits > 0,
+ mesaVis->AccumRedBits > 0,
+ GL_FALSE /* software alpha buffer? */ );
+}
+
+/* Create and initialize the Mesa and driver specific pixmap buffer
+ * data.
+ */
+GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy,
+ __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ GLvisual *mesaVis )
+{
+#if 0
+ /* Different drivers may have different combinations of hardware and
+ * software ancillary buffers.
+ */
+ return gl_create_framebuffer( mesaVis,
+ GL_FALSE, /* software depth buffer? */
+ mesaVis->StencilBits > 0,
+ mesaVis->AccumRedBits > 0,
+ mesaVis->AlphaBits > 0 );
+#else
+ return NULL; /* not implemented yet */
+#endif
+}
+
+/* Copy the back color buffer to the front color buffer.
+ */
+void XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
+{
+ /* FIXME: This assumes buffer is currently bound to a context. This
+ * needs to be able to swap buffers when not currently bound. Also,
+ * this needs to swap according to buffer, and NOT according to
+ * context!
+ */
+ if ( radeonCtx == NULL ) return;
+
+ /* Only swap buffers when a back buffer exists.
+ */
+ if ( radeonCtx->glCtx->Visual->DBflag ) {
+ FLUSH_VB( radeonCtx->glCtx, "swap buffers" );
+ if ( !radeonCtx->doPageFlip ) {
+ radeonSwapBuffers( radeonCtx );
+ } else {
+ radeonPageFlip( radeonCtx );
+ }
+ }
+}
+
+/* Force the context `c' to be the current context and associate with it
+ * buffer `b'.
+ */
+GLboolean XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv )
+{
+ if ( driContextPriv ) {
+ radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate;
+
+ radeonCtx = radeonMakeCurrent( radeonCtx, rmesa, driDrawPriv );
+
+ gl_make_current2( radeonCtx->glCtx,
+ driDrawPriv->mesaBuffer,
+ driReadPriv->mesaBuffer );
+
+ if ( radeonCtx->driDrawable != driDrawPriv ) {
+ radeonCtx->driDrawable = driDrawPriv;
+ radeonCtx->dirty = RADEON_UPLOAD_ALL;
+ }
+
+ /* GH: We need this to correctly calculate the window offset
+ * and aux scissor rects.
+ */
+ radeonCtx->new_state = RADEON_NEW_WINDOW | RADEON_NEW_CLIP;
+
+ if ( !radeonCtx->glCtx->Viewport.Width ) {
+ gl_Viewport( radeonCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h );
+ }
+ } else {
+ gl_make_current( 0, 0 );
+ radeonCtx = NULL;
+ }
+
+ return GL_TRUE;
+}
+
+/* Force the context `c' to be unbound from its buffer.
+ */
+GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+/* This function is called by libGL.so as soon as libGL.so is loaded.
+ * This is where we'd register new extension functions with the dispatcher.
+ */
+void __driRegisterExtensions( void )
+{
+}
+
+/* Initialize the fullscreen mode.
+ */
+GLboolean
+XMesaOpenFullScreen( __DRIcontextPrivate *driContextPriv )
+{
+ radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate;
+ GLint ret;
+
+ /* FIXME: Do we need to check this?
+ */
+ if ( !radeonCtx->glCtx->Visual->DBflag )
+ return GL_TRUE;
+
+ LOCK_HARDWARE( rmesa );
+ radeonWaitForIdleLocked( rmesa );
+
+ /* Ignore errors. If this fails, we simply don't do page flipping.
+ */
+ ret = drmRadeonFullScreen( rmesa->driFd, GL_TRUE );
+
+ UNLOCK_HARDWARE( rmesa );
+
+ rmesa->doPageFlip = ( ret == 0 );
+
+ return GL_TRUE;
+}
+
+/* Shut down the fullscreen mode.
+ */
+GLboolean
+XMesaCloseFullScreen( __DRIcontextPrivate *driContextPriv )
+{
+ radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate;
+
+ LOCK_HARDWARE( rmesa );
+ radeonWaitForIdleLocked( rmesa );
+
+ /* Don't care if this fails, we're not page flipping anymore.
+ */
+ drmRadeonFullScreen( rmesa->driFd, GL_FALSE );
+
+ UNLOCK_HARDWARE( rmesa );
+
+ rmesa->doPageFlip = GL_FALSE;
+ rmesa->currentPage = 0;
+
+ return GL_TRUE;
+}
+
+#endif